1 /* 2 * Copyright (C) 2009 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.cts; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertNotNull; 24 import static org.junit.Assert.assertNull; 25 import static org.junit.Assert.assertTrue; 26 import static org.junit.Assert.fail; 27 28 import android.Manifest; 29 import android.Manifest.permission; 30 import android.app.UiAutomation; 31 import android.bluetooth.BluetoothAdapter; 32 import android.content.ComponentName; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.content.ServiceConnection; 36 import android.content.pm.PackageManager; 37 import android.net.ConnectivityManager; 38 import android.net.wifi.WifiInfo; 39 import android.net.wifi.WifiManager; 40 import android.os.AsyncTask; 41 import android.os.Build; 42 import android.os.IBinder; 43 import android.os.Looper; 44 import android.os.RemoteException; 45 import android.telecom.PhoneAccount; 46 import android.telecom.PhoneAccountHandle; 47 import android.telecom.TelecomManager; 48 import android.telephony.AccessNetworkConstants; 49 import android.telephony.AvailableNetworkInfo; 50 import android.telephony.CellLocation; 51 import android.telephony.NetworkRegistrationInfo; 52 import android.telephony.PhoneStateListener; 53 import android.telephony.ServiceState; 54 import android.telephony.SubscriptionInfo; 55 import android.telephony.SubscriptionManager; 56 import android.telephony.TelephonyManager; 57 import android.telephony.UiccCardInfo; 58 import android.telephony.UiccSlotInfo; 59 import android.telephony.cts.locationaccessingapp.CtsLocationAccessService; 60 import android.telephony.cts.locationaccessingapp.ICtsLocationAccessControl; 61 import android.telephony.emergency.EmergencyNumber; 62 import android.text.TextUtils; 63 import android.util.Log; 64 import android.util.Pair; 65 66 import androidx.test.InstrumentationRegistry; 67 68 import com.android.compatibility.common.util.ShellIdentityUtils; 69 import com.android.compatibility.common.util.TestThread; 70 71 import org.junit.After; 72 import org.junit.Before; 73 import org.junit.Test; 74 75 import java.util.ArrayList; 76 import java.util.Arrays; 77 import java.util.HashSet; 78 import java.util.List; 79 import java.util.Locale; 80 import java.util.Map; 81 import java.util.Objects; 82 import java.util.Set; 83 import java.util.concurrent.LinkedBlockingQueue; 84 import java.util.concurrent.TimeUnit; 85 import java.util.function.Consumer; 86 import java.util.regex.Pattern; 87 import java.util.stream.Collectors; 88 89 /** 90 * Build, install and run the tests by running the commands below: 91 * make cts -j64 92 * cts-tradefed run cts -m CtsTelephonyTestCases --test android.telephony.cts.TelephonyManagerTest 93 */ 94 public class TelephonyManagerTest { 95 private TelephonyManager mTelephonyManager; 96 private SubscriptionManager mSubscriptionManager; 97 private PackageManager mPackageManager; 98 private boolean mOnCellLocationChangedCalled = false; 99 private boolean mServiceStateChangedCalled = false; 100 private boolean mRadioRebootTriggered = false; 101 private boolean mHasRadioPowerOff = false; 102 private ServiceState mServiceState; 103 private final Object mLock = new Object(); 104 private static final int TOLERANCE = 1000; 105 private PhoneStateListener mListener; 106 private static ConnectivityManager mCm; 107 private static final String TAG = "TelephonyManagerTest"; 108 private static final List<Integer> ROAMING_TYPES = Arrays.asList( 109 ServiceState.ROAMING_TYPE_DOMESTIC, 110 ServiceState.ROAMING_TYPE_INTERNATIONAL, 111 ServiceState.ROAMING_TYPE_NOT_ROAMING, 112 ServiceState.ROAMING_TYPE_UNKNOWN); 113 private static final List<Integer> NETWORK_TYPES = Arrays.asList( 114 TelephonyManager.NETWORK_TYPE_UNKNOWN, 115 TelephonyManager.NETWORK_TYPE_GPRS, 116 TelephonyManager.NETWORK_TYPE_EDGE, 117 TelephonyManager.NETWORK_TYPE_UMTS, 118 TelephonyManager.NETWORK_TYPE_CDMA, 119 TelephonyManager.NETWORK_TYPE_EVDO_0, 120 TelephonyManager.NETWORK_TYPE_EVDO_A, 121 TelephonyManager.NETWORK_TYPE_1xRTT, 122 TelephonyManager.NETWORK_TYPE_HSDPA, 123 TelephonyManager.NETWORK_TYPE_HSUPA, 124 TelephonyManager.NETWORK_TYPE_HSPA, 125 TelephonyManager.NETWORK_TYPE_IDEN, 126 TelephonyManager.NETWORK_TYPE_EVDO_B, 127 TelephonyManager.NETWORK_TYPE_LTE, 128 TelephonyManager.NETWORK_TYPE_EHRPD, 129 TelephonyManager.NETWORK_TYPE_HSPAP, 130 TelephonyManager.NETWORK_TYPE_GSM, 131 TelephonyManager.NETWORK_TYPE_TD_SCDMA, 132 TelephonyManager.NETWORK_TYPE_IWLAN, 133 TelephonyManager.NETWORK_TYPE_LTE_CA, 134 TelephonyManager.NETWORK_TYPE_NR); 135 136 private static final int EMERGENCY_NUMBER_SOURCE_RIL_ECCLIST = 0; 137 private static final Set<Integer> EMERGENCY_NUMBER_SOURCE_SET; 138 static { 139 EMERGENCY_NUMBER_SOURCE_SET = new HashSet<Integer>(); 140 EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING); 141 EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM); 142 EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE); 143 EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG); 144 EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT); 145 } 146 147 private static final Set<Integer> EMERGENCY_SERVICE_CATEGORY_SET; 148 static { 149 EMERGENCY_SERVICE_CATEGORY_SET = new HashSet<Integer>(); 150 EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE); 151 EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE); 152 EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE); 153 EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD); 154 EMERGENCY_SERVICE_CATEGORY_SET.add( 155 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE); 156 EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC); 157 EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC); 158 } 159 160 @Before setUp()161 public void setUp() throws Exception { 162 mTelephonyManager = 163 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); 164 mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); 165 mSubscriptionManager = (SubscriptionManager) getContext() 166 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 167 mPackageManager = getContext().getPackageManager(); 168 } 169 170 @After tearDown()171 public void tearDown() throws Exception { 172 if (mListener != null) { 173 // unregister the listener 174 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE); 175 } 176 } 177 grantLocationPermissions()178 public static void grantLocationPermissions() { 179 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 180 String packageName = getContext().getPackageName(); 181 uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_COARSE_LOCATION); 182 uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_FINE_LOCATION); 183 uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_BACKGROUND_LOCATION); 184 } 185 186 @Test testListen()187 public void testListen() throws Throwable { 188 if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) { 189 Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE"); 190 return; 191 } 192 193 if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 194 // TODO: temp workaround, need to adjust test to for CDMA 195 return; 196 } 197 198 grantLocationPermissions(); 199 200 TestThread t = new TestThread(new Runnable() { 201 public void run() { 202 Looper.prepare(); 203 mListener = new PhoneStateListener() { 204 @Override 205 public void onCellLocationChanged(CellLocation location) { 206 if(!mOnCellLocationChangedCalled) { 207 synchronized (mLock) { 208 mOnCellLocationChangedCalled = true; 209 mLock.notify(); 210 } 211 } 212 } 213 }; 214 215 synchronized (mLock) { 216 mLock.notify(); // mListener is ready 217 } 218 219 Looper.loop(); 220 } 221 }); 222 223 synchronized (mLock) { 224 t.start(); 225 mLock.wait(TOLERANCE); // wait for mListener 226 } 227 228 // Test register 229 synchronized (mLock) { 230 // .listen generates an onCellLocationChanged event 231 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION); 232 mLock.wait(TOLERANCE); 233 234 assertTrue("Test register, mOnCellLocationChangedCalled should be true.", 235 mOnCellLocationChangedCalled); 236 } 237 238 synchronized (mLock) { 239 mOnCellLocationChangedCalled = false; 240 CellLocation.requestLocationUpdate(); 241 mLock.wait(TOLERANCE); 242 243 assertTrue("Test register, mOnCellLocationChangedCalled should be true.", 244 mOnCellLocationChangedCalled); 245 } 246 247 // unregister the listener 248 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE); 249 Thread.sleep(TOLERANCE); 250 251 // Test unregister 252 synchronized (mLock) { 253 mOnCellLocationChangedCalled = false; 254 // unregister again, to make sure doing so does not call the listener 255 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE); 256 CellLocation.requestLocationUpdate(); 257 mLock.wait(TOLERANCE); 258 259 assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.", 260 mOnCellLocationChangedCalled); 261 } 262 } 263 264 /** 265 * The getter methods here are all related to the information about the telephony. 266 * These getters are related to concrete location, phone, service provider company, so 267 * it's no need to get details of these information, just make sure they are in right 268 * condition(>0 or not null). 269 */ 270 @Test testTelephonyManager()271 public void testTelephonyManager() { 272 assertTrue(mTelephonyManager.getNetworkType() >= TelephonyManager.NETWORK_TYPE_UNKNOWN); 273 assertTrue(mTelephonyManager.getPhoneType() >= TelephonyManager.PHONE_TYPE_NONE); 274 assertTrue(mTelephonyManager.getSimState() >= TelephonyManager.SIM_STATE_UNKNOWN); 275 assertTrue(mTelephonyManager.getDataActivity() >= TelephonyManager.DATA_ACTIVITY_NONE); 276 assertTrue(mTelephonyManager.getDataState() >= TelephonyManager.DATA_DISCONNECTED); 277 assertTrue(mTelephonyManager.getCallState() >= TelephonyManager.CALL_STATE_IDLE); 278 279 for (int i = 0; i < mTelephonyManager.getPhoneCount(); ++i) { 280 assertTrue(mTelephonyManager.getSimState(i) >= TelephonyManager.SIM_STATE_UNKNOWN); 281 } 282 283 // Make sure devices without MMS service won't fail on this 284 if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE) { 285 assertFalse(mTelephonyManager.getMmsUserAgent().isEmpty()); 286 assertFalse(mTelephonyManager.getMmsUAProfUrl().isEmpty()); 287 } 288 289 // The following methods may return any value depending on the state of the device. Simply 290 // call them to make sure they do not throw any exceptions. 291 mTelephonyManager.getVoiceMailNumber(); 292 mTelephonyManager.getSimOperatorName(); 293 mTelephonyManager.getNetworkCountryIso(); 294 mTelephonyManager.getCellLocation(); 295 mTelephonyManager.getSimCarrierId(); 296 mTelephonyManager.getSimCarrierIdName(); 297 mTelephonyManager.getSimSpecificCarrierId(); 298 mTelephonyManager.getSimSpecificCarrierIdName(); 299 mTelephonyManager.getCarrierIdFromSimMccMnc(); 300 mTelephonyManager.isDataRoamingEnabled(); 301 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 302 (tm) -> tm.getSimSerialNumber()); 303 mTelephonyManager.getSimOperator(); 304 mTelephonyManager.getSignalStrength(); 305 mTelephonyManager.getNetworkOperatorName(); 306 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 307 (tm) -> tm.getSubscriberId()); 308 mTelephonyManager.getLine1Number(); 309 mTelephonyManager.getNetworkOperator(); 310 mTelephonyManager.getSimCountryIso(); 311 mTelephonyManager.getVoiceMailAlphaTag(); 312 mTelephonyManager.isNetworkRoaming(); 313 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 314 (tm) -> tm.getDeviceId()); 315 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 316 (tm) -> tm.getDeviceId(mTelephonyManager.getSlotIndex())); 317 mTelephonyManager.getDeviceSoftwareVersion(); 318 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 319 (tm) -> tm.getImei()); 320 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 321 (tm) -> tm.getImei(mTelephonyManager.getSlotIndex())); 322 mTelephonyManager.getPhoneCount(); 323 mTelephonyManager.getDataEnabled(); 324 mTelephonyManager.getNetworkSpecifier(); 325 mTelephonyManager.getNai(); 326 TelecomManager telecomManager = (TelecomManager) getContext() 327 .getSystemService(Context.TELECOM_SERVICE); 328 PhoneAccountHandle defaultAccount = telecomManager 329 .getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 330 mTelephonyManager.getVoicemailRingtoneUri(defaultAccount); 331 mTelephonyManager.isVoicemailVibrationEnabled(defaultAccount); 332 mTelephonyManager.getCarrierConfig(); 333 } 334 335 @Test testCellLocationFinePermission()336 public void testCellLocationFinePermission() { 337 withRevokedPermission(() -> { 338 try { 339 CellLocation cellLocation = (CellLocation) performLocationAccessCommand( 340 CtsLocationAccessService.COMMAND_GET_CELL_LOCATION); 341 assertTrue(cellLocation == null || cellLocation.isEmpty()); 342 } catch (SecurityException e) { 343 // expected 344 } 345 346 try { 347 List cis = (List) performLocationAccessCommand( 348 CtsLocationAccessService.COMMAND_GET_CELL_INFO); 349 assertTrue(cis == null || cis.isEmpty()); 350 } catch (SecurityException e) { 351 // expected 352 } 353 }, Manifest.permission.ACCESS_FINE_LOCATION); 354 } 355 356 @Test testServiceStateLocationSanitization()357 public void testServiceStateLocationSanitization() { 358 withRevokedPermission(() -> { 359 ServiceState ss = (ServiceState) performLocationAccessCommand( 360 CtsLocationAccessService.COMMAND_GET_SERVICE_STATE); 361 assertServiceStateSanitization(ss, true); 362 363 withRevokedPermission(() -> { 364 ServiceState ss1 = (ServiceState) performLocationAccessCommand( 365 CtsLocationAccessService.COMMAND_GET_SERVICE_STATE); 366 assertServiceStateSanitization(ss1, false); 367 }, 368 Manifest.permission.ACCESS_COARSE_LOCATION); 369 }, 370 Manifest.permission.ACCESS_FINE_LOCATION); 371 } 372 373 @Test testServiceStateListeningWithoutPermissions()374 public void testServiceStateListeningWithoutPermissions() { 375 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) return; 376 377 withRevokedPermission(() -> { 378 ServiceState ss = (ServiceState) performLocationAccessCommand( 379 CtsLocationAccessService.COMMAND_GET_SERVICE_STATE_FROM_LISTENER); 380 assertServiceStateSanitization(ss, true); 381 382 withRevokedPermission(() -> { 383 ServiceState ss1 = (ServiceState) performLocationAccessCommand( 384 CtsLocationAccessService 385 .COMMAND_GET_SERVICE_STATE_FROM_LISTENER); 386 assertServiceStateSanitization(ss1, false); 387 }, 388 Manifest.permission.ACCESS_COARSE_LOCATION); 389 }, 390 Manifest.permission.ACCESS_FINE_LOCATION); 391 } 392 393 @Test testRegistryPermissionsForCellLocation()394 public void testRegistryPermissionsForCellLocation() { 395 withRevokedPermission(() -> { 396 CellLocation cellLocation = (CellLocation) performLocationAccessCommand( 397 CtsLocationAccessService.COMMAND_LISTEN_CELL_LOCATION); 398 assertNull(cellLocation); 399 }, 400 Manifest.permission.ACCESS_FINE_LOCATION); 401 } 402 403 @Test testRegistryPermissionsForCellInfo()404 public void testRegistryPermissionsForCellInfo() { 405 withRevokedPermission(() -> { 406 CellLocation cellLocation = (CellLocation) performLocationAccessCommand( 407 CtsLocationAccessService.COMMAND_LISTEN_CELL_INFO); 408 assertNull(cellLocation); 409 }, 410 Manifest.permission.ACCESS_FINE_LOCATION); 411 } 412 getLocationAccessAppControl()413 private ICtsLocationAccessControl getLocationAccessAppControl() { 414 Intent bindIntent = new Intent(CtsLocationAccessService.CONTROL_ACTION); 415 bindIntent.setComponent(new ComponentName(CtsLocationAccessService.class.getPackageName$(), 416 CtsLocationAccessService.class.getName())); 417 418 LinkedBlockingQueue<ICtsLocationAccessControl> pipe = 419 new LinkedBlockingQueue<>(); 420 getContext().bindService(bindIntent, new ServiceConnection() { 421 @Override 422 public void onServiceConnected(ComponentName name, IBinder service) { 423 pipe.offer(ICtsLocationAccessControl.Stub.asInterface(service)); 424 } 425 426 @Override 427 public void onServiceDisconnected(ComponentName name) { 428 429 } 430 }, Context.BIND_AUTO_CREATE); 431 432 try { 433 return pipe.poll(TOLERANCE, TimeUnit.MILLISECONDS); 434 } catch (InterruptedException e) { 435 fail("interrupted"); 436 } 437 fail("Unable to connect to location access test app"); 438 return null; 439 } 440 performLocationAccessCommand(String command)441 private Object performLocationAccessCommand(String command) { 442 ICtsLocationAccessControl control = getLocationAccessAppControl(); 443 try { 444 List ret = control.performCommand(command); 445 if (!ret.isEmpty()) return ret.get(0); 446 } catch (RemoteException e) { 447 fail("Remote exception"); 448 } 449 return null; 450 } 451 withRevokedPermission(Runnable r, String permission)452 private void withRevokedPermission(Runnable r, String permission) { 453 InstrumentationRegistry.getInstrumentation() 454 .getUiAutomation().revokeRuntimePermission( 455 CtsLocationAccessService.class.getPackageName$(), permission); 456 try { 457 r.run(); 458 } finally { 459 InstrumentationRegistry.getInstrumentation() 460 .getUiAutomation().grantRuntimePermission( 461 CtsLocationAccessService.class.getPackageName$(), permission); 462 } 463 } 464 assertServiceStateSanitization(ServiceState state, boolean sanitizedForFineOnly)465 private void assertServiceStateSanitization(ServiceState state, boolean sanitizedForFineOnly) { 466 if (state == null) return; 467 468 if (state.getNetworkRegistrationInfoList() != null) { 469 for (NetworkRegistrationInfo nrs : state.getNetworkRegistrationInfoList()) { 470 assertNull(nrs.getCellIdentity()); 471 } 472 } 473 474 if (sanitizedForFineOnly) return; 475 476 assertTrue(TextUtils.isEmpty(state.getDataOperatorAlphaLong())); 477 assertTrue(TextUtils.isEmpty(state.getDataOperatorAlphaShort())); 478 assertTrue(TextUtils.isEmpty(state.getDataOperatorNumeric())); 479 assertTrue(TextUtils.isEmpty(state.getVoiceOperatorAlphaLong())); 480 assertTrue(TextUtils.isEmpty(state.getVoiceOperatorAlphaShort())); 481 assertTrue(TextUtils.isEmpty(state.getVoiceOperatorNumeric())); 482 } 483 484 @Test testGetRadioHalVersion()485 public void testGetRadioHalVersion() { 486 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 487 Log.d(TAG,"skipping test on device without FEATURE_TELEPHONY present"); 488 return; 489 } 490 491 Pair<Integer, Integer> version = mTelephonyManager.getRadioHalVersion(); 492 493 // The version must be valid, and the versions start with 1.0 494 assertFalse("Invalid Radio HAL Version: " + version, 495 version.first < 1 || version.second < 0); 496 } 497 498 @Test testCreateForPhoneAccountHandle()499 public void testCreateForPhoneAccountHandle() { 500 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 501 Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY"); 502 return; 503 } 504 TelecomManager telecomManager = getContext().getSystemService(TelecomManager.class); 505 PhoneAccountHandle handle = 506 telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); 507 TelephonyManager telephonyManager = mTelephonyManager.createForPhoneAccountHandle(handle); 508 String globalSubscriberId = ShellIdentityUtils.invokeMethodWithShellPermissions( 509 mTelephonyManager, (tm) -> tm.getSubscriberId()); 510 String localSubscriberId = ShellIdentityUtils.invokeMethodWithShellPermissions( 511 telephonyManager, (tm) -> tm.getSubscriberId()); 512 assertEquals(globalSubscriberId, localSubscriberId); 513 } 514 515 @Test testCreateForPhoneAccountHandle_InvalidHandle()516 public void testCreateForPhoneAccountHandle_InvalidHandle(){ 517 PhoneAccountHandle handle = 518 new PhoneAccountHandle(new ComponentName("com.example.foo", "bar"), "baz"); 519 assertNull(mTelephonyManager.createForPhoneAccountHandle(handle)); 520 } 521 522 /** 523 * Tests that the phone count returned is valid. 524 */ 525 @Test testGetPhoneCount()526 public void testGetPhoneCount() { 527 int phoneCount = mTelephonyManager.getPhoneCount(); 528 int phoneType = mTelephonyManager.getPhoneType(); 529 switch (phoneType) { 530 case TelephonyManager.PHONE_TYPE_GSM: 531 case TelephonyManager.PHONE_TYPE_CDMA: 532 assertTrue("Phone count should be > 0", phoneCount > 0); 533 break; 534 case TelephonyManager.PHONE_TYPE_NONE: 535 assertTrue("Phone count should be 0", phoneCount == 0 || phoneCount == 1); 536 break; 537 default: 538 throw new IllegalArgumentException("Did you add a new phone type? " + phoneType); 539 } 540 } 541 542 /** 543 * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address 544 * if only a WiFi device. At least one of them must be valid. 545 */ 546 @Test testGetDeviceId()547 public void testGetDeviceId() { 548 String deviceId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 549 (tm) -> tm.getDeviceId()); 550 verifyDeviceId(deviceId); 551 } 552 553 /** 554 * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address 555 * if only a WiFi device. At least one of them must be valid. 556 */ 557 @Test testGetDeviceIdForSlot()558 public void testGetDeviceIdForSlot() { 559 String deviceId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 560 (tm) -> tm.getDeviceId(mTelephonyManager.getSlotIndex())); 561 verifyDeviceId(deviceId); 562 // Also verify that no exception is thrown for any slot index (including invalid ones) 563 for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) { 564 // The compiler error 'local variables referenced from a lambda expression must be final 565 // or effectively final' is reported when using i, so assign it to a final variable. 566 final int currI = i; 567 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 568 (tm) -> tm.getDeviceId(currI)); 569 } 570 } 571 verifyDeviceId(String deviceId)572 private void verifyDeviceId(String deviceId) { 573 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 574 // Either IMEI or MEID need to be valid. 575 try { 576 assertImei(deviceId); 577 } catch (AssertionError e) { 578 assertMeidEsn(deviceId); 579 } 580 } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { 581 assertSerialNumber(); 582 assertMacAddress(getWifiMacAddress()); 583 } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) { 584 assertSerialNumber(); 585 assertMacAddress(getBluetoothMacAddress()); 586 } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) { 587 assertTrue(mCm.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET) != null); 588 } 589 } 590 assertImei(String id)591 private static void assertImei(String id) { 592 assertFalse("Imei should not be empty or null", TextUtils.isEmpty(id)); 593 // IMEI may include the check digit 594 String imeiPattern = "[0-9]{14,15}"; 595 String invalidPattern = "[0]{14,15}"; 596 assertTrue("IMEI " + id + " does not match pattern " + imeiPattern, 597 Pattern.matches(imeiPattern, id)); 598 assertFalse("IMEI " + id + " must not be a zero sequence" + invalidPattern, 599 Pattern.matches(invalidPattern, id)); 600 if (id.length() == 15) { 601 // if the ID is 15 digits, the 15th must be a check digit. 602 assertImeiCheckDigit(id); 603 } 604 } 605 assertImeiCheckDigit(String deviceId)606 private static void assertImeiCheckDigit(String deviceId) { 607 int expectedCheckDigit = getLuhnCheckDigit(deviceId.substring(0, 14)); 608 int actualCheckDigit = Character.digit(deviceId.charAt(14), 10); 609 assertEquals("Incorrect check digit for " + deviceId, expectedCheckDigit, actualCheckDigit); 610 } 611 612 /** 613 * Use decimal value (0-9) to index into array to get sum of its digits 614 * needed by Lunh check. 615 * 616 * Example: DOUBLE_DIGIT_SUM[6] = 3 because 6 * 2 = 12 => 1 + 2 = 3 617 */ 618 private static final int[] DOUBLE_DIGIT_SUM = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9}; 619 620 /** 621 * Calculate the check digit by starting from the right, doubling every 622 * each digit, summing all the digits including the doubled ones, and 623 * finding a number to make the sum divisible by 10. 624 * 625 * @param deviceId not including the check digit 626 * @return the check digit 627 */ getLuhnCheckDigit(String deviceId)628 private static int getLuhnCheckDigit(String deviceId) { 629 int sum = 0; 630 int dontDoubleModulus = deviceId.length() % 2; 631 for (int i = deviceId.length() - 1; i >= 0; --i) { 632 int digit = Character.digit(deviceId.charAt(i), 10); 633 if (i % 2 == dontDoubleModulus) { 634 sum += digit; 635 } else { 636 sum += DOUBLE_DIGIT_SUM[digit]; 637 } 638 } 639 sum %= 10; 640 return sum == 0 ? 0 : 10 - sum; 641 } 642 assertMeidEsn(String id)643 private static void assertMeidEsn(String id) { 644 // CDMA device IDs may either be a 14-hex-digit MEID or an 645 // 8-hex-digit ESN. If it's an ESN, it may not be a 646 // pseudo-ESN. 647 assertFalse("Meid ESN should not be empty or null", TextUtils.isEmpty(id)); 648 if (id.length() == 14) { 649 assertMeidFormat(id); 650 } else if (id.length() == 8) { 651 assertHexadecimalEsnFormat(id); 652 } else { 653 fail("device id on CDMA must be 14-digit hex MEID or 8-digit hex ESN."); 654 } 655 } 656 assertHexadecimalEsnFormat(String deviceId)657 private static void assertHexadecimalEsnFormat(String deviceId) { 658 String esnPattern = "[0-9a-fA-F]{8}"; 659 String invalidPattern = "[0]{8}"; 660 assertTrue("ESN hex device id " + deviceId + " does not match pattern " + esnPattern, 661 Pattern.matches(esnPattern, deviceId)); 662 assertFalse("ESN hex device id " + deviceId + " must not be a pseudo-ESN", 663 "80".equals(deviceId.substring(0, 2))); 664 assertFalse("ESN hex device id " + deviceId + "must not be a zero sequence", 665 Pattern.matches(invalidPattern, deviceId)); 666 } 667 assertMeidFormat(String deviceId)668 private static void assertMeidFormat(String deviceId) { 669 // MEID must NOT include the check digit. 670 String meidPattern = "[0-9a-fA-F]{14}"; 671 String invalidPattern = "[0]{14}"; 672 assertTrue("MEID device id " + deviceId + " does not match pattern " 673 + meidPattern, Pattern.matches(meidPattern, deviceId)); 674 assertFalse("MEID device id " + deviceId + "must not be a zero sequence", 675 Pattern.matches(invalidPattern, deviceId)); 676 } 677 assertSerialNumber()678 private void assertSerialNumber() { 679 String serial = ShellIdentityUtils.invokeStaticMethodWithShellPermissions( 680 Build::getSerial); 681 assertNotNull("Non-telephony devices must have a Build.getSerial() number.", 682 serial); 683 assertTrue("Hardware id must be no longer than 20 characters.", 684 serial.length() <= 20); 685 assertTrue("Hardware id must be alphanumeric.", 686 Pattern.matches("[0-9A-Za-z]+", serial)); 687 } 688 assertMacAddress(String macAddress)689 private void assertMacAddress(String macAddress) { 690 String macPattern = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}"; 691 assertTrue("MAC Address " + macAddress + " does not match pattern " + macPattern, 692 Pattern.matches(macPattern, macAddress)); 693 } 694 695 /** @return mac address which requires the WiFi system to be enabled */ getWifiMacAddress()696 private String getWifiMacAddress() { 697 WifiManager wifiManager = (WifiManager) getContext() 698 .getSystemService(Context.WIFI_SERVICE); 699 700 boolean enabled = wifiManager.isWifiEnabled(); 701 702 try { 703 if (!enabled) { 704 wifiManager.setWifiEnabled(true); 705 } 706 707 WifiInfo wifiInfo = wifiManager.getConnectionInfo(); 708 return wifiInfo.getMacAddress(); 709 710 } finally { 711 if (!enabled) { 712 wifiManager.setWifiEnabled(false); 713 } 714 } 715 } 716 getBluetoothMacAddress()717 private String getBluetoothMacAddress() { 718 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 719 if (adapter == null) { 720 return ""; 721 } 722 723 return adapter.getAddress(); 724 } 725 726 private static final String ISO_COUNTRY_CODE_PATTERN = "[a-z]{2}"; 727 728 @Test testGetNetworkCountryIso()729 public void testGetNetworkCountryIso() { 730 String countryCode = mTelephonyManager.getNetworkCountryIso(); 731 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 732 assertTrue("Country code '" + countryCode + "' did not match " 733 + ISO_COUNTRY_CODE_PATTERN, 734 Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode)); 735 } else { 736 // Non-telephony may still have the property defined if it has a SIM. 737 } 738 } 739 740 @Test testGetSimCountryIso()741 public void testGetSimCountryIso() { 742 String countryCode = mTelephonyManager.getSimCountryIso(); 743 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 744 assertTrue("Country code '" + countryCode + "' did not match " 745 + ISO_COUNTRY_CODE_PATTERN, 746 Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode)); 747 } else { 748 // Non-telephony may still have the property defined if it has a SIM. 749 } 750 } 751 752 @Test testGetServiceState()753 public void testGetServiceState() throws InterruptedException { 754 if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) { 755 Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE"); 756 return; 757 } 758 759 TestThread t = new TestThread(new Runnable() { 760 public void run() { 761 Looper.prepare(); 762 763 mListener = new PhoneStateListener() { 764 @Override 765 public void onServiceStateChanged(ServiceState serviceState) { 766 synchronized (mLock) { 767 mServiceState = serviceState; 768 mLock.notify(); 769 } 770 } 771 }; 772 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE); 773 Looper.loop(); 774 } 775 }); 776 777 synchronized (mLock) { 778 t.start(); 779 mLock.wait(TOLERANCE); 780 } 781 782 assertEquals(mServiceState, mTelephonyManager.getServiceState()); 783 } 784 785 @Test testGetSimLocale()786 public void testGetSimLocale() throws InterruptedException { 787 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 788 Log.d(TAG,"skipping test that requires Telephony"); 789 return; 790 } 791 if (SubscriptionManager.getDefaultSubscriptionId() 792 == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 793 fail("Expected SIM inserted"); 794 } 795 Locale locale = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 796 (tm) -> tm.getSimLocale()); 797 Log.d(TAG, "testGetSimLocale: " + locale); 798 assertNotNull(locale); 799 } 800 801 /** 802 * Tests that a GSM device properly reports either the correct TAC (type allocation code) or 803 * null. 804 * The TAC should match the first 8 digits of the IMEI. 805 */ 806 @Test testGetTac()807 public void testGetTac() { 808 String tac = mTelephonyManager.getTypeAllocationCode(); 809 String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 810 (tm) -> tm.getImei()); 811 812 if (tac == null || imei == null) { 813 return; 814 } 815 816 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 817 if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 818 assertEquals(imei.substring(0, 8), tac); 819 } 820 } 821 } 822 823 /** 824 * Tests that a CDMA device properly reports either the correct MC (manufacturer code) or null. 825 * The MC should match the first 8 digits of the MEID. 826 */ 827 @Test testGetMc()828 public void testGetMc() { 829 String mc = mTelephonyManager.getManufacturerCode(); 830 String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 831 (tm) -> tm.getMeid()); 832 833 if (mc == null || meid == null) { 834 return; 835 } 836 837 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 838 if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 839 assertEquals(meid.substring(0, 8), mc); 840 } 841 } 842 } 843 844 /** 845 * Tests that the device properly reports either a valid IMEI or null. 846 */ 847 @Test testGetImei()848 public void testGetImei() { 849 String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 850 (tm) -> tm.getImei()); 851 852 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 853 if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 854 assertImei(imei); 855 } 856 } 857 } 858 859 /** 860 * Tests that the device properly reports either a valid IMEI or null. 861 */ 862 @Test testGetImeiForSlot()863 public void testGetImeiForSlot() { 864 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 865 return; 866 } 867 868 for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) { 869 // The compiler error 'local variables referenced from a lambda expression must be final 870 // or effectively final' is reported when using i, so assign it to a final variable. 871 final int currI = i; 872 String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 873 (tm) -> tm.getImei(currI)); 874 if (!TextUtils.isEmpty(imei)) { 875 assertImei(imei); 876 } 877 } 878 879 // Also verify that no exception is thrown for any slot index (including invalid ones) 880 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 881 (tm) -> tm.getImei(-1)); 882 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 883 (tm) -> tm.getImei(mTelephonyManager.getPhoneCount())); 884 } 885 886 /** 887 * Verifies that {@link TelephonyManager#getRadioPowerState()} does not throw any exception 888 * and returns radio on. 889 */ 890 @Test testGetRadioPowerState()891 public void testGetRadioPowerState() { 892 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 893 return; 894 } 895 896 // Also verify that no exception is thrown. 897 assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo( 898 TelephonyManager.RADIO_POWER_ON); 899 } 900 901 /** 902 * Verifies that {@link TelephonyManager#setCarrierDataEnabled(boolean)} does not throw any 903 * exception. TODO enhance later if we have an API to get data enabled state. 904 */ 905 @Test testSetCarrierDataEnabled()906 public void testSetCarrierDataEnabled() { 907 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 908 return; 909 } 910 // Also verify that no exception is thrown. 911 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 912 (tm) -> tm.setCarrierDataEnabled(false)); 913 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 914 (tm) -> tm.setCarrierDataEnabled(true)); 915 } 916 917 /** 918 * Verifies that {@link TelephonyManager#rebootRadio()} does not throw any exception 919 * and final radio state is radio power on. 920 */ 921 @Test testRebootRadio()922 public void testRebootRadio() throws Throwable { 923 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 924 return; 925 } 926 assertEquals(mTelephonyManager.getServiceState().getState(), ServiceState.STATE_IN_SERVICE); 927 928 TestThread t = new TestThread(new Runnable() { 929 public void run() { 930 Looper.prepare(); 931 932 mListener = new PhoneStateListener() { 933 @Override 934 public void onRadioPowerStateChanged( 935 @TelephonyManager.RadioPowerState int state) { 936 synchronized (mLock) { 937 if (state == TelephonyManager.RADIO_POWER_ON && mHasRadioPowerOff) { 938 mRadioRebootTriggered = true; 939 mLock.notify(); 940 } else if (state == TelephonyManager.RADIO_POWER_OFF) { 941 // reboot must go to power off 942 mHasRadioPowerOff = true; 943 } 944 } 945 } 946 }; 947 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 948 (tm) -> tm.listen(mListener, 949 PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED)); 950 Looper.loop(); 951 } 952 }); 953 954 assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo( 955 TelephonyManager.RADIO_POWER_ON); 956 assertThat(mRadioRebootTriggered).isFalse(); 957 assertThat(mHasRadioPowerOff).isFalse(); 958 boolean success = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 959 (tm) -> tm.rebootRadio()); 960 //skip this test if not supported or unsuccessful (success=false) 961 if(!success) { 962 return; 963 } 964 965 t.start(); 966 synchronized (mLock) { 967 // reboot takes longer time 968 if (!mRadioRebootTriggered) { 969 mLock.wait(10000); 970 } 971 } 972 assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo( 973 TelephonyManager.RADIO_POWER_ON); 974 assertThat(mRadioRebootTriggered).isTrue(); 975 976 // note, other telephony states might not resumes properly at this point. e.g, service state 977 // might still in the transition from OOS to In service. Thus we need to wait for in 978 // service state before running next tests. 979 t = new TestThread(new Runnable() { 980 public void run() { 981 Looper.prepare(); 982 983 mListener = new PhoneStateListener() { 984 @Override 985 public void onServiceStateChanged(ServiceState serviceState) { 986 synchronized (mLock) { 987 if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) { 988 mServiceStateChangedCalled = true; 989 mLock.notify(); 990 } 991 } 992 } 993 }; 994 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 995 (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE)); 996 Looper.loop(); 997 } 998 }); 999 1000 synchronized (mLock) { 1001 t.start(); 1002 if (!mServiceStateChangedCalled) { 1003 mLock.wait(10000); 1004 } 1005 } 1006 assertThat(mTelephonyManager.getServiceState().getState()).isEqualTo( 1007 ServiceState.STATE_IN_SERVICE); 1008 } 1009 1010 /** 1011 * Verifies that {@link TelephonyManager#getAidForAppType(int)} does not throw any exception 1012 * for all supported subscription app type. 1013 */ 1014 @Test testGetAidForAppType()1015 public void testGetAidForAppType() { 1016 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1017 return; 1018 } 1019 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1020 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_SIM)); 1021 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1022 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_CSIM)); 1023 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1024 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_RUIM)); 1025 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1026 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_ISIM)); 1027 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1028 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_USIM)); 1029 } 1030 1031 /** 1032 * Verifies that {@link TelephonyManager#getIsimDomain()} does not throw any exception 1033 */ 1034 @Test testGetIsimDomain()1035 public void testGetIsimDomain() { 1036 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1037 return; 1038 } 1039 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1040 (tm) -> tm.getIsimDomain()); 1041 } 1042 1043 /** 1044 * Basic test to ensure {@link NetworkRegistrationInfo#isRoaming()} does not throw any 1045 * exception. 1046 */ 1047 @Test testNetworkRegistrationInfoIsRoaming()1048 public void testNetworkRegistrationInfoIsRoaming() { 1049 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1050 return; 1051 } 1052 // get NetworkRegistration object 1053 NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState() 1054 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, 1055 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1056 assertThat(nwReg).isNotNull(); 1057 nwReg.isRoaming(); 1058 } 1059 1060 /** 1061 * Basic test to ensure {@link NetworkRegistrationInfo#getRoamingType()} ()} does not throw any 1062 * exception and returns valid result 1063 * @see ServiceState.RoamingType 1064 */ 1065 @Test testNetworkRegistrationInfoGetRoamingType()1066 public void testNetworkRegistrationInfoGetRoamingType() { 1067 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1068 return; 1069 } 1070 // get NetworkRegistration object for voice 1071 NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState() 1072 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, 1073 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1074 assertNotNull(nwReg); 1075 assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES); 1076 1077 // getNetworkRegistration object for data 1078 // get NetworkRegistration object for voice 1079 nwReg = mTelephonyManager.getServiceState() 1080 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, 1081 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1082 assertThat(nwReg).isNotNull(); 1083 assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES); 1084 } 1085 1086 /** 1087 * Basic test to ensure {@link NetworkRegistrationInfo#getAccessNetworkTechnology()} not 1088 * throw any exception and returns valid result 1089 * @see TelephonyManager.NetworkType 1090 */ 1091 @Test testNetworkRegistationStateGetAccessNetworkTechnology()1092 public void testNetworkRegistationStateGetAccessNetworkTechnology() { 1093 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1094 return; 1095 } 1096 // get NetworkRegistration object for voice 1097 NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState() 1098 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, 1099 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1100 assertThat(nwReg).isNotNull(); 1101 assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES); 1102 1103 // get NetworkRegistation object for data 1104 nwReg = mTelephonyManager.getServiceState() 1105 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, 1106 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1107 assertThat(nwReg).isNotNull(); 1108 assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES); 1109 } 1110 1111 1112 /** 1113 * Tests that the device properly reports either a valid MEID or null. 1114 */ 1115 @Test testGetMeid()1116 public void testGetMeid() { 1117 String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1118 (tm) -> tm.getMeid()); 1119 1120 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1121 if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 1122 assertMeidEsn(meid); 1123 } 1124 } 1125 } 1126 1127 /** 1128 * Tests that the device properly reports either a valid MEID or null. 1129 */ 1130 @Test testGetMeidForSlot()1131 public void testGetMeidForSlot() { 1132 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1133 return; 1134 } 1135 1136 SubscriptionManager sm = (SubscriptionManager) getContext() 1137 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 1138 List<SubscriptionInfo> subInfos = sm.getActiveSubscriptionInfoList(); 1139 1140 if (subInfos != null) { 1141 for (SubscriptionInfo subInfo : subInfos) { 1142 int slotIndex = subInfo.getSimSlotIndex(); 1143 int subId = subInfo.getSubscriptionId(); 1144 TelephonyManager tm = mTelephonyManager.createForSubscriptionId(subId); 1145 if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 1146 String meid = ShellIdentityUtils.invokeMethodWithShellPermissions( 1147 mTelephonyManager, 1148 (telephonyManager) -> telephonyManager.getMeid(slotIndex)); 1149 1150 if (!TextUtils.isEmpty(meid)) { 1151 assertMeidEsn(meid); 1152 } 1153 } 1154 } 1155 } 1156 1157 // Also verify that no exception is thrown for any slot index (including invalid ones) 1158 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1159 (tm) -> tm.getMeid(-1)); 1160 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1161 (tm) -> tm.getMeid(mTelephonyManager.getPhoneCount())); 1162 } 1163 1164 /** 1165 * Tests sendDialerSpecialCode API. 1166 * Expects a security exception since the caller does not have carrier privileges or is not the 1167 * current default dialer app. 1168 */ 1169 @Test testSendDialerSpecialCode()1170 public void testSendDialerSpecialCode() { 1171 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1172 Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY"); 1173 return; 1174 } 1175 try { 1176 mTelephonyManager.sendDialerSpecialCode("4636"); 1177 fail("Expected SecurityException. App does not have carrier privileges or is not the " 1178 + "default dialer app"); 1179 } catch (SecurityException expected) { 1180 } 1181 } 1182 1183 /** 1184 * Tests that the device properly reports the contents of EF_FPLMN or null 1185 */ 1186 @Test testGetForbiddenPlmns()1187 public void testGetForbiddenPlmns() { 1188 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1189 return; 1190 } 1191 String[] plmns = mTelephonyManager.getForbiddenPlmns(); 1192 1193 int phoneType = mTelephonyManager.getPhoneType(); 1194 switch (phoneType) { 1195 case TelephonyManager.PHONE_TYPE_GSM: 1196 assertNotNull("Forbidden PLMNs must be valid or an empty list!", plmns); 1197 case TelephonyManager.PHONE_TYPE_CDMA: 1198 case TelephonyManager.PHONE_TYPE_NONE: 1199 if (plmns == null) { 1200 return; 1201 } 1202 } 1203 1204 for(String plmn : plmns) { 1205 assertTrue( 1206 "Invalid Length for PLMN-ID, must be 5 or 6! plmn=" + plmn, 1207 plmn.length() >= 5 && plmn.length() <= 6); 1208 assertTrue( 1209 "PLMNs must be strings of digits 0-9! plmn=" + plmn, 1210 android.text.TextUtils.isDigitsOnly(plmn)); 1211 } 1212 } 1213 1214 /** 1215 * Verify that TelephonyManager.getCardIdForDefaultEuicc returns a positive value or either 1216 * UNINITIALIZED_CARD_ID or UNSUPPORTED_CARD_ID. 1217 */ 1218 @Test testGetCardIdForDefaultEuicc()1219 public void testGetCardIdForDefaultEuicc() { 1220 int cardId = mTelephonyManager.getCardIdForDefaultEuicc(); 1221 assertTrue("Card ID for default EUICC is not a valid value", 1222 cardId == TelephonyManager.UNSUPPORTED_CARD_ID 1223 || cardId == TelephonyManager.UNINITIALIZED_CARD_ID 1224 || cardId >= 0); 1225 } 1226 1227 /** 1228 * Tests that a SecurityException is thrown when trying to access UiccCardsInfo. 1229 */ 1230 @Test testGetUiccCardsInfo()1231 public void testGetUiccCardsInfo() { 1232 try { 1233 // Requires READ_PRIVILEGED_PHONE_STATE or carrier privileges 1234 List<UiccCardInfo> infos = mTelephonyManager.getUiccCardsInfo(); 1235 fail("Expected SecurityException. App does not have carrier privileges"); 1236 } catch (SecurityException e) { 1237 } 1238 } 1239 getContext()1240 private static Context getContext() { 1241 return InstrumentationRegistry.getContext(); 1242 } 1243 1244 /** 1245 * Tests that the device properly sets the network selection mode to automatic. 1246 * Expects a security exception since the caller does not have carrier privileges. 1247 */ 1248 @Test testSetNetworkSelectionModeAutomatic()1249 public void testSetNetworkSelectionModeAutomatic() { 1250 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1251 Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY"); 1252 return; 1253 } 1254 try { 1255 mTelephonyManager.setNetworkSelectionModeAutomatic(); 1256 fail("Expected SecurityException. App does not have carrier privileges."); 1257 } catch (SecurityException expected) { 1258 } 1259 } 1260 1261 /** 1262 * Tests that the device properly asks the radio to connect to the input network and change 1263 * selection mode to manual. 1264 * Expects a security exception since the caller does not have carrier privileges. 1265 */ 1266 @Test testSetNetworkSelectionModeManual()1267 public void testSetNetworkSelectionModeManual() { 1268 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1269 Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY"); 1270 return; 1271 } 1272 try { 1273 mTelephonyManager.setNetworkSelectionModeManual( 1274 "" /* operatorNumeric */, false /* persistSelection */); 1275 fail("Expected SecurityException. App does not have carrier privileges."); 1276 } catch (SecurityException expected) { 1277 } 1278 } 1279 1280 /** 1281 * Tests TelephonyManager.getEmergencyNumberList. 1282 */ 1283 @Test testGetEmergencyNumberList()1284 public void testGetEmergencyNumberList() { 1285 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1286 return; 1287 } 1288 Map<Integer, List<EmergencyNumber>> emergencyNumberList 1289 = mTelephonyManager.getEmergencyNumberList(); 1290 1291 assertFalse(emergencyNumberList == null); 1292 1293 checkEmergencyNumberFormat(emergencyNumberList); 1294 1295 int defaultSubId = mSubscriptionManager.getDefaultSubscriptionId(); 1296 1297 // 112 and 911 should always be available 1298 // Reference: 3gpp 22.101, Section 10 - Emergency Calls 1299 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1300 emergencyNumberList.get(defaultSubId), "911")); 1301 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1302 emergencyNumberList.get(defaultSubId), "112")); 1303 1304 // 000, 08, 110, 118, 119, and 999 should be always available when sim is absent 1305 // Reference: 3gpp 22.101, Section 10 - Emergency Calls 1306 if (mTelephonyManager.getPhoneCount() > 0 1307 && mSubscriptionManager.getSimStateForSlotIndex(0) 1308 == TelephonyManager.SIM_STATE_ABSENT) { 1309 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1310 emergencyNumberList.get(defaultSubId), "000")); 1311 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1312 emergencyNumberList.get(defaultSubId), "08")); 1313 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1314 emergencyNumberList.get(defaultSubId), "110")); 1315 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1316 emergencyNumberList.get(defaultSubId), "118")); 1317 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1318 emergencyNumberList.get(defaultSubId), "119")); 1319 assertTrue(checkIfEmergencyNumberListHasSpecificAddress( 1320 emergencyNumberList.get(defaultSubId), "999")); 1321 } 1322 } 1323 1324 /** 1325 * Tests TelephonyManager.isEmergencyNumber. 1326 */ 1327 @Test testIsEmergencyNumber()1328 public void testIsEmergencyNumber() { 1329 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1330 return; 1331 } 1332 // 112 and 911 should always be available 1333 // Reference: 3gpp 22.101, Section 10 - Emergency Calls 1334 assertTrue(mTelephonyManager.isEmergencyNumber("911")); 1335 assertTrue(mTelephonyManager.isEmergencyNumber("112")); 1336 1337 // 000, 08, 110, 118, 119, and 999 should be always available when sim is absent 1338 // Reference: 3gpp 22.101, Section 10 - Emergency Calls 1339 if (mTelephonyManager.getPhoneCount() > 0 1340 && mSubscriptionManager.getSimStateForSlotIndex(0) 1341 == TelephonyManager.SIM_STATE_ABSENT) { 1342 assertTrue(mTelephonyManager.isEmergencyNumber("000")); 1343 assertTrue(mTelephonyManager.isEmergencyNumber("08")); 1344 assertTrue(mTelephonyManager.isEmergencyNumber("110")); 1345 assertTrue(mTelephonyManager.isEmergencyNumber("118")); 1346 assertTrue(mTelephonyManager.isEmergencyNumber("119")); 1347 assertTrue(mTelephonyManager.isEmergencyNumber("999")); 1348 } 1349 } 1350 1351 /** 1352 * Tests TelephonyManager.isPotentialEmergencyNumber. 1353 */ 1354 @Test testIsPotentialEmergencyNumber()1355 public void testIsPotentialEmergencyNumber() { 1356 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1357 return; 1358 } 1359 1360 String countryIso = mTelephonyManager.getNetworkCountryIso(); 1361 String potentialEmergencyAddress = "91112345"; 1362 // According to com.android.i18n.phonenumbers.ShortNumberInfo, in 1363 // these countries, if extra digits are added to an emergency number, 1364 // it no longer connects to the emergency service. 1365 if (countryIso.equals("br") || countryIso.equals("cl") || countryIso.equals("ni")) { 1366 assertFalse(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1367 (tm) -> tm.isPotentialEmergencyNumber(potentialEmergencyAddress))); 1368 } else { 1369 assertTrue(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1370 (tm) -> tm.isPotentialEmergencyNumber(potentialEmergencyAddress))); 1371 } 1372 } 1373 1374 /** 1375 * Tests {@link TelephonyManager#getSupportedRadioAccessFamily()} 1376 */ 1377 @Test testGetRadioAccessFamily()1378 public void testGetRadioAccessFamily() { 1379 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1380 return; 1381 } 1382 long raf = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1383 (tm) -> tm.getSupportedRadioAccessFamily()); 1384 assertThat(raf).isNotEqualTo(TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN); 1385 } 1386 assertSetOpportunisticSubSuccess(int value)1387 private static void assertSetOpportunisticSubSuccess(int value) { 1388 assertThat(value).isEqualTo(TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS); 1389 } 1390 assertSetOpportunisticInvalidParameter(int value)1391 private static void assertSetOpportunisticInvalidParameter(int value) { 1392 assertThat(value).isEqualTo(TelephonyManager.SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION); 1393 } 1394 1395 /** 1396 * Tests {@link TelephonyManager#setPreferredOpportunisticDataSubscription} and 1397 * {@link TelephonyManager#getPreferredOpportunisticDataSubscription} 1398 */ 1399 @Test testPreferredOpportunisticDataSubscription()1400 public void testPreferredOpportunisticDataSubscription() { 1401 int randomSubId = 1; 1402 int activeSubscriptionInfoCount = ShellIdentityUtils.invokeMethodWithShellPermissions( 1403 mSubscriptionManager, (tm) -> tm.getActiveSubscriptionInfoCount()); 1404 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1405 return; 1406 } 1407 if (mTelephonyManager.getPhoneCount() == 1) { 1408 return; 1409 } 1410 if (mTelephonyManager.getPhoneCount() == 2 && activeSubscriptionInfoCount != 2) { 1411 fail("This test requires two SIM cards."); 1412 } 1413 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1414 (tm) -> tm.setPreferredOpportunisticDataSubscription( 1415 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, 1416 null, null)); 1417 // wait for the data change to take effect 1418 waitForMs(500); 1419 int subId = 1420 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1421 (tm) -> tm.getPreferredOpportunisticDataSubscription()); 1422 assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 1423 List<SubscriptionInfo> subscriptionInfoList = 1424 ShellIdentityUtils.invokeMethodWithShellPermissions(mSubscriptionManager, 1425 (tm) -> tm.getOpportunisticSubscriptions()); 1426 Consumer<Integer> callbackSuccess = TelephonyManagerTest::assertSetOpportunisticSubSuccess; 1427 Consumer<Integer> callbackFailure = 1428 TelephonyManagerTest::assertSetOpportunisticInvalidParameter; 1429 if (subscriptionInfoList == null || subscriptionInfoList.size() == 0) { 1430 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1431 (tm) -> tm.setPreferredOpportunisticDataSubscription(randomSubId, false, 1432 AsyncTask.SERIAL_EXECUTOR, callbackFailure)); 1433 // wait for the data change to take effect 1434 waitForMs(500); 1435 subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1436 (tm) -> tm.getPreferredOpportunisticDataSubscription()); 1437 assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 1438 1439 } else { 1440 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1441 (tm) -> tm.setPreferredOpportunisticDataSubscription( 1442 subscriptionInfoList.get(0).getSubscriptionId(), false, 1443 AsyncTask.SERIAL_EXECUTOR, callbackSuccess)); 1444 // wait for the data change to take effect 1445 waitForMs(500); 1446 subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1447 (tm) -> tm.getPreferredOpportunisticDataSubscription()); 1448 assertThat(subId).isEqualTo(subscriptionInfoList.get(0).getSubscriptionId()); 1449 } 1450 1451 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1452 (tm) -> tm.setPreferredOpportunisticDataSubscription( 1453 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, 1454 AsyncTask.SERIAL_EXECUTOR, callbackSuccess)); 1455 // wait for the data change to take effect 1456 waitForMs(500); 1457 subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, 1458 (tm) -> tm.getPreferredOpportunisticDataSubscription()); 1459 assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 1460 } 1461 assertUpdateAvailableNetworkSuccess(int value)1462 private static void assertUpdateAvailableNetworkSuccess(int value) { 1463 assertThat(value).isEqualTo(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS); 1464 } 1465 assertUpdateAvailableNetworkInvalidArguments(int value)1466 private static void assertUpdateAvailableNetworkInvalidArguments(int value) { 1467 assertThat(value).isEqualTo(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS); 1468 } 1469 checkIfEmergencyNumberListHasSpecificAddress( List<EmergencyNumber> emergencyNumberList, String address)1470 private static boolean checkIfEmergencyNumberListHasSpecificAddress( 1471 List<EmergencyNumber> emergencyNumberList, String address) { 1472 for (EmergencyNumber emergencyNumber : emergencyNumberList) { 1473 if (address.equals(emergencyNumber.getNumber())) { 1474 return true; 1475 } 1476 } 1477 return false; 1478 } 1479 checkEmergencyNumberFormat( Map<Integer, List<EmergencyNumber>> emergencyNumberLists)1480 private static void checkEmergencyNumberFormat( 1481 Map<Integer, List<EmergencyNumber>> emergencyNumberLists) { 1482 for (List<EmergencyNumber> emergencyNumberList : emergencyNumberLists.values()) { 1483 for (EmergencyNumber emergencyNumber : emergencyNumberList) { 1484 1485 // Validate Emergency number address 1486 assertTrue(validateEmergencyNumberAddress(emergencyNumber.getNumber())); 1487 1488 // Validate Emergency number country Iso 1489 assertTrue(validateEmergencyNumberCountryIso(emergencyNumber.getCountryIso())); 1490 1491 // Validate Emergency number mnc 1492 assertTrue(validateEmergencyNumberMnc(emergencyNumber.getMnc())); 1493 1494 // Validate Emergency service category list 1495 assertTrue(validateEmergencyServiceCategoryList( 1496 emergencyNumber.getEmergencyServiceCategories())); 1497 1498 // Validate Emergency number source list 1499 assertTrue(validateEmergencyNumberSourceList( 1500 emergencyNumber.getEmergencyNumberSources())); 1501 1502 // Validate Emergency URN list 1503 // (just verify it is not null, because the support of this field is optional) 1504 assertTrue(emergencyNumber.getEmergencyUrns() != null); 1505 1506 // Validat Emergency call routing 1507 assertTrue(validateEmergencyCallRouting( 1508 emergencyNumber.getEmergencyCallRouting())); 1509 1510 // Valid the emergency number should be at least in a valid source. 1511 assertTrue(validateEmergencyNumberFromAnySource(emergencyNumber)); 1512 1513 // Valid the emergency number should be at least in a valid category. 1514 assertTrue(validateEmergencyNumberInAnyCategory(emergencyNumber)); 1515 } 1516 1517 // Validate compareTo 1518 assertTrue(validateEmergencyNumberCompareTo(emergencyNumberList)); 1519 } 1520 } 1521 1522 /** 1523 * Tests {@link TelephonyManager#updateAvailableNetworks} 1524 */ 1525 @Test testUpdateAvailableNetworks()1526 public void testUpdateAvailableNetworks() { 1527 int randomSubId = 1; 1528 int activeSubscriptionInfoCount = ShellIdentityUtils.invokeMethodWithShellPermissions( 1529 mSubscriptionManager, (tm) -> tm.getActiveSubscriptionInfoCount()); 1530 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1531 return; 1532 } 1533 if (mTelephonyManager.getPhoneCount() == 1) { 1534 return; 1535 } 1536 if (mTelephonyManager.getPhoneCount() == 2 && activeSubscriptionInfoCount != 2) { 1537 fail("This test requires two SIM cards."); 1538 } 1539 1540 List<SubscriptionInfo> subscriptionInfoList = 1541 ShellIdentityUtils.invokeMethodWithShellPermissions(mSubscriptionManager, 1542 (tm) -> tm.getOpportunisticSubscriptions()); 1543 List<String> mccMncs = new ArrayList<String>(); 1544 List<Integer> bands = new ArrayList<Integer>(); 1545 List<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<AvailableNetworkInfo>(); 1546 Consumer<Integer> callbackSuccess = 1547 TelephonyManagerTest::assertUpdateAvailableNetworkSuccess; 1548 Consumer<Integer> callbackFailure = 1549 TelephonyManagerTest::assertUpdateAvailableNetworkInvalidArguments; 1550 if (subscriptionInfoList == null || subscriptionInfoList.size() == 0 1551 || !mSubscriptionManager.isActiveSubscriptionId( 1552 subscriptionInfoList.get(0).getSubscriptionId())) { 1553 AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(randomSubId, 1554 AvailableNetworkInfo.PRIORITY_HIGH, mccMncs, bands); 1555 availableNetworkInfos.add(availableNetworkInfo); 1556 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1557 (tm) -> tm.updateAvailableNetworks(availableNetworkInfos, 1558 AsyncTask.SERIAL_EXECUTOR, callbackFailure)); 1559 // wait for the data change to take effect 1560 waitForMs(500); 1561 // clear all the operations at the end of test. 1562 availableNetworkInfos.clear(); 1563 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1564 (tm) -> tm.updateAvailableNetworks(availableNetworkInfos, 1565 AsyncTask.SERIAL_EXECUTOR, callbackFailure)); 1566 } else { 1567 AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo( 1568 subscriptionInfoList.get(0).getSubscriptionId(), 1569 AvailableNetworkInfo.PRIORITY_HIGH, mccMncs, bands); 1570 availableNetworkInfos.add(availableNetworkInfo); 1571 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1572 (tm) -> tm.updateAvailableNetworks(availableNetworkInfos, 1573 AsyncTask.SERIAL_EXECUTOR, callbackSuccess)); 1574 // wait for the data change to take effect 1575 waitForMs(500); 1576 // clear all the operations at the end of test. 1577 availableNetworkInfos.clear(); 1578 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1579 (tm) -> tm.updateAvailableNetworks(availableNetworkInfos, 1580 AsyncTask.SERIAL_EXECUTOR, callbackSuccess)); 1581 } 1582 } 1583 1584 @Test testSwitchMultiSimConfig()1585 public void testSwitchMultiSimConfig() { 1586 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1587 return; 1588 } 1589 1590 boolean rebootRequired = ShellIdentityUtils.invokeMethodWithShellPermissions( 1591 mTelephonyManager, (tm) -> tm.doesSwitchMultiSimConfigTriggerReboot()); 1592 1593 // It's hard to test if reboot is needed. 1594 if (!rebootRequired) { 1595 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1596 (tm) -> tm.switchMultiSimConfig(1)); 1597 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1598 (tm) -> tm.switchMultiSimConfig(2)); 1599 } else { 1600 // This should result in no-op. 1601 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager, 1602 (tm) -> tm.switchMultiSimConfig(mTelephonyManager.getPhoneCount())); 1603 } 1604 } 1605 1606 @Test testIccOpenLogicalChannelBySlot()1607 public void testIccOpenLogicalChannelBySlot() { 1608 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1609 return; 1610 } 1611 // just verify no crash 1612 try { 1613 ShellIdentityUtils.invokeMethodWithShellPermissions( 1614 mTelephonyManager, (tm) -> tm.iccOpenLogicalChannelBySlot(0, null, 0)); 1615 } catch (IllegalArgumentException e) { 1616 // IllegalArgumentException is okay, just not SecurityException 1617 } 1618 } 1619 1620 @Test testIccCloseLogicalChannelBySlot()1621 public void testIccCloseLogicalChannelBySlot() { 1622 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1623 return; 1624 } 1625 // just verify no crash 1626 try { 1627 ShellIdentityUtils.invokeMethodWithShellPermissions( 1628 mTelephonyManager, (tm) -> tm.iccCloseLogicalChannelBySlot(0, 0)); 1629 } catch (IllegalArgumentException e) { 1630 // IllegalArgumentException is okay, just not SecurityException 1631 } 1632 } 1633 1634 @Test testIccTransmitApduLogicalChannelBySlot()1635 public void testIccTransmitApduLogicalChannelBySlot() { 1636 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1637 return; 1638 } 1639 int slotIndex = getValidSlotIndex(); 1640 String result = ShellIdentityUtils.invokeMethodWithShellPermissions( 1641 mTelephonyManager, (tm) -> tm.iccTransmitApduLogicalChannelBySlot( 1642 slotIndex, 1643 0 /* channel */, 1644 0 /* cla */, 1645 0 /* instruction */, 1646 0 /* p1 */, 1647 0 /* p2 */, 1648 0 /* p3 */, 1649 null /* data */)); 1650 assertTrue(TextUtils.isEmpty(result)); 1651 } 1652 1653 @Test testIccTransmitApduBasicChannelBySlot()1654 public void testIccTransmitApduBasicChannelBySlot() { 1655 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1656 return; 1657 } 1658 // just verify no crash 1659 int slotIndex = getValidSlotIndex(); 1660 try { 1661 ShellIdentityUtils.invokeMethodWithShellPermissions( 1662 mTelephonyManager, (tm) -> tm.iccTransmitApduBasicChannelBySlot( 1663 slotIndex, 1664 0 /* cla */, 1665 0 /* instruction */, 1666 0 /* p1 */, 1667 0 /* p2 */, 1668 0 /* p3 */, 1669 null /* data */)); 1670 } catch (IllegalArgumentException e ) { 1671 // IllegalArgumentException is okay, just not SecurityException 1672 } 1673 } 1674 1675 /** 1676 * Validate Emergency Number address that only contains the dialable character. 1677 * 1678 * @param address Emergency number address to validate 1679 * @return {@code true} if the address is valid; {@code false} otherwise. 1680 */ validateEmergencyNumberAddress(String address)1681 private static boolean validateEmergencyNumberAddress(String address) { 1682 if (address == null) { 1683 return false; 1684 } 1685 for (char c : address.toCharArray()) { 1686 if (!isDialable(c)) { 1687 return false; 1688 } 1689 } 1690 return true; 1691 } 1692 1693 /** 1694 * Validate Emergency Number country Iso 1695 * 1696 * @param countryIso Emergency number country iso to validate 1697 * @return {@code true} if the country iso is valid; {@code false} otherwise. 1698 */ validateEmergencyNumberCountryIso(String countryIso)1699 private static boolean validateEmergencyNumberCountryIso(String countryIso) { 1700 if (countryIso == null) { 1701 return false; 1702 } 1703 int length = countryIso.length(); 1704 return length >= 0 && length <= 2; 1705 } 1706 1707 /** 1708 * Validate Emergency Number MNC 1709 * 1710 * @param mnc Emergency number MNC to validate 1711 * @return {@code true} if the MNC is valid; {@code false} otherwise. 1712 */ validateEmergencyNumberMnc(String mnc)1713 private static boolean validateEmergencyNumberMnc(String mnc) { 1714 if (mnc == null) { 1715 return false; 1716 } 1717 int length = mnc.length(); 1718 return length >= 0 && length <= 3; 1719 } 1720 1721 /** 1722 * Validate Emergency service category list 1723 * 1724 * @param categories Emergency service category list to validate 1725 * @return {@code true} if the category list is valid; {@code false} otherwise. 1726 */ validateEmergencyServiceCategoryList(List<Integer> categories)1727 private static boolean validateEmergencyServiceCategoryList(List<Integer> categories) { 1728 if (categories == null) { 1729 return false; 1730 } 1731 if (categories.contains(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED)) { 1732 return categories.size() == 1; 1733 } 1734 for (int category : categories) { 1735 if (!EMERGENCY_SERVICE_CATEGORY_SET.contains(category)) { 1736 return false; 1737 } 1738 } 1739 return true; 1740 } 1741 1742 /** 1743 * Validate Emergency number source list 1744 * 1745 * @param categories Emergency number source list to validate 1746 * @return {@code true} if the source list is valid; {@code false} otherwise. 1747 */ validateEmergencyNumberSourceList(List<Integer> sources)1748 private static boolean validateEmergencyNumberSourceList(List<Integer> sources) { 1749 if (sources == null) { 1750 return false; 1751 } 1752 for (int source : sources) { 1753 if (!EMERGENCY_NUMBER_SOURCE_SET.contains(source)) { 1754 return false; 1755 } 1756 } 1757 return true; 1758 } 1759 1760 /** 1761 * Validate Emergency call routing. 1762 * 1763 * @param routing Emergency call routing to validate 1764 * @return {@code true} if the emergency call routing is valid; {@code false} otherwise. 1765 */ validateEmergencyCallRouting(int routing)1766 private static boolean validateEmergencyCallRouting(int routing) { 1767 return routing >= EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN 1768 && routing <= (EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY 1769 | EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL); 1770 } 1771 1772 /** 1773 * Valid the emergency number should be at least from a valid source. 1774 * 1775 * @param emergencyNumber Emergency number to verify 1776 * @return {@code true} if the emergency number is from any source; {@code false} otherwise. 1777 */ validateEmergencyNumberFromAnySource(EmergencyNumber emergencyNumber)1778 private static boolean validateEmergencyNumberFromAnySource(EmergencyNumber emergencyNumber) { 1779 boolean isFromAnySource = false; 1780 for (int possibleSourceValue = EMERGENCY_NUMBER_SOURCE_RIL_ECCLIST; 1781 possibleSourceValue <= (EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING 1782 | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM 1783 | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE 1784 | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG 1785 | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT); 1786 possibleSourceValue++) { 1787 if (emergencyNumber.isFromSources(possibleSourceValue)) { 1788 isFromAnySource = true; 1789 break; 1790 } 1791 } 1792 return isFromAnySource; 1793 } 1794 1795 /** 1796 * Valid the emergency number should be at least in a valid category. 1797 * 1798 * @param emergencyNumber Emergency number to verify 1799 * @return {@code true} if it is in any category; {@code false} otherwise. 1800 */ validateEmergencyNumberInAnyCategory(EmergencyNumber emergencyNumber)1801 private static boolean validateEmergencyNumberInAnyCategory(EmergencyNumber emergencyNumber) { 1802 boolean isInAnyCategory = false; 1803 for (int possibleCategoryValue = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED; 1804 possibleCategoryValue <= (EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE 1805 | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE 1806 | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE 1807 | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD 1808 | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE 1809 | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC 1810 | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC); 1811 possibleCategoryValue++) { 1812 if (emergencyNumber.isInEmergencyServiceCategories(possibleCategoryValue)) { 1813 isInAnyCategory = true; 1814 break; 1815 } 1816 } 1817 return isInAnyCategory; 1818 } 1819 validateEmergencyNumberCompareTo( List<EmergencyNumber> emergencyNumberList)1820 private static boolean validateEmergencyNumberCompareTo( 1821 List<EmergencyNumber> emergencyNumberList) { 1822 if (emergencyNumberList == null) { 1823 return false; 1824 } 1825 if (emergencyNumberList.size() > 0) { 1826 EmergencyNumber emergencyNumber = emergencyNumberList.get(0); 1827 if (emergencyNumber.compareTo(emergencyNumber) != 0) { 1828 return false; 1829 } 1830 } 1831 return true; 1832 } 1833 isDialable(char c)1834 private static boolean isDialable(char c) { 1835 return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N'; 1836 } 1837 getValidSlotIndex()1838 private int getValidSlotIndex() { 1839 return ShellIdentityUtils.invokeMethodWithShellPermissions( 1840 mTelephonyManager, (tm) -> { 1841 List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo(); 1842 Set<String> presentCards = Arrays.stream(mTelephonyManager.getUiccSlotsInfo()) 1843 .filter(UiccSlotInfo::getIsActive) 1844 .map(UiccSlotInfo::getCardId) 1845 .filter(Objects::nonNull) 1846 // hack around getUiccSlotsInfo not stripping trailing F 1847 .map(s -> s.endsWith("F") ? s.substring(0, s.length() - 1) : s) 1848 .collect(Collectors.toSet()); 1849 int slotIndex = -1; 1850 for (UiccCardInfo cardInfo : cardInfos) { 1851 if (presentCards.contains(cardInfo.getIccId()) 1852 || presentCards.contains(cardInfo.getEid())) { 1853 slotIndex = cardInfo.getSlotIndex(); 1854 break; 1855 } 1856 } 1857 if (slotIndex < 0) { 1858 fail("Test must be run with SIM card inserted, presentCards = " 1859 + presentCards + "cardinfos = " + cardInfos); 1860 } 1861 return slotIndex; 1862 }); 1863 } 1864 waitForMs(long ms)1865 public static void waitForMs(long ms) { 1866 try { 1867 Thread.sleep(ms); 1868 } catch (InterruptedException e) { 1869 Log.d(TAG, "InterruptedException while waiting: " + e); 1870 } 1871 } 1872 } 1873