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