1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony.ims;
18 
19 import android.annotation.NonNull;
20 import android.annotation.RequiresFeature;
21 import android.annotation.SdkConstant;
22 import android.annotation.SuppressLint;
23 import android.annotation.SystemApi;
24 import android.annotation.SystemService;
25 import android.content.Context;
26 import android.content.pm.PackageManager;
27 import android.telephony.BinderCacheManager;
28 import android.telephony.SubscriptionManager;
29 import android.telephony.TelephonyFrameworkInitializer;
30 import android.telephony.ims.aidl.IImsRcsController;
31 
32 import com.android.internal.telephony.ITelephony;
33 
34 /**
35  * Provides access to information about Telephony IMS services on the device.
36  */
37 @SystemService(Context.TELEPHONY_IMS_SERVICE)
38 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
39 public class ImsManager {
40 
41     /**
42      * <p>Broadcast Action: Indicates that a previously allowed IMS operation was rejected by the
43      * network due to the network returning a "forbidden" response. This may be due to a
44      * provisioning change from the network.
45      * May include the {@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX} extra to also specify
46      * which subscription the operation was rejected for.
47      * <p class="note">
48      * Carrier applications may listen to this broadcast to be notified of possible IMS provisioning
49      * issues.
50      * @hide
51      */
52     // Moved from TelephonyIntents, need to keep backwards compatibility with OEM apps that have
53     // this value hard-coded in BroadcastReceiver.
54     @SuppressLint("ActionValue")
55     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
56     public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION =
57             "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION";
58 
59     /**
60      * An intent action indicating that IMS registration for WiFi calling has resulted in an error.
61      * Contains error information that should be displayed to the user.
62      * <p>
63      * This intent will contain the following extra key/value pairs:
64      * {@link #EXTRA_WFC_REGISTRATION_FAILURE_TITLE}
65      * and {@link #EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE}, which contain carrier specific
66      * error information that should be displayed to the user.
67      * <p>
68      * Usage: This intent is sent as an ordered broadcast. If the settings application is going
69      * to show the error information specified to the user, it should respond to
70      * {@link android.content.BroadcastReceiver#setResultCode(int)} with
71      * {@link android.app.Activity#RESULT_CANCELED}, which will signal to the framework that the
72      * event was handled. If the framework does not receive a response to the ordered broadcast,
73      * it will then show a notification to the user indicating that there was a registration
74      * failure.
75      */
76     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
77     public static final String ACTION_WFC_IMS_REGISTRATION_ERROR =
78             "android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR";
79 
80     /**
81      * An extra key corresponding to a {@link CharSequence} value which contains the carrier
82      * specific title to be displayed as part of the message shown to the user when there is an
83      * error registering for WiFi calling.
84      */
85     public static final String EXTRA_WFC_REGISTRATION_FAILURE_TITLE =
86             "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_TITLE";
87 
88     /**
89      * An extra key corresponding to a {@link CharSequence} value which contains the carrier
90      * specific message to  be displayed as part of the message shown to the user when there is an
91      * error registering for WiFi calling.
92      */
93     public static final String EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE =
94             "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_MESSAGE";
95 
96     // Cache Telephony Binder interfaces, one cache per process.
97     private static final BinderCacheManager<ITelephony> sTelephonyCache =
98             new BinderCacheManager<>(ImsManager::getITelephonyInterface);
99     private static final BinderCacheManager<IImsRcsController> sRcsCache =
100             new BinderCacheManager<>(ImsManager::getIImsRcsControllerInterface);
101 
102     private final Context mContext;
103 
104     /**
105      * Use {@link Context#getSystemService(String)} to get an instance of this class.
106      * @hide
107      */
ImsManager(@onNull Context context)108     public ImsManager(@NonNull Context context) {
109         mContext = context;
110     }
111 
112     /**
113      * Create an instance of ImsRcsManager for the subscription id specified.
114      *
115      * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
116      * @throws IllegalArgumentException if the subscription is invalid.
117      * @return a ImsRcsManager instance with the specific subscription ID.
118      */
119     @NonNull
getImsRcsManager(int subscriptionId)120     public ImsRcsManager getImsRcsManager(int subscriptionId) {
121         if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
122             throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
123         }
124 
125         return new ImsRcsManager(mContext, subscriptionId, sRcsCache, sTelephonyCache);
126     }
127 
128     /**
129      * Create an instance of ImsMmTelManager for the subscription id specified.
130      *
131      * @param subscriptionId The ID of the subscription that this ImsMmTelManager will use.
132      * @throws IllegalArgumentException if the subscription is invalid.
133      * @return a ImsMmTelManager instance with the specific subscription ID.
134      */
135     @NonNull
getImsMmTelManager(int subscriptionId)136     public ImsMmTelManager getImsMmTelManager(int subscriptionId) {
137         if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
138             throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
139         }
140 
141         return new ImsMmTelManager(mContext, subscriptionId, sTelephonyCache);
142     }
143 
144     /**
145      * Create an instance of {@link SipDelegateManager} for the subscription id specified.
146      * <p>
147      * Allows an IMS application to forward SIP traffic through the device's IMS service,
148      * which is used for cellular carriers that require the device to share a single IMS
149      * registration for both MMTEL and RCS features.
150      * @param subscriptionId The ID of the subscription that this {@link SipDelegateManager} will
151      *                       be bound to.
152      * @throws IllegalArgumentException if the subscription is invalid.
153      * @return a {@link SipDelegateManager} instance for the specified subscription ID.
154      * @hide
155      */
156     @SystemApi
157     @NonNull
getSipDelegateManager(int subscriptionId)158     public SipDelegateManager getSipDelegateManager(int subscriptionId) {
159         if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
160             throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
161         }
162 
163         return new SipDelegateManager(mContext, subscriptionId, sRcsCache, sTelephonyCache);
164     }
165 
166 
167     /**
168      * Create an instance of {@link ProvisioningManager} for the subscription id specified.
169      * <p>
170      * Provides a ProvisioningManager instance to carrier apps to update carrier provisioning
171      * information, as well as provides a callback so that apps can listen for changes
172      * in MMTEL/RCS provisioning
173      * @param subscriptionId The ID of the subscription that this ProvisioningManager will use.
174      * @throws IllegalArgumentException if the subscription is invalid.
175      * @return a ProvisioningManager instance with the specific subscription ID.
176      */
177     @NonNull
getProvisioningManager(int subscriptionId)178     public ProvisioningManager getProvisioningManager(int subscriptionId) {
179         if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
180             throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
181         }
182 
183         return new ProvisioningManager(subscriptionId);
184     }
185 
getIImsRcsControllerInterface()186     private static IImsRcsController getIImsRcsControllerInterface() {
187         return IImsRcsController.Stub.asInterface(
188                 TelephonyFrameworkInitializer
189                         .getTelephonyServiceManager()
190                         .getTelephonyImsServiceRegisterer()
191                         .get());
192     }
193 
getITelephonyInterface()194     private static ITelephony getITelephonyInterface() {
195         return ITelephony.Stub.asInterface(
196                 TelephonyFrameworkInitializer
197                         .getTelephonyServiceManager()
198                         .getTelephonyServiceRegisterer()
199                         .get());
200     }
201 }
202