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