• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Manifest;
20 import android.annotation.CallbackExecutor;
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.RequiresFeature;
25 import android.annotation.RequiresPermission;
26 import android.content.pm.PackageManager;
27 import android.net.Uri;
28 import android.os.Binder;
29 import android.os.Bundle;
30 import android.telephony.AccessNetworkConstants;
31 import android.telephony.NetworkRegistrationInfo;
32 import android.telephony.ims.aidl.IImsRegistrationCallback;
33 import android.telephony.ims.feature.ImsFeature;
34 import android.telephony.ims.stub.ImsRegistrationImplBase;
35 import android.util.Log;
36 
37 import java.lang.annotation.Retention;
38 import java.lang.annotation.RetentionPolicy;
39 import java.util.HashMap;
40 import java.util.Map;
41 import java.util.concurrent.Executor;
42 import java.util.function.Consumer;
43 
44 /**
45  * Manages IMS Service registration state for associated {@link ImsFeature}s.
46  */
47 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
48 public interface RegistrationManager {
49 
50     /**
51      * @hide
52      */
53     // Defines the underlying radio technology type that we have registered for IMS over.
54     @IntDef(prefix = "REGISTRATION_STATE_",
55             value = {
56                     REGISTRATION_STATE_NOT_REGISTERED,
57                     REGISTRATION_STATE_REGISTERING,
58                     REGISTRATION_STATE_REGISTERED
59             })
60     @Retention(RetentionPolicy.SOURCE)
61     public @interface ImsRegistrationState {}
62 
63     /**
64      * The IMS service is currently not registered to the carrier network.
65      */
66     int REGISTRATION_STATE_NOT_REGISTERED = 0;
67 
68     /**
69      * The IMS service is currently in the process of registering to the carrier network.
70      */
71     int REGISTRATION_STATE_REGISTERING = 1;
72 
73     /**
74      * The IMS service is currently registered to the carrier network.
75      */
76     int REGISTRATION_STATE_REGISTERED = 2;
77 
78     /**@hide*/
79     // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN
80     // and WWAN are more accurate constants.
81     Map<Integer, Integer> IMS_REG_TO_ACCESS_TYPE_MAP =
82             new HashMap<Integer, Integer>() {{
83                 // Map NONE to -1 to make sure that we handle the REGISTRATION_TECH_NONE
84                 // case, since it is defined.
85                 put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE,
86                         AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
87                 put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
88                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
89                 put(ImsRegistrationImplBase.REGISTRATION_TECH_NR,
90                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
91                 put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
92                         AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
93                 /* As the cross sim will be using ePDG tunnel over internet, it behaves
94                    like IWLAN in most cases. Hence setting the access type as IWLAN
95                  */
96                 put(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM,
97                         AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
98             }};
99 
100     /** @hide */
101     @NonNull
registrationStateToString( final @NetworkRegistrationInfo.RegistrationState int value)102     static String registrationStateToString(
103             final @NetworkRegistrationInfo.RegistrationState int value) {
104         switch (value) {
105             case REGISTRATION_STATE_NOT_REGISTERED:
106                 return "REGISTRATION_STATE_NOT_REGISTERED";
107             case REGISTRATION_STATE_REGISTERING:
108                 return "REGISTRATION_STATE_REGISTERING";
109             case REGISTRATION_STATE_REGISTERED:
110                 return "REGISTRATION_STATE_REGISTERED";
111             default:
112                 return Integer.toString(value);
113         }
114     }
115 
116     /**
117      * @param regtech The registration technology.
118      * @return The Access Network type from registration technology.
119      * @hide
120      */
getAccessType(int regtech)121     static int getAccessType(int regtech) {
122         if (!RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regtech)) {
123             Log.w("RegistrationManager", "getAccessType - invalid regType returned: "
124                     + regtech);
125             return AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
126         }
127         return RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(regtech);
128     }
129 
130     /**
131      * Callback class for receiving IMS network Registration callback events.
132      * @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
133      * @see #unregisterImsRegistrationCallback(RegistrationCallback)
134      */
135     class RegistrationCallback {
136 
137         private static class RegistrationBinder extends IImsRegistrationCallback.Stub {
138 
139             private final RegistrationCallback mLocalCallback;
140             private Executor mExecutor;
141             private Bundle mBundle = new Bundle();
142 
RegistrationBinder(RegistrationCallback localCallback)143             RegistrationBinder(RegistrationCallback localCallback) {
144                 mLocalCallback = localCallback;
145             }
146 
147             @Override
onRegistered(ImsRegistrationAttributes attr)148             public void onRegistered(ImsRegistrationAttributes attr) {
149                 if (mLocalCallback == null) return;
150 
151                 final long callingIdentity = Binder.clearCallingIdentity();
152                 try {
153                     mExecutor.execute(() -> mLocalCallback.onRegistered(attr));
154                 } finally {
155                     restoreCallingIdentity(callingIdentity);
156                 }
157             }
158 
159             @Override
onRegistering(ImsRegistrationAttributes attr)160             public void onRegistering(ImsRegistrationAttributes attr) {
161                 if (mLocalCallback == null) return;
162 
163                 final long callingIdentity = Binder.clearCallingIdentity();
164                 try {
165                     mExecutor.execute(() -> mLocalCallback.onRegistering(attr));
166                 } finally {
167                     restoreCallingIdentity(callingIdentity);
168                 }
169             }
170 
171             @Override
onDeregistered(ImsReasonInfo info)172             public void onDeregistered(ImsReasonInfo info) {
173                 if (mLocalCallback == null) return;
174 
175                 final long callingIdentity = Binder.clearCallingIdentity();
176                 try {
177                     mExecutor.execute(() -> mLocalCallback.onUnregistered(info));
178                 } finally {
179                     restoreCallingIdentity(callingIdentity);
180                 }
181             }
182 
183             @Override
onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info)184             public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) {
185                 if (mLocalCallback == null) return;
186 
187                 final long callingIdentity = Binder.clearCallingIdentity();
188                 try {
189                     mExecutor.execute(() -> mLocalCallback.onTechnologyChangeFailed(
190                             getAccessType(imsRadioTech), info));
191                 } finally {
192                     restoreCallingIdentity(callingIdentity);
193                 }
194             }
195 
onSubscriberAssociatedUriChanged(Uri[] uris)196             public void onSubscriberAssociatedUriChanged(Uri[] uris) {
197                 if (mLocalCallback == null) return;
198 
199                 final long callingIdentity = Binder.clearCallingIdentity();
200                 try {
201                     mExecutor.execute(() -> mLocalCallback.onSubscriberAssociatedUriChanged(uris));
202                 } finally {
203                     restoreCallingIdentity(callingIdentity);
204                 }
205             }
206 
setExecutor(Executor executor)207             private void setExecutor(Executor executor) {
208                 mExecutor = executor;
209             }
210         }
211 
212         private final RegistrationBinder mBinder = new RegistrationBinder(this);
213 
214         /**
215          * Notifies the framework when the IMS Provider is registered to the IMS network.
216          *
217          * @param imsTransportType the radio access technology.
218          * @deprecated Use {@link #onRegistered(ImsRegistrationAttributes)} instead.
219          */
220         @Deprecated
onRegistered(@ccessNetworkConstants.TransportType int imsTransportType)221         public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
222         }
223 
224         /**
225          * Notifies the framework when the IMS Provider is registered to the IMS network
226          * with corresponding attributes.
227          *
228          * @param attributes The attributes associated with this IMS registration.
229          */
onRegistered(@onNull ImsRegistrationAttributes attributes)230         public void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
231             // Default impl to keep backwards compatibility with old implementations
232             onRegistered(attributes.getTransportType());
233         }
234 
235         /**
236          * Notifies the framework when the IMS Provider is trying to register the IMS network.
237          *
238          * @param imsTransportType the radio access technology.
239          * @deprecated Use {@link #onRegistering(ImsRegistrationAttributes)} instead.
240          */
onRegistering(@ccessNetworkConstants.TransportType int imsTransportType)241         public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
242         }
243 
244         /**
245          * Notifies the framework when the IMS Provider is trying to register the IMS network.
246          *
247          * @param attributes The attributes associated with this IMS registration.
248          */
onRegistering(@onNull ImsRegistrationAttributes attributes)249         public void onRegistering(@NonNull ImsRegistrationAttributes attributes) {
250             // Default impl to keep backwards compatibility with old implementations
251             onRegistering(attributes.getTransportType());
252         }
253 
254         /**
255          * Notifies the framework when the IMS Provider is unregistered from the IMS network.
256          *
257          * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
258          */
onUnregistered(@onNull ImsReasonInfo info)259         public void onUnregistered(@NonNull ImsReasonInfo info) {
260         }
261 
262         /**
263          * A failure has occurred when trying to handover registration to another technology type.
264          *
265          * @param imsTransportType The transport type that has failed to handover registration to.
266          * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
267          */
onTechnologyChangeFailed( @ccessNetworkConstants.TransportType int imsTransportType, @NonNull ImsReasonInfo info)268         public void onTechnologyChangeFailed(
269                 @AccessNetworkConstants.TransportType int imsTransportType,
270                 @NonNull ImsReasonInfo info) {
271         }
272 
273         /**
274          * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
275          * it changes. Per RFC3455, an associated URI is a URI that the service provider has
276          * allocated to a user for their own usage. A user's phone number is typically one of the
277          * associated URIs.
278          * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
279          *         subscription.
280          * @hide
281          */
onSubscriberAssociatedUriChanged(@ullable Uri[] uris)282         public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
283         }
284 
285         /**@hide*/
getBinder()286         public final IImsRegistrationCallback getBinder() {
287             return mBinder;
288         }
289 
290         /**@hide*/
291         //Only exposed as public for compatibility with deprecated ImsManager APIs.
setExecutor(Executor executor)292         public void setExecutor(Executor executor) {
293             mBinder.setExecutor(executor);
294         }
295     }
296 
297     /**
298      * Registers a {@link RegistrationCallback} with the system. Use
299      * @param executor The {@link Executor} that will be used to call the IMS registration state
300      *                 callback.
301      * @param c A callback called on the supplied {@link Executor} that will contain the
302      *                      registration state of the IMS service, which will be one of the
303      * {@see  SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
304      * events and call {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up.
305      *
306      * When the callback is registered, it will initiate the callback c to be called with the
307      * current registration state.
308      *
309      * @param executor The executor the callback events should be run on.
310      * @param c The {@link RegistrationCallback} to be added.
311      * @see #unregisterImsRegistrationCallback(RegistrationCallback)
312      * @throws ImsException if the subscription associated with this callback is valid, but
313      * the {@link ImsService} associated with the subscription is not available. This can happen if
314      * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
315      * reason.
316      */
317     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
registerImsRegistrationCallback(@onNull @allbackExecutor Executor executor, @NonNull RegistrationCallback c)318     void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
319             @NonNull RegistrationCallback c) throws ImsException;
320 
321     /**
322      * Removes an existing {@link RegistrationCallback}.
323      *
324      * When the subscription associated with this callback is removed (SIM removed, ESIM swap,
325      * etc...), this callback will automatically be removed. If this method is called for an
326      * inactive subscription, it will result in a no-op.
327      *
328      * @param c The {@link RegistrationCallback} to be removed.
329      * @see android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
330      * @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
331      */
332     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
unregisterImsRegistrationCallback(@onNull RegistrationCallback c)333     void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c);
334 
335     /**
336      * Gets the registration state of the IMS service.
337      * @param executor The {@link Executor} that will be used to call the IMS registration state
338      *                 callback.
339      * @param stateCallback A callback called on the supplied {@link Executor} that will contain the
340  *                      registration state of the IMS service, which will be one of the
341  *                      following: {@link #REGISTRATION_STATE_NOT_REGISTERED},
342  *                      {@link #REGISTRATION_STATE_REGISTERING}, or
343  *                      {@link #REGISTRATION_STATE_REGISTERED}.
344      */
345     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getRegistrationState(@onNull @allbackExecutor Executor executor, @NonNull @ImsRegistrationState Consumer<Integer> stateCallback)346     void getRegistrationState(@NonNull @CallbackExecutor Executor executor,
347             @NonNull @ImsRegistrationState Consumer<Integer> stateCallback);
348 
349     /**
350      * Gets the Transport Type associated with the current IMS registration.
351      * @param executor The {@link Executor} that will be used to call the transportTypeCallback.
352      * @param transportTypeCallback The transport type associated with the current IMS registration,
353      * which will be one of following:
354      * {@see AccessNetworkConstants#TRANSPORT_TYPE_WWAN},
355      * {@see AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, or
356      * {@see AccessNetworkConstants#TRANSPORT_TYPE_INVALID}.
357      */
358     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getRegistrationTransportType( @onNull @allbackExecutor Executor executor, @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback)359     void getRegistrationTransportType(
360             @NonNull @CallbackExecutor Executor executor,
361             @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback);
362 }
363