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