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