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 com.android.phone; 18 19 import static android.content.pm.PackageManager.FEATURE_TELEPHONY_IMS; 20 import static android.content.pm.PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION; 21 import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING; 22 23 import android.Manifest; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.app.compat.CompatChanges; 27 import android.compat.annotation.ChangeId; 28 import android.compat.annotation.EnabledAfter; 29 import android.content.pm.PackageManager; 30 import android.net.Uri; 31 import android.os.Binder; 32 import android.os.Build; 33 import android.os.RemoteException; 34 import android.os.ServiceSpecificException; 35 import android.os.SystemProperties; 36 import android.os.UserHandle; 37 import android.telephony.SubscriptionManager; 38 import android.telephony.TelephonyFrameworkInitializer; 39 import android.telephony.ims.DelegateRequest; 40 import android.telephony.ims.ImsException; 41 import android.telephony.ims.RcsContactUceCapability; 42 import android.telephony.ims.RcsUceAdapter.PublishState; 43 import android.telephony.ims.RegistrationManager; 44 import android.telephony.ims.aidl.IImsCapabilityCallback; 45 import android.telephony.ims.aidl.IImsRcsController; 46 import android.telephony.ims.aidl.IImsRegistrationCallback; 47 import android.telephony.ims.aidl.IRcsUceControllerCallback; 48 import android.telephony.ims.aidl.IRcsUcePublishStateCallback; 49 import android.telephony.ims.aidl.ISipDelegate; 50 import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback; 51 import android.telephony.ims.aidl.ISipDelegateMessageCallback; 52 import android.telephony.ims.feature.ImsFeature; 53 import android.telephony.ims.feature.RcsFeature; 54 import android.telephony.ims.stub.ImsRegistrationImplBase; 55 import android.util.Log; 56 57 import com.android.ims.ImsManager; 58 import com.android.ims.internal.IImsServiceFeatureCallback; 59 import com.android.internal.telephony.IIntegerConsumer; 60 import com.android.internal.telephony.ISipDialogStateCallback; 61 import com.android.internal.telephony.Phone; 62 import com.android.internal.telephony.TelephonyPermissions; 63 import com.android.internal.telephony.flags.FeatureFlags; 64 import com.android.internal.telephony.ims.ImsResolver; 65 import com.android.services.telephony.rcs.RcsFeatureController; 66 import com.android.services.telephony.rcs.SipTransportController; 67 import com.android.services.telephony.rcs.TelephonyRcsService; 68 import com.android.services.telephony.rcs.UceControllerManager; 69 70 import java.util.List; 71 import java.util.Set; 72 73 /** 74 * Implementation of the IImsRcsController interface. 75 */ 76 public class ImsRcsController extends IImsRcsController.Stub { 77 private static final String TAG = "ImsRcsController"; 78 79 /** The singleton instance. */ 80 private static ImsRcsController sInstance; 81 82 private PhoneGlobals mApp; 83 private TelephonyRcsService mRcsService; 84 private ImsResolver mImsResolver; 85 private FeatureFlags mFeatureFlags; 86 private PackageManager mPackageManager; 87 // set by shell cmd phone src set-device-enabled true/false 88 private Boolean mSingleRegistrationOverride; 89 private final int mVendorApiLevel; 90 91 /** 92 * For apps targeting Android T and above, support the publishing state on APIs, such as 93 * {@code RcsUceAdapter#PUBLISH_STATE_PUBLISHING} 94 * @hide 95 */ 96 @ChangeId 97 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S) 98 public static final long SUPPORT_PUBLISHING_STATE = 202894742; 99 100 /** 101 * Initialize the singleton ImsRcsController instance. 102 * This is only done once, at startup, from PhoneApp.onCreate(). 103 */ init(PhoneGlobals app, FeatureFlags featureFlags)104 static ImsRcsController init(PhoneGlobals app, FeatureFlags featureFlags) { 105 synchronized (ImsRcsController.class) { 106 if (sInstance == null) { 107 sInstance = new ImsRcsController(app, featureFlags); 108 } else { 109 Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance); 110 } 111 return sInstance; 112 } 113 } 114 115 /** Private constructor; @see init() */ ImsRcsController(PhoneGlobals app, FeatureFlags featureFlags)116 private ImsRcsController(PhoneGlobals app, FeatureFlags featureFlags) { 117 Log.i(TAG, "ImsRcsController"); 118 mApp = app; 119 mFeatureFlags = featureFlags; 120 mPackageManager = mApp.getPackageManager(); 121 TelephonyFrameworkInitializer 122 .getTelephonyServiceManager().getTelephonyImsServiceRegisterer().register(this); 123 mImsResolver = ImsResolver.getInstance(); 124 mVendorApiLevel = SystemProperties.getInt( 125 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT); 126 } 127 128 /** 129 * Register a {@link RegistrationManager.RegistrationCallback} to receive IMS network 130 * registration state. 131 */ 132 @Override registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback)133 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback) { 134 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( 135 mApp, subId, "registerImsRegistrationCallback"); 136 137 enforceTelephonyFeatureWithException(getCurrentPackageName(), 138 FEATURE_TELEPHONY_IMS, "registerImsRegistrationCallback"); 139 140 final long token = Binder.clearCallingIdentity(); 141 try { 142 getRcsFeatureController(subId).registerImsRegistrationCallback(subId, callback); 143 } catch (ImsException e) { 144 Log.e(TAG, "registerImsRegistrationCallback: sudId=" + subId + ", " + e.getMessage()); 145 throw new ServiceSpecificException(e.getCode()); 146 } finally { 147 Binder.restoreCallingIdentity(token); 148 } 149 } 150 151 /** 152 * Removes an existing {@link RegistrationManager.RegistrationCallback}. 153 */ 154 @Override unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback)155 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) { 156 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( 157 mApp, subId, "unregisterImsRegistrationCallback"); 158 159 enforceTelephonyFeatureWithException(getCurrentPackageName(), 160 FEATURE_TELEPHONY_IMS, "unregisterImsRegistrationCallback"); 161 162 final long token = Binder.clearCallingIdentity(); 163 try { 164 getRcsFeatureController(subId).unregisterImsRegistrationCallback(subId, callback); 165 } catch (ServiceSpecificException e) { 166 Log.e(TAG, "unregisterImsRegistrationCallback: error=" + e.errorCode); 167 } finally { 168 Binder.restoreCallingIdentity(token); 169 } 170 } 171 172 /** 173 * Get the IMS service registration state for the RcsFeature associated with this sub id. 174 */ 175 @Override getImsRcsRegistrationState(int subId, IIntegerConsumer consumer)176 public void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer) { 177 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( 178 mApp, subId, "getImsRcsRegistrationState"); 179 180 enforceTelephonyFeatureWithException(getCurrentPackageName(), 181 FEATURE_TELEPHONY_IMS, "getImsRcsRegistrationState"); 182 183 final long token = Binder.clearCallingIdentity(); 184 try { 185 getRcsFeatureController(subId).getRegistrationState(regState -> { 186 try { 187 consumer.accept((regState == null) 188 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState); 189 } catch (RemoteException e) { 190 Log.w(TAG, "getImsRcsRegistrationState: callback is not available."); 191 } 192 }); 193 } finally { 194 Binder.restoreCallingIdentity(token); 195 } 196 } 197 198 /** 199 * Gets the Transport Type associated with the current IMS RCS registration. 200 */ 201 @Override getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer)202 public void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer) { 203 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( 204 mApp, subId, "getImsRcsRegistrationTransportType"); 205 206 enforceTelephonyFeatureWithException(getCurrentPackageName(), 207 FEATURE_TELEPHONY_IMS, "getImsRcsRegistrationTransportType"); 208 209 final long token = Binder.clearCallingIdentity(); 210 try { 211 getRcsFeatureController(subId).getRegistrationTech(regTech -> { 212 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager 213 int regTechConverted = (regTech == null) 214 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech; 215 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get( 216 regTechConverted); 217 try { 218 consumer.accept(regTechConverted); 219 } catch (RemoteException e) { 220 Log.w(TAG, "getImsRcsRegistrationTransportType: callback is not available."); 221 } 222 }); 223 } finally { 224 Binder.restoreCallingIdentity(token); 225 } 226 } 227 228 /** 229 * Register a capability callback which will provide RCS availability updates for the 230 * subscription specified. 231 * 232 * @param subId the subscription ID 233 * @param callback The ImsCapabilityCallback to be registered. 234 */ 235 @Override registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback)236 public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) { 237 enforceReadPrivilegedPermission("registerRcsAvailabilityCallback"); 238 239 enforceTelephonyFeatureWithException(getCurrentPackageName(), 240 FEATURE_TELEPHONY_IMS, "registerRcsAvailabilityCallback"); 241 242 final long token = Binder.clearCallingIdentity(); 243 try { 244 getRcsFeatureController(subId).registerRcsAvailabilityCallback(subId, callback); 245 } catch (ImsException e) { 246 Log.e(TAG, "registerRcsAvailabilityCallback: sudId=" + subId + ", " + e.getMessage()); 247 throw new ServiceSpecificException(e.getCode()); 248 } finally { 249 Binder.restoreCallingIdentity(token); 250 } 251 } 252 253 /** 254 * Remove the registered capability callback. 255 * 256 * @param subId the subscription ID 257 * @param callback The ImsCapabilityCallback to be removed. 258 */ 259 @Override unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback)260 public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) { 261 enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback"); 262 263 enforceTelephonyFeatureWithException(getCurrentPackageName(), 264 FEATURE_TELEPHONY_IMS, "unregisterRcsAvailabilityCallback"); 265 266 final long token = Binder.clearCallingIdentity(); 267 try { 268 getRcsFeatureController(subId).unregisterRcsAvailabilityCallback(subId, callback); 269 } catch (ServiceSpecificException e) { 270 Log.e(TAG, "unregisterRcsAvailabilityCallback: error=" + e.errorCode); 271 } finally { 272 Binder.restoreCallingIdentity(token); 273 } 274 } 275 276 /** 277 * Query for the capability of an IMS RCS service 278 * 279 * @param subId the subscription ID 280 * @param capability the RCS capability to query. 281 * @param radioTech the radio technology type that we are querying. 282 * @return true if the RCS capability is capable for this subscription, false otherwise. 283 */ 284 @Override isCapable(int subId, @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability, @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)285 public boolean isCapable(int subId, 286 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability, 287 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) { 288 enforceReadPrivilegedPermission("isCapable"); 289 290 enforceTelephonyFeatureWithException(getCurrentPackageName(), 291 FEATURE_TELEPHONY_IMS, "isCapable"); 292 293 final long token = Binder.clearCallingIdentity(); 294 try { 295 return getRcsFeatureController(subId).isCapable(capability, radioTech); 296 } catch (ImsException e) { 297 Log.e(TAG, "isCapable: sudId=" + subId 298 + ", capability=" + capability + ", " + e.getMessage()); 299 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 300 } finally { 301 Binder.restoreCallingIdentity(token); 302 } 303 } 304 305 /** 306 * Query the availability of an IMS RCS capability. 307 * 308 * @param subId the subscription ID 309 * @param capability the RCS capability to query. 310 * @return true if the RCS capability is currently available for the associated subscription, 311 * @param radioTech the radio technology type that we are querying. 312 * false otherwise. 313 */ 314 @Override isAvailable(int subId, @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability, @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)315 public boolean isAvailable(int subId, 316 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability, 317 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) { 318 enforceReadPrivilegedPermission("isAvailable"); 319 320 enforceTelephonyFeatureWithException(getCurrentPackageName(), 321 FEATURE_TELEPHONY_IMS, "isAvailable"); 322 323 final long token = Binder.clearCallingIdentity(); 324 try { 325 return getRcsFeatureController(subId).isAvailable(capability, radioTech); 326 } catch (ImsException e) { 327 Log.e(TAG, "isAvailable: sudId=" + subId 328 + ", capability=" + capability + ", " + e.getMessage()); 329 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 330 } finally { 331 Binder.restoreCallingIdentity(token); 332 } 333 } 334 335 @Override requestCapabilities(int subId, String callingPackage, String callingFeatureId, List<Uri> contactNumbers, IRcsUceControllerCallback c)336 public void requestCapabilities(int subId, String callingPackage, String callingFeatureId, 337 List<Uri> contactNumbers, IRcsUceControllerCallback c) { 338 enforceAccessUserCapabilityExchangePermission("requestCapabilities"); 339 enforceReadContactsPermission("requestCapabilities"); 340 341 enforceTelephonyFeatureWithException(callingPackage, 342 FEATURE_TELEPHONY_IMS, "requestCapabilities"); 343 344 final long token = Binder.clearCallingIdentity(); 345 try { 346 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 347 UceControllerManager.class); 348 if (uceCtrlManager == null) { 349 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 350 "This subscription does not support UCE."); 351 } 352 uceCtrlManager.requestCapabilities(contactNumbers, c); 353 } catch (ImsException e) { 354 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 355 } finally { 356 Binder.restoreCallingIdentity(token); 357 } 358 } 359 360 @Override requestAvailability(int subId, String callingPackage, String callingFeatureId, Uri contactNumber, IRcsUceControllerCallback c)361 public void requestAvailability(int subId, String callingPackage, 362 String callingFeatureId, Uri contactNumber, IRcsUceControllerCallback c) { 363 enforceAccessUserCapabilityExchangePermission("requestAvailability"); 364 enforceReadContactsPermission("requestAvailability"); 365 366 enforceTelephonyFeatureWithException(callingPackage, 367 FEATURE_TELEPHONY_IMS, "requestAvailability"); 368 369 final long token = Binder.clearCallingIdentity(); 370 try { 371 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 372 UceControllerManager.class); 373 if (uceCtrlManager == null) { 374 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 375 "This subscription does not support UCE."); 376 } 377 uceCtrlManager.requestNetworkAvailability(contactNumber, c); 378 } catch (ImsException e) { 379 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 380 } finally { 381 Binder.restoreCallingIdentity(token); 382 } 383 } 384 385 @Override getUcePublishState(int subId)386 public @PublishState int getUcePublishState(int subId) { 387 enforceReadPrivilegedPermission("getUcePublishState"); 388 389 enforceTelephonyFeatureWithException(getCurrentPackageName(), 390 FEATURE_TELEPHONY_IMS, "getUcePublishState"); 391 392 final int uid = Binder.getCallingUid(); 393 final long token = Binder.clearCallingIdentity(); 394 boolean isSupportPublishingState = false; 395 try { 396 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 397 UceControllerManager.class); 398 if (uceCtrlManager == null) { 399 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 400 "This subscription does not support UCE."); 401 } 402 if (CompatChanges.isChangeEnabled(SUPPORT_PUBLISHING_STATE, uid)) { 403 isSupportPublishingState = true; 404 } 405 return uceCtrlManager.getUcePublishState(isSupportPublishingState); 406 } catch (ImsException e) { 407 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 408 } finally { 409 Binder.restoreCallingIdentity(token); 410 } 411 } 412 413 /** 414 * Add new feature tags to the Set used to calculate the capabilities in PUBLISH. 415 */ 416 // Used for SHELL command only right now. addUceRegistrationOverrideShell(int subId, Set<String> featureTags)417 public RcsContactUceCapability addUceRegistrationOverrideShell(int subId, 418 Set<String> featureTags) throws ImsException { 419 // Permission check happening in PhoneInterfaceManager. 420 try { 421 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 422 UceControllerManager.class); 423 if (uceCtrlManager == null) { 424 return null; 425 } 426 return uceCtrlManager.addUceRegistrationOverride(featureTags); 427 } catch (ServiceSpecificException e) { 428 throw new ImsException(e.getMessage(), e.errorCode); 429 } 430 } 431 432 /** 433 * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH. 434 */ 435 // Used for SHELL command only right now. removeUceRegistrationOverrideShell(int subId, Set<String> featureTags)436 public RcsContactUceCapability removeUceRegistrationOverrideShell(int subId, 437 Set<String> featureTags) throws ImsException { 438 // Permission check happening in PhoneInterfaceManager. 439 try { 440 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 441 UceControllerManager.class); 442 if (uceCtrlManager == null) { 443 return null; 444 } 445 return uceCtrlManager.removeUceRegistrationOverride(featureTags); 446 } catch (ServiceSpecificException e) { 447 throw new ImsException(e.getMessage(), e.errorCode); 448 } 449 } 450 451 /** 452 * Clear all overrides in the Set used to calculate the capabilities in PUBLISH. 453 */ 454 // Used for SHELL command only right now. clearUceRegistrationOverrideShell(int subId)455 public RcsContactUceCapability clearUceRegistrationOverrideShell(int subId) 456 throws ImsException { 457 try { 458 // Permission check happening in PhoneInterfaceManager. 459 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 460 UceControllerManager.class); 461 if (uceCtrlManager == null) { 462 return null; 463 } 464 return uceCtrlManager.clearUceRegistrationOverride(); 465 } catch (ServiceSpecificException e) { 466 throw new ImsException(e.getMessage(), e.errorCode); 467 } 468 } 469 470 /** 471 * @return current RcsContactUceCapability instance that will be used for PUBLISH. 472 */ 473 // Used for SHELL command only right now. getLatestRcsContactUceCapabilityShell(int subId)474 public RcsContactUceCapability getLatestRcsContactUceCapabilityShell(int subId) 475 throws ImsException { 476 try { 477 // Permission check happening in PhoneInterfaceManager. 478 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 479 UceControllerManager.class); 480 if (uceCtrlManager == null) { 481 return null; 482 } 483 return uceCtrlManager.getLatestRcsContactUceCapability(); 484 } catch (ServiceSpecificException e) { 485 throw new ImsException(e.getMessage(), e.errorCode); 486 } 487 } 488 489 /** 490 * @return the PIDf XML used in the last PUBLISH procedure or "none" if the device is not 491 * published. Returns {@code null} if the operation failed due to an error. 492 */ 493 // Used for SHELL command only right now. getLastUcePidfXmlShell(int subId)494 public String getLastUcePidfXmlShell(int subId) throws ImsException { 495 try { 496 // Permission check happening in PhoneInterfaceManager. 497 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 498 UceControllerManager.class); 499 if (uceCtrlManager == null) { 500 return null; 501 } 502 String pidfXml = uceCtrlManager.getLastPidfXml(); 503 return pidfXml == null ? "none" : pidfXml; 504 } catch (ServiceSpecificException e) { 505 throw new ImsException(e.getMessage(), e.errorCode); 506 } 507 } 508 509 /** 510 * Remove UCE requests cannot be sent to the network status. 511 * @return true if this command is successful. 512 */ 513 // Used for SHELL command only right now. removeUceRequestDisallowedStatus(int subId)514 public boolean removeUceRequestDisallowedStatus(int subId) throws ImsException { 515 try { 516 UceControllerManager uceCtrlManager = getRcsFeatureController(subId, true).getFeature( 517 UceControllerManager.class); 518 if (uceCtrlManager == null) { 519 return false; 520 } 521 return uceCtrlManager.removeUceRequestDisallowedStatus(); 522 } catch (ServiceSpecificException e) { 523 throw new ImsException(e.getMessage(), e.errorCode); 524 } 525 } 526 527 /** 528 * Set the timeout for contact capabilities request. 529 */ 530 // Used for SHELL command only right now. setCapabilitiesRequestTimeout(int subId, long timeoutAfter)531 public boolean setCapabilitiesRequestTimeout(int subId, long timeoutAfter) throws ImsException { 532 try { 533 UceControllerManager uceCtrlManager = getRcsFeatureController(subId, true).getFeature( 534 UceControllerManager.class); 535 if (uceCtrlManager == null) { 536 return false; 537 } 538 return uceCtrlManager.setCapabilitiesRequestTimeout(timeoutAfter); 539 } catch (ServiceSpecificException e) { 540 throw new ImsException(e.getMessage(), e.errorCode); 541 } 542 } 543 544 @Override registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c)545 public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) { 546 enforceReadPrivilegedPermission("registerUcePublishStateCallback"); 547 548 enforceTelephonyFeatureWithException(getCurrentPackageName(), 549 FEATURE_TELEPHONY_IMS, "registerUcePublishStateCallback"); 550 551 final int uid = Binder.getCallingUid(); 552 final long token = Binder.clearCallingIdentity(); 553 boolean isSupportPublishingState = false; 554 try { 555 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 556 UceControllerManager.class); 557 if (uceCtrlManager == null) { 558 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 559 "This subscription does not support UCE."); 560 } 561 562 if (CompatChanges.isChangeEnabled(SUPPORT_PUBLISHING_STATE, uid)) { 563 isSupportPublishingState = true; 564 } 565 uceCtrlManager.registerPublishStateCallback(c, isSupportPublishingState); 566 } catch (ImsException e) { 567 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 568 } finally { 569 Binder.restoreCallingIdentity(token); 570 } 571 } 572 573 @Override unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c)574 public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) { 575 enforceReadPrivilegedPermission("unregisterUcePublishStateCallback"); 576 577 enforceTelephonyFeatureWithException(getCurrentPackageName(), 578 FEATURE_TELEPHONY_IMS, "unregisterUcePublishStateCallback"); 579 580 final long token = Binder.clearCallingIdentity(); 581 try { 582 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature( 583 UceControllerManager.class); 584 if (uceCtrlManager == null) { 585 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 586 "This subscription does not support UCE."); 587 } 588 uceCtrlManager.unregisterPublishStateCallback(c); 589 } catch (ServiceSpecificException e) { 590 Log.e(TAG, "unregisterUcePublishStateCallback: error=" + e.errorCode); 591 } finally { 592 Binder.restoreCallingIdentity(token); 593 } 594 } 595 596 @Override isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId)597 public boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId) { 598 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( 599 mApp, subId, callingPackage, callingFeatureId, "isUceSettingEnabled")) { 600 Log.w(TAG, "isUceSettingEnabled: READ_PHONE_STATE app op disabled when accessing " 601 + "isUceSettingEnabled"); 602 return false; 603 } 604 605 enforceTelephonyFeatureWithException(callingPackage, 606 FEATURE_TELEPHONY_IMS, "isUceSettingEnabled"); 607 608 final long token = Binder.clearCallingIdentity(); 609 try { 610 return SubscriptionManager.getBooleanSubscriptionProperty(subId, 611 SubscriptionManager.IMS_RCS_UCE_ENABLED, false /*defaultValue*/, mApp); 612 } finally { 613 Binder.restoreCallingIdentity(token); 614 } 615 } 616 617 @Override setUceSettingEnabled(int subId, boolean isEnabled)618 public void setUceSettingEnabled(int subId, boolean isEnabled) { 619 enforceModifyPermission(); 620 621 enforceTelephonyFeatureWithException(getCurrentPackageName(), 622 FEATURE_TELEPHONY_IMS, "setUceSettingEnabled"); 623 624 final long token = Binder.clearCallingIdentity(); 625 try { 626 SubscriptionManager.setSubscriptionProperty(subId, 627 SubscriptionManager.IMS_RCS_UCE_ENABLED, (isEnabled ? "1" : "0")); 628 } finally { 629 Binder.restoreCallingIdentity(token); 630 } 631 } 632 633 @Override isSipDelegateSupported(int subId)634 public boolean isSipDelegateSupported(int subId) { 635 TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(), 636 "isSipDelegateSupported", 637 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION, 638 Manifest.permission.READ_PRIVILEGED_PHONE_STATE); 639 if (!isImsSingleRegistrationSupportedOnDevice()) { 640 return false; 641 } 642 final long token = Binder.clearCallingIdentity(); 643 try { 644 SipTransportController transport = getRcsFeatureController(subId).getFeature( 645 SipTransportController.class); 646 if (transport == null) { 647 return false; 648 } 649 return transport.isSupported(subId); 650 } catch (ImsException e) { 651 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 652 } catch (ServiceSpecificException e) { 653 if (e.errorCode == ImsException.CODE_ERROR_UNSUPPORTED_OPERATION) { 654 return false; 655 } 656 throw e; 657 } finally { 658 Binder.restoreCallingIdentity(token); 659 } 660 } 661 662 @Override createSipDelegate(int subId, DelegateRequest request, String packageName, ISipDelegateConnectionStateCallback delegateState, ISipDelegateMessageCallback delegateMessage)663 public void createSipDelegate(int subId, DelegateRequest request, String packageName, 664 ISipDelegateConnectionStateCallback delegateState, 665 ISipDelegateMessageCallback delegateMessage) { 666 enforceImsSingleRegistrationPermission("createSipDelegate"); 667 if (!isImsSingleRegistrationSupportedOnDevice()) { 668 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 669 "SipDelegate creation is only supported for devices supporting IMS single " 670 + "registration"); 671 } 672 if (!UserHandle.getUserHandleForUid(Binder.getCallingUid()).isSystem()) { 673 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 674 "SipDelegate creation is only available to primary user."); 675 } 676 try { 677 int remoteUid = mApp.getPackageManager().getPackageUid(packageName, 0 /*flags*/); 678 if (Binder.getCallingUid() != remoteUid) { 679 throw new SecurityException("passed in packageName does not match the caller"); 680 } 681 } catch (PackageManager.NameNotFoundException e) { 682 throw new SecurityException("Passed in PackageName can not be found on device"); 683 } 684 685 final int uid = Binder.getCallingUid(); 686 final long identity = Binder.clearCallingIdentity(); 687 SipTransportController transport = getRcsFeatureController(subId).getFeature( 688 SipTransportController.class); 689 if (transport == null) { 690 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 691 "This subscription does not support the creation of SIP delegates"); 692 } 693 try { 694 transport.createSipDelegate(subId, uid, request, packageName, delegateState, 695 delegateMessage); 696 } catch (ImsException e) { 697 throw new ServiceSpecificException(e.getCode(), e.getMessage()); 698 } finally { 699 Binder.restoreCallingIdentity(identity); 700 } 701 } 702 703 @Override destroySipDelegate(int subId, ISipDelegate connection, int reason)704 public void destroySipDelegate(int subId, ISipDelegate connection, int reason) { 705 // Do not check permissions here - the caller needs to have a connection already from the 706 // create method to call this method. 707 if (connection == null) { 708 return; 709 } 710 final long identity = Binder.clearCallingIdentity(); 711 try { 712 SipTransportController transport = getRcsFeatureController(subId).getFeature( 713 SipTransportController.class); 714 if (transport == null) { 715 return; 716 } 717 transport.destroySipDelegate(subId, connection, reason); 718 } catch (ServiceSpecificException e) { 719 Log.e(TAG, "destroySipDelegate: error=" + e.errorCode); 720 } finally { 721 Binder.restoreCallingIdentity(identity); 722 } 723 } 724 725 @Override triggerNetworkRegistration(int subId, ISipDelegate connection, int sipCode, String sipReason)726 public void triggerNetworkRegistration(int subId, ISipDelegate connection, int sipCode, 727 String sipReason) { 728 enforceImsSingleRegistrationPermission("triggerNetworkRegistration"); 729 730 final long identity = Binder.clearCallingIdentity(); 731 try { 732 SipTransportController transport = getRcsFeatureController(subId).getFeature( 733 SipTransportController.class); 734 if (transport == null) { 735 return; 736 } 737 transport.triggerFullNetworkRegistration(subId, connection, sipCode, sipReason); 738 } catch (ServiceSpecificException e) { 739 Log.e(TAG, "triggerNetworkRegistration: error=" + e.errorCode); 740 } finally { 741 Binder.restoreCallingIdentity(identity); 742 } 743 } 744 745 /** 746 * Register a state of Sip Dialog callback 747 */ 748 @Override registerSipDialogStateCallback(int subId, ISipDialogStateCallback cb)749 public void registerSipDialogStateCallback(int subId, ISipDialogStateCallback cb) { 750 enforceReadPrivilegedPermission("registerSipDialogStateCallback"); 751 if (cb == null) { 752 throw new IllegalArgumentException("SipDialogStateCallback is null"); 753 } 754 final long identity = Binder.clearCallingIdentity(); 755 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 756 throw new IllegalArgumentException("Invalid Subscription ID: " + subId); 757 } 758 759 enforceTelephonyFeatureWithException(getCurrentPackageName(), 760 FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "registerSipDialogStateCallback"); 761 762 try { 763 SipTransportController transport = getRcsFeatureController(subId).getFeature( 764 SipTransportController.class); 765 if (transport == null) { 766 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, 767 "This transport does not support the registerSipDialogStateCallback" 768 + " of SIP delegates"); 769 } 770 transport.addCallbackForSipDialogState(subId, cb); 771 } finally { 772 Binder.restoreCallingIdentity(identity); 773 } 774 } 775 776 /** 777 * Unregister a state of Sip Dialog callback 778 */ 779 @Override unregisterSipDialogStateCallback(int subId, ISipDialogStateCallback cb)780 public void unregisterSipDialogStateCallback(int subId, ISipDialogStateCallback cb) { 781 enforceReadPrivilegedPermission("unregisterSipDialogStateCallback"); 782 if (cb == null) { 783 throw new IllegalArgumentException("SipDialogStateCallback is null"); 784 } 785 final long identity = Binder.clearCallingIdentity(); 786 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 787 throw new IllegalArgumentException("Invalid Subscription ID: " + subId); 788 } 789 790 enforceTelephonyFeatureWithException(getCurrentPackageName(), 791 FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "unregisterSipDialogStateCallback"); 792 793 try { 794 SipTransportController transport = getRcsFeatureController(subId).getFeature( 795 SipTransportController.class); 796 if (transport == null) { 797 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, 798 "This transport does not support the unregisterSipDialogStateCallback" 799 + " of SIP delegates"); 800 } 801 transport.removeCallbackForSipDialogState(subId, cb); 802 } finally { 803 Binder.restoreCallingIdentity(identity); 804 } 805 } 806 807 /** 808 * Registers for updates to the RcsFeature connection through the IImsServiceFeatureCallback 809 * callback. 810 */ 811 @Override registerRcsFeatureCallback(int slotId, IImsServiceFeatureCallback callback)812 public void registerRcsFeatureCallback(int slotId, IImsServiceFeatureCallback callback) { 813 enforceModifyPermission(); 814 815 final long identity = Binder.clearCallingIdentity(); 816 try { 817 if (mImsResolver == null) { 818 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 819 "Device does not support IMS"); 820 } 821 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_RCS, callback); 822 } finally { 823 Binder.restoreCallingIdentity(identity); 824 } 825 } 826 827 /** 828 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature. 829 */ 830 @Override unregisterImsFeatureCallback(IImsServiceFeatureCallback callback)831 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) { 832 enforceModifyPermission(); 833 834 final long identity = Binder.clearCallingIdentity(); 835 try { 836 if (mImsResolver == null) return; 837 mImsResolver.unregisterImsFeatureCallback(callback); 838 } finally { 839 Binder.restoreCallingIdentity(identity); 840 } 841 } 842 843 /** 844 * Make sure either called from same process as self (phone) or IPC caller has read privilege. 845 * 846 * @throws SecurityException if the caller does not have the required permission 847 */ enforceReadPrivilegedPermission(String message)848 private void enforceReadPrivilegedPermission(String message) { 849 mApp.enforceCallingOrSelfPermission( 850 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message); 851 } 852 853 /** 854 * @throws SecurityException if the caller does not have the required 855 * PERFORM_IMS_SINGLE_REGISTRATION permission. 856 */ enforceImsSingleRegistrationPermission(String message)857 private void enforceImsSingleRegistrationPermission(String message) { 858 mApp.enforceCallingOrSelfPermission( 859 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION, message); 860 } 861 862 /** 863 * Make sure the caller has the MODIFY_PHONE_STATE permission. 864 * 865 * @throws SecurityException if the caller does not have the required permission 866 */ enforceModifyPermission()867 private void enforceModifyPermission() { 868 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 869 } 870 871 /** 872 * Make sure the caller has the ACCESS_RCS_USER_CAPABILITY_EXCHANGE permission. 873 * 874 * @throws SecurityException if the caller does not have the required permission. 875 */ enforceAccessUserCapabilityExchangePermission(String message)876 private void enforceAccessUserCapabilityExchangePermission(String message) { 877 mApp.enforceCallingOrSelfPermission( 878 android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, message); 879 } 880 881 /** 882 * Make sure the caller has the READ_CONTACTS permission. 883 * 884 * @throws SecurityException if the caller does not have the required permission. 885 */ enforceReadContactsPermission(String message)886 private void enforceReadContactsPermission(String message) { 887 mApp.enforceCallingOrSelfPermission( 888 android.Manifest.permission.READ_CONTACTS, message); 889 } 890 891 /** 892 * Retrieve RcsFeatureManager instance. 893 * 894 * @param subId the subscription ID 895 * @return The RcsFeatureManager instance 896 * @throws ServiceSpecificException if getting RcsFeatureManager instance failed. 897 */ getRcsFeatureController(int subId)898 private RcsFeatureController getRcsFeatureController(int subId) { 899 return getRcsFeatureController(subId, false /* skipVerifyingConfig */); 900 } 901 902 /** 903 * Retrieve RcsFeatureManager instance. 904 * 905 * @param subId the subscription ID 906 * @param skipVerifyingConfig If the RCS configuration can be skip. 907 * @return The RcsFeatureManager instance 908 * @throws ServiceSpecificException if getting RcsFeatureManager instance failed. 909 */ getRcsFeatureController(int subId, boolean skipVerifyingConfig)910 private RcsFeatureController getRcsFeatureController(int subId, boolean skipVerifyingConfig) { 911 if (!ImsManager.isImsSupportedOnDevice(mApp)) { 912 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 913 "IMS is not available on device."); 914 } 915 if (mRcsService == null) { 916 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 917 "IMS is not available on device."); 918 } 919 Phone phone = PhoneGlobals.getPhone(subId); 920 if (phone == null) { 921 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION, 922 "Invalid subscription Id: " + subId); 923 } 924 int slotId = phone.getPhoneId(); 925 if (!skipVerifyingConfig) { 926 verifyImsRcsConfiguredOrThrow(slotId); 927 verifyRcsSubIdActiveOrThrow(slotId, subId); 928 } 929 RcsFeatureController c = mRcsService.getFeatureController(slotId); 930 if (c == null) { 931 // If we hit this case, we have verified that TelephonyRcsService has processed any 932 // subId changes for the associated slot and applied configs. In this case, the configs 933 // do not have the RCS feature enabled. 934 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 935 "The requested operation is not supported for subId " + subId); 936 } 937 if (!skipVerifyingConfig && c.getAssociatedSubId() != subId) { 938 // If we hit this case, the ImsFeature has not finished setting up the RCS feature yet 939 // or the RCS feature has crashed and is being set up again. 940 Log.w(TAG, "getRcsFeatureController: service unavailable on slot " + slotId 941 + " for subId " + subId); 942 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, 943 "The ImsService is not currently available for subid " + subId 944 + ", please try again"); 945 } 946 return c; 947 } 948 949 /** 950 * Ensure the TelephonyRcsService is tracking the supplied subId for the supplied slotId and has 951 * set up the stack. 952 */ verifyRcsSubIdActiveOrThrow(int slotId, int subId)953 private void verifyRcsSubIdActiveOrThrow(int slotId, int subId) { 954 if (mRcsService.verifyActiveSubId(slotId, subId)) return; 955 956 Log.w(TAG, "verifyRcsSubIdActiveOrThrow: verify failed, service not set up yet on " 957 + "slot " + slotId + " for subId " + subId); 958 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, 959 "ImsService set up in progress for subId " + subId 960 + ", please try again"); 961 } 962 963 /** 964 * Throw an ImsException if the IMS resolver does not have an ImsService configured for RCS 965 * for the given slot ID or no ImsResolver instance has been created. 966 * @param slotId The slot ID that the IMS service is created for. 967 * @throws ServiceSpecificException If there is no ImsService configured for this slot. 968 */ verifyImsRcsConfiguredOrThrow(int slotId)969 private void verifyImsRcsConfiguredOrThrow(int slotId) { 970 if (mImsResolver == null 971 || !mImsResolver.isImsServiceConfiguredForFeature(slotId, ImsFeature.FEATURE_RCS)) { 972 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, 973 "This subscription does not support RCS"); 974 } 975 } 976 isImsSingleRegistrationSupportedOnDevice()977 private boolean isImsSingleRegistrationSupportedOnDevice() { 978 return mSingleRegistrationOverride != null ? mSingleRegistrationOverride 979 : mApp.getPackageManager().hasSystemFeature( 980 PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION); 981 } 982 983 /** 984 * Get the current calling package name. 985 * @return the current calling package name 986 */ 987 @Nullable getCurrentPackageName()988 private String getCurrentPackageName() { 989 if (mPackageManager == null) return null; 990 String[] callingUids = mPackageManager.getPackagesForUid(Binder.getCallingUid()); 991 return (callingUids == null) ? null : callingUids[0]; 992 } 993 994 /** 995 * Make sure the device has required telephony feature 996 * 997 * @throws UnsupportedOperationException if the device does not have required telephony feature 998 */ enforceTelephonyFeatureWithException(@ullable String callingPackage, @NonNull String telephonyFeature, @NonNull String methodName)999 private void enforceTelephonyFeatureWithException(@Nullable String callingPackage, 1000 @NonNull String telephonyFeature, @NonNull String methodName) { 1001 if (callingPackage == null || mPackageManager == null) { 1002 return; 1003 } 1004 1005 if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis() 1006 || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage, 1007 Binder.getCallingUserHandle()) 1008 || mVendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) { 1009 // Skip to check associated telephony feature, 1010 // if compatibility change is not enabled for the current process or 1011 // the SDK version of vendor partition is less than Android V. 1012 return; 1013 } 1014 1015 if (!mPackageManager.hasSystemFeature(telephonyFeature)) { 1016 throw new UnsupportedOperationException( 1017 methodName + " is unsupported without " + telephonyFeature); 1018 } 1019 } 1020 setRcsService(TelephonyRcsService rcsService)1021 void setRcsService(TelephonyRcsService rcsService) { 1022 mRcsService = rcsService; 1023 } 1024 1025 /** 1026 * Override device RCS single registration support check for CTS testing or remove override 1027 * if the Boolean is set to null. 1028 */ setDeviceSingleRegistrationSupportOverride(Boolean deviceOverrideValue)1029 void setDeviceSingleRegistrationSupportOverride(Boolean deviceOverrideValue) { 1030 mSingleRegistrationOverride = deviceOverrideValue; 1031 } 1032 } 1033