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.cts; 18 19 import android.app.Instrumentation; 20 import android.app.role.RoleManager; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.ServiceConnection; 25 import android.os.IBinder; 26 import android.telephony.cts.externalimsservice.ITestExternalImsService; 27 import android.telephony.cts.externalimsservice.TestExternalImsService; 28 import android.telephony.cts.util.TelephonyUtils; 29 import android.telephony.ims.feature.ImsFeature; 30 import android.telephony.ims.stub.ImsFeatureConfiguration; 31 import android.text.TextUtils; 32 import android.util.Log; 33 import android.util.SparseArray; 34 35 import androidx.test.platform.app.InstrumentationRegistry; 36 37 import com.android.compatibility.common.util.ShellIdentityUtils; 38 39 import java.util.List; 40 import java.util.concurrent.CountDownLatch; 41 import java.util.concurrent.LinkedBlockingQueue; 42 import java.util.concurrent.TimeUnit; 43 44 /** 45 * Connects The CTS test ImsService to the Telephony Framework. 46 */ 47 public class ImsServiceConnector { 48 49 private static final String TAG = "CtsImsServiceConnector"; 50 51 private static final String PACKAGE_NAME = 52 InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName(); 53 private static final String EXTERNAL_PACKAGE_NAME = 54 TestExternalImsService.class.getPackage().getName(); 55 56 private static final String COMMAND_BASE = "cmd phone "; 57 private static final String COMMAND_SET_IMS_SERVICE = "ims set-ims-service "; 58 private static final String COMMAND_GET_IMS_SERVICE = "ims get-ims-service "; 59 private static final String COMMAND_CLEAR_SERVICE_OVERRIDE = "ims clear-ims-service-override"; 60 private static final String COMMAND_CARRIER_SERVICE_IDENTIFIER = "-c "; 61 private static final String COMMAND_DEVICE_SERVICE_IDENTIFIER = "-d "; 62 private static final String COMMAND_USER_ID_IDENTIFIER = "-u "; 63 private static final String COMMAND_SLOT_IDENTIFIER = "-s "; 64 private static final String COMMAND_FEATURE_IDENTIFIER = "-f "; 65 private static final String COMMAND_ENABLE_IMS = "ims enable "; 66 private static final String COMMAND_DISABLE_IMS = "ims disable "; 67 private static final String COMMAND_SET_DEVICE_SINGLE_REGISTRATION_ENABLED = 68 "src set-device-enabled "; 69 private static final String COMMAND_GET_DEVICE_SINGLE_REGISTRATION_ENABLED = 70 "src get-device-enabled"; 71 private static final String COMMAND_SET_CARRIER_SINGLE_REGISTRATION_ENABLED = 72 "src set-carrier-enabled "; 73 private static final String COMMAND_GET_CARRIER_SINGLE_REGISTRATION_ENABLED = 74 "src get-carrier-enabled"; 75 private static final String COMMAND_REMOVE_EAB_CONTACT = "uce remove-eab-contact "; 76 private static final String COMMAND_GET_UCE_ENABLED = "uce get-device-enabled"; 77 private static final String COMMAND_SET_UCE_ENABLED = "uce set-device-enabled "; 78 private static final String COMMAND_REMOVE_UCE_REQUEST_DISALLOWED_STATUS = 79 "uce remove-request-disallowed-status "; 80 private static final String COMMAND_SET_CAPABILITY_REQUEST_TIMEOUT = 81 "uce set-capabilities-request-timeout "; 82 private static final String COMMAND_SET_TEST_MODE_ENABLED = "src set-test-enabled "; 83 private static final String COMMAND_SET_D2D_ENABLED = "d2d set-device-support "; 84 85 private boolean mIsTestTypeExecutor = false; 86 setExecutorTestType(boolean type)87 public void setExecutorTestType(boolean type) { 88 mIsTestTypeExecutor = type; 89 } 90 91 private class TestCarrierServiceConnection implements ServiceConnection { 92 93 private final CountDownLatch mLatch; 94 TestCarrierServiceConnection(CountDownLatch latch)95 TestCarrierServiceConnection(CountDownLatch latch) { 96 mLatch = latch; 97 } 98 99 @Override onServiceConnected(ComponentName name, IBinder service)100 public void onServiceConnected(ComponentName name, IBinder service) { 101 mCarrierService = ((TestImsService.LocalBinder) service).getService(); 102 mLatch.countDown(); 103 } 104 105 @Override onServiceDisconnected(ComponentName name)106 public void onServiceDisconnected(ComponentName name) { 107 mCarrierService = null; 108 } 109 } 110 111 private class TestDeviceServiceConnection implements ServiceConnection { 112 113 private final CountDownLatch mLatch; 114 TestDeviceServiceConnection(CountDownLatch latch)115 TestDeviceServiceConnection(CountDownLatch latch) { 116 mLatch = latch; 117 } 118 119 @Override onServiceConnected(ComponentName name, IBinder service)120 public void onServiceConnected(ComponentName name, IBinder service) { 121 mExternalService = ITestExternalImsService.Stub.asInterface(service); 122 mLatch.countDown(); 123 } 124 125 @Override onServiceDisconnected(ComponentName name)126 public void onServiceDisconnected(ComponentName name) { 127 mExternalService = null; 128 } 129 } 130 131 public class Connection { 132 133 private static final int CONNECTION_TYPE_IMS_SERVICE_DEVICE = 1; 134 private static final int CONNECTION_TYPE_IMS_SERVICE_CARRIER = 2; 135 private static final int CONNECTION_TYPE_DEFAULT_SMS_APP = 3; 136 137 private boolean mIsServiceOverridden = false; 138 private String mOrigMmTelServicePackage; 139 private String mOrigRcsServicePackage; 140 private String mOrigSmsPackage; 141 private int mConnectionType; 142 private int mSlotId; 143 private SparseArray<String> mFeatureTypeToPackageOverrideMap = new SparseArray<>(2); Connection(int connectionType, int slotId)144 Connection(int connectionType, int slotId) { 145 mConnectionType = connectionType; 146 mSlotId = slotId; 147 } 148 clearPackage()149 void clearPackage() throws Exception { 150 mIsServiceOverridden = true; 151 switch (mConnectionType) { 152 case CONNECTION_TYPE_IMS_SERVICE_CARRIER: { 153 boolean unbindSent = setCarrierImsService("none"); 154 if (unbindSent) waitForCarrierPackageUnbind(); 155 break; 156 } 157 case CONNECTION_TYPE_IMS_SERVICE_DEVICE: { 158 boolean unbindSent = setDeviceImsService(""); 159 if (unbindSent) waitForDevicePackageUnbind(); 160 break; 161 } 162 case CONNECTION_TYPE_DEFAULT_SMS_APP: { 163 // We don't need to clear anything for default SMS app. 164 break; 165 } 166 } 167 } 168 waitForCarrierPackageUnbind()169 void waitForCarrierPackageUnbind() { 170 TestImsService carrierService = getCarrierService(); 171 if (carrierService == null) return; 172 // First unbind the local services 173 removeLocalCarrierServiceConnection(); 174 // Then wait for AOSP to unbind if there is still an active binding. 175 boolean isBound = carrierService.isTelephonyBound(); 176 if (ImsUtils.VDBG) Log.i(TAG, "waitForCarrierPackageUnbind: isBound=" + isBound); 177 if (isBound) { 178 // Wait for telephony to unbind to local ImsService 179 carrierService.waitForLatchCountdown(TestImsService.LATCH_ON_UNBIND); 180 } 181 } 182 waitForDevicePackageUnbind()183 void waitForDevicePackageUnbind() throws Exception { 184 // Wait until the ImsService unbinds 185 ITestExternalImsService externalService = getExternalService(); 186 if (externalService == null) return; 187 // First unbind the local services 188 removeLocalExternalServiceConnection(); 189 // Then wait for AOSP to unbind if there is still an active binding. 190 boolean isBound = externalService.isTelephonyBound(); 191 if (ImsUtils.VDBG) Log.i(TAG, "waitForDevicePackageUnbind: isBound=" + isBound); 192 if (isBound) { 193 // Wait for telephony to unbind to external ImsService 194 externalService.waitForLatchCountdown(TestImsService.LATCH_ON_UNBIND); 195 } 196 } 197 overrideService(ImsFeatureConfiguration config)198 boolean overrideService(ImsFeatureConfiguration config) throws Exception { 199 mIsServiceOverridden = true; 200 switch (mConnectionType) { 201 case CONNECTION_TYPE_IMS_SERVICE_CARRIER: { 202 return bindCarrierImsService(config, PACKAGE_NAME); 203 } 204 case CONNECTION_TYPE_IMS_SERVICE_DEVICE: { 205 return bindDeviceImsService(config, EXTERNAL_PACKAGE_NAME); 206 } 207 case CONNECTION_TYPE_DEFAULT_SMS_APP: { 208 return setDefaultSmsApp(PACKAGE_NAME); 209 } 210 } 211 return false; 212 } 213 restoreOriginalPackage()214 void restoreOriginalPackage() throws Exception { 215 if (!mIsServiceOverridden) { 216 return; 217 } 218 mIsServiceOverridden = false; 219 220 if (mOrigRcsServicePackage == null) { 221 mOrigRcsServicePackage = ""; 222 } 223 224 if (mOrigMmTelServicePackage == null) { 225 mOrigMmTelServicePackage = ""; 226 } 227 228 switch (mConnectionType) { 229 case CONNECTION_TYPE_IMS_SERVICE_CARRIER: { 230 clearCarrierImsServiceOverride(); 231 break; 232 } 233 case CONNECTION_TYPE_IMS_SERVICE_DEVICE: { 234 setDeviceImsService(mOrigMmTelServicePackage, ImsFeature.FEATURE_MMTEL); 235 setDeviceImsService(mOrigRcsServicePackage, ImsFeature.FEATURE_RCS); 236 break; 237 } 238 case CONNECTION_TYPE_DEFAULT_SMS_APP: { 239 setDefaultSmsApp(mOrigSmsPackage); 240 break; 241 } 242 } 243 } 244 245 /** 246 * @return true if the configuration set here still exists in telephony or false if it was 247 * changed (due to something like a Phone process crash). 248 */ checkConfigurationExists()249 boolean checkConfigurationExists() throws Exception { 250 boolean result = true; 251 String mmTelPackage = mFeatureTypeToPackageOverrideMap.get(ImsFeature.FEATURE_MMTEL); 252 String rcsPackage = mFeatureTypeToPackageOverrideMap.get(ImsFeature.FEATURE_RCS); 253 switch (mConnectionType) { 254 case CONNECTION_TYPE_IMS_SERVICE_CARRIER: { 255 result &= isPackageTheSame(mmTelPackage, getMmTelCarrierService()); 256 result &= isPackageTheSame(rcsPackage, getRcsCarrierService()); 257 break; 258 } 259 case CONNECTION_TYPE_IMS_SERVICE_DEVICE: { 260 result &= isPackageTheSame(mmTelPackage, getMmTelDeviceService()); 261 result &= isPackageTheSame(rcsPackage, getRcsDeviceService()); 262 break; 263 } 264 case CONNECTION_TYPE_DEFAULT_SMS_APP: { 265 break; 266 } 267 } 268 return result; 269 } 270 isPackageTheSame(String pkgA, String pkgB)271 private boolean isPackageTheSame(String pkgA, String pkgB) { 272 if (TextUtils.isEmpty(pkgA) && TextUtils.isEmpty(pkgB)) { 273 return true; 274 } 275 return TextUtils.equals(pkgA, pkgB); 276 } 277 storeOriginalPackage()278 private void storeOriginalPackage() throws Exception { 279 switch (mConnectionType) { 280 case CONNECTION_TYPE_IMS_SERVICE_CARRIER: { 281 mOrigMmTelServicePackage = getMmTelCarrierService(); 282 mOrigRcsServicePackage = getRcsCarrierService(); 283 break; 284 } 285 case CONNECTION_TYPE_IMS_SERVICE_DEVICE: { 286 mOrigMmTelServicePackage = getMmTelDeviceService(); 287 mOrigRcsServicePackage = getRcsDeviceService(); 288 break; 289 } 290 case CONNECTION_TYPE_DEFAULT_SMS_APP: { 291 mOrigSmsPackage = getDefaultSmsApp(); 292 break; 293 } 294 } 295 } 296 setDeviceImsService(String packageName)297 private boolean setDeviceImsService(String packageName) throws Exception { 298 mFeatureTypeToPackageOverrideMap.put(ImsFeature.FEATURE_MMTEL, packageName); 299 mFeatureTypeToPackageOverrideMap.put(ImsFeature.FEATURE_RCS, packageName); 300 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 301 constructSetImsServiceOverrideCommand(false, packageName, new int[] { 302 ImsFeature.FEATURE_MMTEL, ImsFeature.FEATURE_RCS})); 303 if (ImsUtils.VDBG) { 304 Log.d(TAG, "setDeviceMmTelImsService result: " + result); 305 } 306 return "true".equals(result); 307 } 308 setCarrierImsService(String packageName)309 private boolean setCarrierImsService(String packageName) throws Exception { 310 mFeatureTypeToPackageOverrideMap.put(ImsFeature.FEATURE_MMTEL, packageName); 311 mFeatureTypeToPackageOverrideMap.put(ImsFeature.FEATURE_RCS, packageName); 312 String command = constructSetImsServiceOverrideCommand(true, packageName, new int[] { 313 ImsFeature.FEATURE_EMERGENCY_MMTEL, ImsFeature.FEATURE_MMTEL, 314 ImsFeature.FEATURE_RCS}); 315 String result = TelephonyUtils.executeShellCommand(mInstrumentation, command); 316 if (ImsUtils.VDBG) { 317 Log.d(TAG, "setCarrierMmTelImsService: command=[" + command + "], result: " 318 + result); 319 } 320 return "true".equals(result); 321 } 322 setDeviceImsService(String packageName, int featureType)323 private boolean setDeviceImsService(String packageName, int featureType) throws Exception { 324 mFeatureTypeToPackageOverrideMap.put(featureType, packageName); 325 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 326 constructSetImsServiceOverrideCommand(false, packageName, 327 new int[]{featureType})); 328 if (ImsUtils.VDBG) { 329 Log.d(TAG, "setDeviceMmTelImsService result: " + result); 330 } 331 return "true".equals(result); 332 } 333 setCarrierImsService(String packageName, int featureType)334 private boolean setCarrierImsService(String packageName, int featureType) throws Exception { 335 mFeatureTypeToPackageOverrideMap.put(featureType, packageName); 336 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 337 constructSetImsServiceOverrideCommand(true, packageName, 338 new int[]{featureType})); 339 if (ImsUtils.VDBG) { 340 Log.d(TAG, "setCarrierMmTelImsService result: " + result); 341 } 342 return "true".equals(result); 343 } 344 clearCarrierImsServiceOverride()345 private boolean clearCarrierImsServiceOverride() throws Exception { 346 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 347 constructClearCarrierImsServiceOverrideCommand()); 348 if (ImsUtils.VDBG) { 349 Log.d(TAG, "clearCarrierImsServiceOverride result: " + result); 350 } 351 return "true".equals(result); 352 } 353 setDefaultSmsApp(String packageName)354 private boolean setDefaultSmsApp(String packageName) throws Exception { 355 RoleManager roleManager = mInstrumentation.getContext() 356 .getSystemService(RoleManager.class); 357 Boolean result; 358 LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(1); 359 if (TextUtils.isEmpty(packageName)) { 360 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(roleManager, 361 (m) -> m.clearRoleHoldersAsUser(RoleManager.ROLE_SMS, 362 RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, 363 android.os.Process.myUserHandle(), 364 // Run on calling binder thread. 365 Runnable::run, queue::offer)); 366 } else { 367 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(roleManager, 368 (m) -> m.addRoleHolderAsUser(RoleManager.ROLE_SMS, packageName, 0, 369 android.os.Process.myUserHandle(), 370 // Run on calling binder thread. 371 Runnable::run, queue::offer)); 372 } 373 result = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); 374 if (ImsUtils.VDBG) { 375 Log.d(TAG, "setDefaultSmsApp result: " + result); 376 } 377 return result; 378 } 379 getDefaultSmsApp()380 private String getDefaultSmsApp() throws Exception { 381 RoleManager roleManager = mInstrumentation.getContext() 382 .getSystemService(RoleManager.class); 383 List<String> result = ShellIdentityUtils.invokeMethodWithShellPermissions(roleManager, 384 (m) -> m.getRoleHolders(RoleManager.ROLE_SMS)); 385 if (ImsUtils.VDBG) { 386 Log.d(TAG, "getDefaultSmsApp result: " + result); 387 } 388 if (result.isEmpty()) { 389 // No default SMS app. 390 return null; 391 } 392 // There should only be one default sms app 393 return result.get(0); 394 } 395 bindCarrierImsService(ImsFeatureConfiguration config, String packageName)396 private boolean bindCarrierImsService(ImsFeatureConfiguration config, String packageName) 397 throws Exception { 398 getCarrierService().setFeatureConfig(config); 399 boolean setCarrierImsService = setCarrierImsService(packageName); 400 Log.i("bindCarrierImsService", "setCarrierImsService = " + setCarrierImsService); 401 if (!setCarrierImsService) return false; 402 boolean getCarrierService = getCarrierService().waitForLatchCountdown( 403 TestImsService.LATCH_FEATURES_READY); 404 Log.i("bindCarrierImsService", "getCarrierService = " + getCarrierService); 405 return setCarrierImsService && getCarrierService; 406 } 407 bindDeviceImsService(ImsFeatureConfiguration config, String packageName)408 private boolean bindDeviceImsService(ImsFeatureConfiguration config, String packageName) 409 throws Exception { 410 getExternalService().setFeatureConfig(config); 411 return setDeviceImsService(packageName) && getExternalService().waitForLatchCountdown( 412 TestImsService.LATCH_FEATURES_READY); 413 } 414 getMmTelCarrierService()415 private String getMmTelCarrierService() throws Exception { 416 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 417 constructGetImsServiceCommand(true, ImsFeature.FEATURE_MMTEL)); 418 if (ImsUtils.VDBG) { 419 Log.d(TAG, "getMmTelCarrierService result: " + result); 420 } 421 return result; 422 } 423 getRcsCarrierService()424 private String getRcsCarrierService() throws Exception { 425 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 426 constructGetImsServiceCommand(true, ImsFeature.FEATURE_RCS)); 427 if (ImsUtils.VDBG) { 428 Log.d(TAG, "getRcsCarrierService result: " + result); 429 } 430 return result; 431 } 432 getMmTelDeviceService()433 private String getMmTelDeviceService() throws Exception { 434 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 435 constructGetImsServiceCommand(false, ImsFeature.FEATURE_MMTEL)); 436 if (ImsUtils.VDBG) { 437 Log.d(TAG, "getMmTelDeviceService result: " + result); 438 } 439 return result; 440 } 441 getRcsDeviceService()442 private String getRcsDeviceService() throws Exception { 443 String result = TelephonyUtils.executeShellCommand(mInstrumentation, 444 constructGetImsServiceCommand(false, ImsFeature.FEATURE_RCS)); 445 if (ImsUtils.VDBG) { 446 Log.d(TAG, "getRcsDeviceService result: " + result); 447 } 448 return result; 449 } 450 constructSetImsServiceOverrideCommand(boolean isCarrierService, String packageName, int[] featureTypes)451 private String constructSetImsServiceOverrideCommand(boolean isCarrierService, 452 String packageName, int[] featureTypes) { 453 int userId = mInstrumentation.getContext().getUserId(); 454 return COMMAND_BASE + COMMAND_SET_IMS_SERVICE + COMMAND_SLOT_IDENTIFIER + mSlotId + " " 455 + COMMAND_USER_ID_IDENTIFIER + userId + " " 456 + (isCarrierService 457 ? COMMAND_CARRIER_SERVICE_IDENTIFIER : COMMAND_DEVICE_SERVICE_IDENTIFIER) 458 + COMMAND_FEATURE_IDENTIFIER + getFeatureTypesString(featureTypes) + " " 459 + packageName; 460 } 461 constructGetImsServiceCommand(boolean isCarrierService, int featureType)462 private String constructGetImsServiceCommand(boolean isCarrierService, int featureType) { 463 return COMMAND_BASE + COMMAND_GET_IMS_SERVICE + COMMAND_SLOT_IDENTIFIER + mSlotId + " " 464 + (isCarrierService 465 ? COMMAND_CARRIER_SERVICE_IDENTIFIER : COMMAND_DEVICE_SERVICE_IDENTIFIER) 466 + COMMAND_FEATURE_IDENTIFIER + featureType; 467 } 468 constructClearCarrierImsServiceOverrideCommand()469 private String constructClearCarrierImsServiceOverrideCommand() { 470 return COMMAND_BASE + COMMAND_CLEAR_SERVICE_OVERRIDE + COMMAND_SLOT_IDENTIFIER 471 + mSlotId; 472 } 473 getFeatureTypesString(int[] featureTypes)474 private String getFeatureTypesString(int[] featureTypes) { 475 if (featureTypes.length == 0) return ""; 476 StringBuilder builder = new StringBuilder(); 477 builder.append(featureTypes[0]); 478 for (int i = 1; i < featureTypes.length; i++) { 479 builder.append(","); 480 builder.append(featureTypes[i]); 481 } 482 return builder.toString(); 483 } 484 } 485 486 private Instrumentation mInstrumentation; 487 488 private TestImsService mCarrierService; 489 private TestCarrierServiceConnection mCarrierServiceConn; 490 private ITestExternalImsService mExternalService; 491 private TestDeviceServiceConnection mExternalServiceConn; 492 493 private Connection mDeviceServiceConnection; 494 private Connection mCarrierServiceConnection; 495 private Connection mDefaultSmsAppConnection; 496 ImsServiceConnector(Instrumentation instrumentation)497 public ImsServiceConnector(Instrumentation instrumentation) { 498 mInstrumentation = instrumentation; 499 } 500 501 /** 502 * Clear all active IMS services. 503 * @param slotId SIM slot ID 504 * @throws Exception 505 */ clearAllActiveImsServices(int slotId)506 public void clearAllActiveImsServices(int slotId) throws Exception { 507 mDeviceServiceConnection = new Connection(Connection.CONNECTION_TYPE_IMS_SERVICE_DEVICE, 508 slotId); 509 mDeviceServiceConnection.storeOriginalPackage(); 510 mDeviceServiceConnection.clearPackage(); 511 512 mCarrierServiceConnection = new Connection(Connection.CONNECTION_TYPE_IMS_SERVICE_CARRIER, 513 slotId); 514 mCarrierServiceConnection.storeOriginalPackage(); 515 mCarrierServiceConnection.clearPackage(); 516 517 mDefaultSmsAppConnection = new Connection(Connection.CONNECTION_TYPE_DEFAULT_SMS_APP, 518 slotId); 519 mDefaultSmsAppConnection.storeOriginalPackage(); 520 // No need to clear SMS App, only replace when necessary. 521 } 522 523 /** 524 * Binds to the local implementation of ImsService but does not trigger ImsService bind from 525 * telephony to allow additional configuration steps. 526 * @return true if this request succeeded, false otherwise. 527 */ connectCarrierImsServiceLocally()528 public boolean connectCarrierImsServiceLocally() { 529 if (!setupLocalCarrierImsService()) { 530 Log.w(TAG, "connectCarrierImsService: couldn't set up service."); 531 return false; 532 } 533 mCarrierService.resetState(); 534 if (mIsTestTypeExecutor) { 535 mCarrierService.setExecutorTestType(mIsTestTypeExecutor); 536 // reset the mIsTestTypeExecutor value 537 mIsTestTypeExecutor = false; 538 } 539 return true; 540 } 541 542 /** 543 * Trigger the telephony framework to bind to the local ImsService implementation. 544 * @return true if this request succeeded, false otherwise. 545 */ triggerFrameworkConnectionToCarrierImsService( ImsFeatureConfiguration config)546 public boolean triggerFrameworkConnectionToCarrierImsService( 547 ImsFeatureConfiguration config) throws Exception { 548 return mCarrierServiceConnection.overrideService(config); 549 } 550 551 /** 552 * Connect the CTS process local ImsService using the given config 553 */ connectCarrierImsService(ImsFeatureConfiguration config)554 public boolean connectCarrierImsService(ImsFeatureConfiguration config) throws Exception { 555 if (!connectCarrierImsServiceLocally()) return false; 556 return triggerFrameworkConnectionToCarrierImsService(config); 557 } 558 559 /** 560 * Connect the ImsService hosted in a different test app using the given config 561 */ connectDeviceImsService(long capabilities, ImsFeatureConfiguration config)562 public boolean connectDeviceImsService(long capabilities, 563 ImsFeatureConfiguration config) throws Exception { 564 if (!setupExternalImsService()) { 565 Log.w(TAG, "connectDeviceImsService: couldn't set up service."); 566 return false; 567 } 568 mExternalService.resetState(); 569 if (capabilities != 0) { 570 mExternalService.addCapabilities(capabilities); 571 Log.d(TAG, "connectDeviceImsService: added capabilities = " + capabilities); 572 } 573 return mDeviceServiceConnection.overrideService(config); 574 } 575 connectDeviceImsService(ImsFeatureConfiguration config)576 public boolean connectDeviceImsService(ImsFeatureConfiguration config) throws Exception { 577 return connectDeviceImsService(0, config); 578 } 579 setDefaultSmsApp()580 boolean setDefaultSmsApp() throws Exception { 581 return mDefaultSmsAppConnection.overrideService(null); 582 } 583 restoreDefaultSmsApp()584 void restoreDefaultSmsApp() throws Exception { 585 mDefaultSmsAppConnection.restoreOriginalPackage(); 586 } 587 588 /** 589 * Disconnect the previously connected ImsService that used {@link #connectCarrierImsService} 590 */ disconnectCarrierImsService()591 public void disconnectCarrierImsService() throws Exception { 592 mCarrierServiceConnection.clearPackage(); 593 } 594 595 /** 596 * Disconnect the previously connected ImsService that used {@link #connectDeviceImsService} 597 */ disconnectDeviceImsService()598 public void disconnectDeviceImsService() throws Exception { 599 mDeviceServiceConnection.clearPackage(); 600 } 601 isCarrierServiceStillConfigured()602 boolean isCarrierServiceStillConfigured() throws Exception { 603 return mCarrierServiceConnection.checkConfigurationExists(); 604 } 605 setupLocalCarrierImsService()606 private boolean setupLocalCarrierImsService() { 607 if (mCarrierService != null) { 608 return true; 609 } 610 CountDownLatch latch = new CountDownLatch(1); 611 mCarrierServiceConn = new TestCarrierServiceConnection(latch); 612 mInstrumentation.getContext().bindService(new Intent(mInstrumentation.getContext(), 613 TestImsService.class), mCarrierServiceConn, Context.BIND_AUTO_CREATE); 614 try { 615 return latch.await(5000, TimeUnit.MILLISECONDS); 616 } catch (InterruptedException e) { 617 return false; 618 } 619 } 620 setupExternalImsService()621 private boolean setupExternalImsService() { 622 if (mExternalService != null) { 623 return true; 624 } 625 CountDownLatch latch = new CountDownLatch(1); 626 mExternalServiceConn = new TestDeviceServiceConnection(latch); 627 Intent deviceIntent = new Intent(); 628 deviceIntent.setComponent(new ComponentName(EXTERNAL_PACKAGE_NAME, 629 TestExternalImsService.class.getName())); 630 mInstrumentation.getContext().bindService(deviceIntent, mExternalServiceConn, 631 Context.BIND_AUTO_CREATE); 632 try { 633 return latch.await(5000, TimeUnit.MILLISECONDS); 634 } catch (InterruptedException e) { 635 return false; 636 } 637 } 638 removeLocalCarrierServiceConnection()639 void removeLocalCarrierServiceConnection() { 640 if (mCarrierServiceConn != null) { 641 mInstrumentation.getContext().unbindService(mCarrierServiceConn); 642 mCarrierServiceConn = null; 643 mCarrierService = null; 644 } 645 } 646 removeLocalExternalServiceConnection()647 void removeLocalExternalServiceConnection() { 648 if (mExternalServiceConn != null) { 649 mInstrumentation.getContext().unbindService(mExternalServiceConn); 650 mExternalServiceConn = null; 651 mExternalService = null; 652 } 653 } 654 655 /** 656 * Detect and disconnect all active services. 657 * @throws Exception 658 */ disconnectServices()659 public void disconnectServices() throws Exception { 660 // Remove local connections 661 removeLocalCarrierServiceConnection(); 662 removeLocalExternalServiceConnection(); 663 mDeviceServiceConnection.restoreOriginalPackage(); 664 mCarrierServiceConnection.restoreOriginalPackage(); 665 mDefaultSmsAppConnection.restoreOriginalPackage(); 666 667 // Remove any overrides for single registration state 668 setDeviceSingleRegistrationEnabled(null); 669 } 670 enableImsService(int slot)671 void enableImsService(int slot) throws Exception { 672 TelephonyUtils.executeShellCommand(mInstrumentation, COMMAND_BASE + COMMAND_ENABLE_IMS 673 + COMMAND_SLOT_IDENTIFIER + slot); 674 } 675 disableImsService(int slot)676 void disableImsService(int slot) throws Exception { 677 TelephonyUtils.executeShellCommand(mInstrumentation, COMMAND_BASE + COMMAND_DISABLE_IMS 678 + COMMAND_SLOT_IDENTIFIER + slot); 679 } 680 setDeviceSingleRegistrationEnabled(Boolean enabled)681 void setDeviceSingleRegistrationEnabled(Boolean enabled) throws Exception { 682 TelephonyUtils.executeShellCommand(mInstrumentation, COMMAND_BASE 683 + COMMAND_SET_DEVICE_SINGLE_REGISTRATION_ENABLED 684 // if "null" is sent, it will remove override 685 + (enabled != null ? enabled : "null")); 686 } 687 getDeviceSingleRegistrationEnabled()688 boolean getDeviceSingleRegistrationEnabled() throws Exception { 689 return Boolean.parseBoolean(TelephonyUtils.executeShellCommand(mInstrumentation, 690 COMMAND_BASE + COMMAND_GET_DEVICE_SINGLE_REGISTRATION_ENABLED)); 691 } 692 getCarrierSingleRegistrationEnabled()693 boolean getCarrierSingleRegistrationEnabled() throws Exception { 694 return Boolean.parseBoolean(TelephonyUtils.executeShellCommand(mInstrumentation, 695 COMMAND_BASE + COMMAND_GET_CARRIER_SINGLE_REGISTRATION_ENABLED)); 696 } 697 getDeviceUceEnabled()698 boolean getDeviceUceEnabled() throws Exception { 699 return Boolean.parseBoolean(TelephonyUtils.executeShellCommand(mInstrumentation, 700 COMMAND_BASE + COMMAND_GET_UCE_ENABLED)); 701 } 702 setDeviceUceEnabled(boolean isEnabled)703 void setDeviceUceEnabled(boolean isEnabled) throws Exception { 704 TelephonyUtils.executeShellCommand(mInstrumentation, 705 COMMAND_BASE + COMMAND_SET_UCE_ENABLED + isEnabled); 706 } 707 removeEabContacts(int slotId, String phoneNum)708 void removeEabContacts(int slotId, String phoneNum) throws Exception { 709 StringBuilder cmdBuilder = new StringBuilder(); 710 cmdBuilder.append(COMMAND_BASE).append(COMMAND_REMOVE_EAB_CONTACT) 711 .append(COMMAND_SLOT_IDENTIFIER).append(slotId).append(" ").append(phoneNum); 712 TelephonyUtils.executeShellCommand(mInstrumentation, cmdBuilder.toString()); 713 } 714 getCarrierService()715 public TestImsService getCarrierService() { 716 return mCarrierService; 717 } 718 getExternalService()719 public ITestExternalImsService getExternalService() { 720 return mExternalService; 721 } 722 setSingleRegistrationTestModeEnabled(boolean enabled)723 void setSingleRegistrationTestModeEnabled(boolean enabled) throws Exception { 724 TelephonyUtils.executeShellCommand(mInstrumentation, COMMAND_BASE 725 + COMMAND_SET_TEST_MODE_ENABLED + (enabled ? "true" : "false")); 726 } 727 removeUceRequestDisallowedStatus(int slotId)728 void removeUceRequestDisallowedStatus(int slotId) throws Exception { 729 StringBuilder cmdBuilder = new StringBuilder(); 730 cmdBuilder.append(COMMAND_BASE).append(COMMAND_REMOVE_UCE_REQUEST_DISALLOWED_STATUS) 731 .append(COMMAND_SLOT_IDENTIFIER).append(slotId); 732 TelephonyUtils.executeShellCommand(mInstrumentation, cmdBuilder.toString()); 733 } 734 setCapabilitiesRequestTimeout(int slotId, long timeoutAfterMs)735 void setCapabilitiesRequestTimeout(int slotId, long timeoutAfterMs) throws Exception { 736 StringBuilder cmdBuilder = new StringBuilder(); 737 cmdBuilder.append(COMMAND_BASE).append(COMMAND_SET_CAPABILITY_REQUEST_TIMEOUT) 738 .append(COMMAND_SLOT_IDENTIFIER).append(slotId).append(" ").append(timeoutAfterMs); 739 TelephonyUtils.executeShellCommand(mInstrumentation, cmdBuilder.toString()); 740 } 741 setDeviceToDeviceCommunicationEnabled(boolean enabled)742 void setDeviceToDeviceCommunicationEnabled(boolean enabled) throws Exception { 743 TelephonyUtils.executeShellCommand(mInstrumentation, COMMAND_BASE 744 + COMMAND_SET_D2D_ENABLED + (enabled ? "true" : "default")); 745 } 746 } 747