1 /* 2 * Copyright (C) 2015 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 android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 20 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 21 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 22 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 23 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 24 import static android.telephony.SubscriptionManager.TRANSFER_STATUS_TRANSFERRED_OUT; 25 import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS; 26 27 import static com.google.common.truth.Truth.assertThat; 28 29 import static org.junit.Assert.assertEquals; 30 import static org.junit.Assert.assertFalse; 31 import static org.junit.Assert.assertNotEquals; 32 import static org.junit.Assert.assertNotNull; 33 import static org.junit.Assert.assertNull; 34 import static org.junit.Assert.assertTrue; 35 import static org.junit.Assert.fail; 36 import static org.junit.Assume.assumeNotNull; 37 import static org.junit.Assume.assumeTrue; 38 39 import android.annotation.Nullable; 40 import android.app.AppOpsManager; 41 import android.app.UiAutomation; 42 import android.content.BroadcastReceiver; 43 import android.content.Context; 44 import android.content.Intent; 45 import android.content.IntentFilter; 46 import android.content.pm.PackageManager; 47 import android.content.res.Resources; 48 import android.net.ConnectivityManager; 49 import android.net.ConnectivityManager.NetworkCallback; 50 import android.net.Network; 51 import android.net.NetworkCapabilities; 52 import android.net.NetworkRequest; 53 import android.net.Uri; 54 import android.os.Looper; 55 import android.os.ParcelUuid; 56 import android.os.PersistableBundle; 57 import android.os.Process; 58 import android.os.UserHandle; 59 import android.platform.test.annotations.AppModeNonSdkSandbox; 60 import android.platform.test.annotations.RequiresFlagsEnabled; 61 import android.platform.test.flag.junit.CheckFlagsRule; 62 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 63 import android.telephony.CarrierConfigManager; 64 import android.telephony.SubscriptionInfo; 65 import android.telephony.SubscriptionManager; 66 import android.telephony.SubscriptionPlan; 67 import android.telephony.TelephonyManager; 68 import android.telephony.cts.util.TelephonyUtils; 69 import android.telephony.ims.ImsException; 70 import android.telephony.ims.ImsManager; 71 import android.telephony.ims.ImsMmTelManager; 72 import android.telephony.ims.ImsRcsManager; 73 import android.telephony.ims.RcsUceAdapter; 74 75 import androidx.test.InstrumentationRegistry; 76 77 import com.android.compatibility.common.util.ApiTest; 78 import com.android.compatibility.common.util.CarrierPrivilegeUtils; 79 import com.android.compatibility.common.util.PropertyUtil; 80 import com.android.compatibility.common.util.ShellIdentityUtils; 81 import com.android.compatibility.common.util.SystemUtil; 82 import com.android.compatibility.common.util.TestThread; 83 import com.android.internal.telephony.flags.Flags; 84 import com.android.internal.util.ArrayUtils; 85 86 import org.junit.After; 87 import org.junit.AfterClass; 88 import org.junit.Before; 89 import org.junit.BeforeClass; 90 import org.junit.Rule; 91 import org.junit.Test; 92 93 import java.io.ByteArrayInputStream; 94 import java.io.IOException; 95 import java.time.Period; 96 import java.time.ZonedDateTime; 97 import java.util.ArrayList; 98 import java.util.Arrays; 99 import java.util.HashSet; 100 import java.util.List; 101 import java.util.Set; 102 import java.util.UUID; 103 import java.util.concurrent.CompletableFuture; 104 import java.util.concurrent.CountDownLatch; 105 import java.util.concurrent.Executor; 106 import java.util.concurrent.LinkedBlockingQueue; 107 import java.util.concurrent.TimeUnit; 108 import java.util.concurrent.atomic.AtomicBoolean; 109 import java.util.function.BooleanSupplier; 110 import java.util.function.Consumer; 111 import java.util.function.Predicate; 112 import java.util.stream.Collectors; 113 114 public class SubscriptionManagerTest { 115 private static final String TAG = "SubscriptionManagerTest"; 116 private static final String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE"; 117 private static final String READ_PRIVILEGED_PHONE_STATE = 118 "android.permission.READ_PRIVILEGED_PHONE_STATE"; 119 private static final List<Uri> CONTACTS = new ArrayList<>(); 120 static { 121 CONTACTS.add(Uri.fromParts("tel", "+16505551212", null)); 122 CONTACTS.add(Uri.fromParts("tel", "+16505552323", null)); 123 } 124 125 // time to wait when testing APIs which enable or disable subscriptions. The time waiting 126 // to enable is longer because enabling a subscription can take longer than disabling 127 private static final int SUBSCRIPTION_DISABLE_WAIT_MS = 5000; 128 private static final int SUBSCRIPTION_ENABLE_WAIT_MS = 50000; 129 130 // time to wait for subscription plans to expire 131 private static final int SUBSCRIPTION_PLAN_EXPIRY_MS = 50; 132 private static final int SUBSCRIPTION_PLAN_CLEAR_WAIT_MS = 5000; 133 134 @Rule 135 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 136 137 private int mSubId; 138 private int mDefaultVoiceSubId; 139 private String mPackageName; 140 private SubscriptionManager mSm; 141 private SubscriptionManagerTest.CarrierConfigReceiver mReceiver; 142 @SuppressWarnings("StaticAssignmentOfThrowable") 143 private static AssertionError sInitError = null; 144 145 private static class CarrierConfigReceiver extends BroadcastReceiver { 146 private CountDownLatch mLatch = new CountDownLatch(1); 147 private final int mSubId; 148 CarrierConfigReceiver(int subId)149 CarrierConfigReceiver(int subId) { 150 mSubId = subId; 151 } 152 153 @Override onReceive(Context context, Intent intent)154 public void onReceive(Context context, Intent intent) { 155 if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) { 156 int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, 157 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 158 if (mSubId == subId) { 159 mLatch.countDown(); 160 } 161 } 162 } 163 clearQueue()164 void clearQueue() { 165 mLatch = new CountDownLatch(1); 166 } 167 waitForCarrierConfigChanged()168 void waitForCarrierConfigChanged() throws Exception { 169 mLatch.await(5000, TimeUnit.MILLISECONDS); 170 } 171 } 172 overrideCarrierConfig(PersistableBundle bundle, int subId)173 private void overrideCarrierConfig(PersistableBundle bundle, int subId) throws Exception { 174 mReceiver = new CarrierConfigReceiver(subId); 175 IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 176 InstrumentationRegistry.getContext().registerReceiver(mReceiver, filter); 177 try { 178 mReceiver.clearQueue(); 179 180 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn( 181 InstrumentationRegistry.getContext().getSystemService( 182 CarrierConfigManager.class), 183 (cm) -> cm.overrideConfig(subId, bundle)); 184 mReceiver.waitForCarrierConfigChanged(); 185 } finally { 186 InstrumentationRegistry.getContext().unregisterReceiver(mReceiver); 187 mReceiver = null; 188 } 189 } 190 191 /** 192 * Callback used in testRegisterNetworkCallback that allows caller to block on 193 * {@code onAvailable}. 194 */ 195 private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { 196 private final CountDownLatch mAvailableLatch = new CountDownLatch(1); 197 waitForAvailable()198 public void waitForAvailable() throws InterruptedException { 199 assumeTrue("Cellular network did not come up after 5 seconds", 200 mAvailableLatch.await(5, TimeUnit.SECONDS)); 201 } 202 203 @Override onAvailable(Network network)204 public void onAvailable(Network network) { 205 mAvailableLatch.countDown(); 206 } 207 } 208 209 @BeforeClass 210 @SuppressWarnings("StaticAssignmentOfThrowable") setUpClass()211 public static void setUpClass() throws Exception { 212 if (!isSupported()) return; 213 214 final TestNetworkCallback callback = new TestNetworkCallback(); 215 final ConnectivityManager cm = InstrumentationRegistry.getContext() 216 .getSystemService(ConnectivityManager.class); 217 cm.registerNetworkCallback(new NetworkRequest.Builder() 218 .addTransportType(TRANSPORT_CELLULAR) 219 .addCapability(NET_CAPABILITY_INTERNET) 220 .build(), callback); 221 try { 222 // Wait to get callback for availability of internet 223 callback.waitForAvailable(); 224 } catch (AssertionError e) { 225 sInitError = e; 226 } catch (InterruptedException e) { 227 sInitError = new AssertionError("NetworkCallback wait was interrupted"); 228 } finally { 229 cm.unregisterNetworkCallback(callback); 230 } 231 } 232 233 @AfterClass tearDownClass()234 public static void tearDownClass() throws Exception { 235 if (!isSupported()) return; 236 TelephonyUtils.flushTelephonyMetrics(InstrumentationRegistry.getInstrumentation()); 237 } 238 239 @Before setUp()240 public void setUp() throws Exception { 241 if (sInitError != null) throw sInitError; 242 assumeTrue(isSupported()); 243 244 mSm = InstrumentationRegistry.getContext().getSystemService(SubscriptionManager.class); 245 mSubId = SubscriptionManager.getDefaultDataSubscriptionId(); 246 mDefaultVoiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId(); 247 mPackageName = InstrumentationRegistry.getContext().getPackageName(); 248 249 setIdentifierAccess(false); 250 } 251 252 @After tearDown()253 public void tearDown() throws Exception { 254 if (mReceiver != null) { 255 InstrumentationRegistry.getContext().unregisterReceiver(mReceiver); 256 mReceiver = null; 257 } 258 } 259 260 /** 261 * Correctness check that both {@link PackageManager#FEATURE_TELEPHONY} and 262 * {@link NetworkCapabilities#TRANSPORT_CELLULAR} network must both be 263 * either defined or undefined; you can't cross the streams. 264 */ 265 @Test testCorrectness()266 public void testCorrectness() throws Exception { 267 final boolean hasCellular = findCellularNetwork() != null; 268 if (!hasCellular) { 269 fail("Device claims to support " + PackageManager.FEATURE_TELEPHONY 270 + " but has no active cellular network, which is required for validation"); 271 } 272 273 if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 274 fail("Device must have a valid default data subId for validation"); 275 } 276 } 277 278 @Test 279 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testGetActiveSubscriptionInfoCount()280 public void testGetActiveSubscriptionInfoCount() throws Exception { 281 assertTrue(mSm.getActiveSubscriptionInfoCount() <= 282 mSm.getActiveSubscriptionInfoCountMax()); 283 } 284 285 @Test 286 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testGetActiveSubscriptionInfoForIcc()287 public void testGetActiveSubscriptionInfoForIcc() throws Exception { 288 SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 289 (sm) -> sm.getActiveSubscriptionInfo(mSubId)); 290 assertNotNull(ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 291 (sm) -> sm.getActiveSubscriptionInfoForIcc(info.getIccId()))); 292 } 293 294 @Test 295 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testGetAllSubscriptionInfoList()296 public void testGetAllSubscriptionInfoList() throws Exception { 297 List<SubscriptionInfo> allSubInfoList = ShellIdentityUtils.invokeMethodWithShellPermissions( 298 mSm, SubscriptionManager::getAllSubscriptionInfoList); 299 SubscriptionInfo subInfo = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 300 (sm) -> sm.getActiveSubscriptionInfo(mSubId)); 301 assertThat(allSubInfoList).contains(subInfo); 302 } 303 304 @Test 305 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testIsActiveSubscriptionId()306 public void testIsActiveSubscriptionId() throws Exception { 307 assertTrue(mSm.isActiveSubscriptionId(mSubId)); 308 } 309 310 @Test testGetSubscriptionIds()311 public void testGetSubscriptionIds() throws Exception { 312 int slotId = SubscriptionManager.getSlotIndex(mSubId); 313 int[] subIds = mSm.getSubscriptionIds(slotId); 314 assertNotNull(subIds); 315 assertTrue(ArrayUtils.contains(subIds, mSubId)); 316 } 317 318 @Test testGetSubscriptionId()319 public void testGetSubscriptionId() throws Exception { 320 int slotId = SubscriptionManager.getSlotIndex(mSubId); 321 assertThat(SubscriptionManager.getSubscriptionId(slotId)).isEqualTo(mSubId); 322 } 323 324 @Test 325 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testGetResourcesForSubId()326 public void testGetResourcesForSubId() { 327 Resources r = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 328 (sm) -> sm.getResourcesForSubId(InstrumentationRegistry.getContext(), mSubId)); 329 // this is an old method which returns mcc/mnc as ints, so use the old SM.getMcc/Mnc methods 330 // because they also use ints 331 assertEquals(mSm.getActiveSubscriptionInfo(mSubId).getMcc(), r.getConfiguration().mcc); 332 assertEquals(mSm.getActiveSubscriptionInfo(mSubId).getMnc(), r.getConfiguration().mnc); 333 } 334 335 @Test testIsUsableSubscriptionId()336 public void testIsUsableSubscriptionId() throws Exception { 337 assertTrue(SubscriptionManager.isUsableSubscriptionId(mSubId)); 338 } 339 340 @Test 341 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testActiveSubscriptions()342 public void testActiveSubscriptions() throws Exception { 343 List<SubscriptionInfo> subList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 344 (sm) -> sm.getActiveSubscriptionInfoList()); 345 int[] idList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 346 (sm) -> sm.getActiveSubscriptionIdList()); 347 // Assert when there is no sim card present or detected 348 assertNotNull("Active subscriber required", subList); 349 assertNotNull("Active subscriber required", idList); 350 assertFalse("Active subscriber required", subList.isEmpty()); 351 assertNotEquals("Active subscriber required", 0, idList.length); 352 for (int i = 0; i < subList.size(); i++) { 353 assertTrue(subList.get(i).getSubscriptionId() >= 0); 354 assertTrue(subList.get(i).getSimSlotIndex() >= 0); 355 assertTrue(ArrayUtils.contains(idList, subList.get(i).getSubscriptionId())); 356 if (i >= 1) { 357 assertTrue(subList.get(i - 1).getSimSlotIndex() 358 <= subList.get(i).getSimSlotIndex()); 359 assertTrue(subList.get(i - 1).getSimSlotIndex() < subList.get(i).getSimSlotIndex() 360 || subList.get(i - 1).getSubscriptionId() 361 < subList.get(i).getSubscriptionId()); 362 } 363 } 364 } 365 366 @Test 367 @RequiresFlagsEnabled(Flags.FLAG_ENFORCE_SUBSCRIPTION_USER_FILTER) 368 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") 369 public void testForAllProfilesSubscriptionManager() { 370 SubscriptionManager allProfileSm = InstrumentationRegistry.getContext() 371 .getSystemService(SubscriptionManager.class).createForAllUserProfiles(); 372 373 List<SubscriptionInfo> specificProfileSubList = ShellIdentityUtils 374 .invokeMethodWithShellPermissions(mSm, 375 SubscriptionManager::getActiveSubscriptionInfoList); 376 // Assert when there is no sim card present or detected 377 assertNotNull("Active subscriber required", specificProfileSubList); 378 379 List<SubscriptionInfo> allProfileSubList = ShellIdentityUtils 380 .invokeMethodWithShellPermissions(allProfileSm, 381 SubscriptionManager::getActiveSubscriptionInfoList); 382 383 assertTrue(allProfileSubList.size() >= specificProfileSubList.size()); 384 } 385 386 @Test 387 public void testSubscriptionPlans() throws Exception { 388 // Make ourselves the owner 389 setSubPlanOwner(mSubId, mPackageName); 390 391 // Push empty list and we get empty back 392 mSm.setSubscriptionPlans(mSubId, Arrays.asList()); 393 assertEquals(Arrays.asList(), mSm.getSubscriptionPlans(mSubId)); 394 395 // Push simple plan and get it back 396 final SubscriptionPlan plan = buildValidSubscriptionPlan(System.currentTimeMillis()); 397 mSm.setSubscriptionPlans(mSubId, Arrays.asList(plan)); 398 final SubscriptionPlan returnedPlan = mSm.getSubscriptionPlans(mSubId).get(0); 399 assertEquals(plan, returnedPlan); 400 if (Flags.subscriptionPlanAllowStatusAndEndDate()) { 401 assertNull(returnedPlan.getPlanEndDate()); 402 assertEquals( 403 SubscriptionPlan.SUBSCRIPTION_STATUS_ACTIVE, 404 returnedPlan.getSubscriptionStatus()); 405 } 406 407 // Push plan with expiration time and verify that it expired 408 mSm.setSubscriptionPlans(mSubId, Arrays.asList(plan), SUBSCRIPTION_PLAN_EXPIRY_MS); 409 Thread.sleep(SUBSCRIPTION_PLAN_EXPIRY_MS); 410 Thread.sleep(SUBSCRIPTION_PLAN_CLEAR_WAIT_MS); 411 assertTrue(mSm.getSubscriptionPlans(mSubId).isEmpty()); 412 413 // Push simple non-recurring plan and get it back 414 ZonedDateTime start = ZonedDateTime.parse("2007-03-14T00:00:00.000Z"); 415 ZonedDateTime end = ZonedDateTime.parse("2024-11-08T00:00:00.000Z"); 416 final SubscriptionPlan planNonRecurring = 417 buildValidSubscriptionPlanNonRecurring(System.currentTimeMillis(), start, end); 418 mSm.setSubscriptionPlans(mSubId, Arrays.asList(planNonRecurring)); 419 final SubscriptionPlan returnedPlanNonRecurring = mSm.getSubscriptionPlans(mSubId).get(0); 420 assertEquals(planNonRecurring, returnedPlanNonRecurring); 421 if (Flags.subscriptionPlanAllowStatusAndEndDate()) { 422 assertEquals(end, returnedPlanNonRecurring.getPlanEndDate()); 423 } 424 425 // Now revoke our access 426 setSubPlanOwner(mSubId, null); 427 try { 428 mSm.setSubscriptionPlans(mSubId, Arrays.asList()); 429 fail(); 430 } catch (SecurityException expected) { 431 } 432 try { 433 mSm.getSubscriptionPlans(mSubId); 434 fail(); 435 } catch (SecurityException expected) { 436 } 437 } 438 439 @Test 440 public void testSubscriptionPlansOverrideCongested() throws Exception { 441 final ConnectivityManager cm = InstrumentationRegistry.getContext() 442 .getSystemService(ConnectivityManager.class); 443 final Network net = findCellularNetwork(); 444 assumeNotNull("Active cellular network required", net); 445 446 // Make ourselves the owner 447 setSubPlanOwner(mSubId, mPackageName); 448 449 // Missing plans means no overrides 450 mSm.setSubscriptionPlans(mSubId, Arrays.asList()); 451 try { 452 mSm.setSubscriptionOverrideCongested(mSubId, true, 0); 453 fail(); 454 } catch (SecurityException | IllegalStateException expected) { 455 } 456 457 // Defining plans means we get to override 458 mSm.setSubscriptionPlans(mSubId, 459 Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis()))); 460 461 // Cellular is uncongested by default 462 assertTrue(cm.getNetworkCapabilities(net).hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 463 464 // Override should make it go congested 465 { 466 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 467 return !caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 468 }); 469 mSm.setSubscriptionOverrideCongested( 470 mSubId, true, TelephonyManager.getAllNetworkTypes(), 0); 471 assertTrue(latch.await(10, TimeUnit.SECONDS)); 472 } 473 474 // Clearing override should make it go uncongested 475 { 476 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 477 return caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 478 }); 479 mSm.setSubscriptionOverrideCongested(mSubId, false, 0); 480 assertTrue(latch.await(10, TimeUnit.SECONDS)); 481 } 482 483 // Now revoke our access 484 setSubPlanOwner(mSubId, null); 485 try { 486 mSm.setSubscriptionOverrideCongested( 487 mSubId, true, TelephonyManager.getAllNetworkTypes(), 0); 488 fail(); 489 } catch (SecurityException | IllegalStateException expected) { 490 } 491 } 492 493 @Test testSubscriptionInfoRecord()494 public void testSubscriptionInfoRecord() { 495 assumeTrue("Remote SIM is only supported on automotive", isAutomotive()); 496 497 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 498 499 final String uniqueId = "00:01:02:03:04:05"; 500 final String displayName = "device_name"; 501 uiAutomation.adoptShellPermissionIdentity(); 502 try { 503 mSm.addSubscriptionInfoRecord(uniqueId, displayName, 504 SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB, 505 SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); 506 assertNotNull(mSm.getActiveSubscriptionInfoForIcc(uniqueId)); 507 mSm.removeSubscriptionInfoRecord(uniqueId, 508 SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); 509 assertNull(mSm.getActiveSubscriptionInfoForIcc(uniqueId)); 510 } finally { 511 uiAutomation.dropShellPermissionIdentity(); 512 } 513 514 // Testing permission fail 515 try { 516 mSm.addSubscriptionInfoRecord(uniqueId, displayName, 517 SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB, 518 SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); 519 mSm.removeSubscriptionInfoRecord(uniqueId, 520 SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); 521 fail("SecurityException should be thrown without MODIFY_PHONE_STATE"); 522 } catch (SecurityException expected) { 523 // expected 524 } 525 } 526 527 @Test testSetDefaultVoiceSubId()528 public void testSetDefaultVoiceSubId() { 529 // Only make sense to set default sub if the device supports more than 1 modem. 530 final TelephonyManager tm = InstrumentationRegistry.getContext() 531 .getSystemService(TelephonyManager.class).createForSubscriptionId(mSubId); 532 assumeTrue(tm.getActiveModemCount() > 1); 533 534 int oldSubId = SubscriptionManager.getDefaultVoiceSubscriptionId(); 535 InstrumentationRegistry.getInstrumentation().getUiAutomation() 536 .adoptShellPermissionIdentity(); 537 538 final String uniqueId = "00:01:02:03:04:05"; 539 final String displayName = "device_name"; 540 try { 541 // Insert a second SIM 542 mSm.addSubscriptionInfoRecord(uniqueId, displayName, 1, 543 SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); 544 mSm.getActiveSubscriptionInfoForIcc(uniqueId); 545 546 mSm.setDefaultVoiceSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 547 assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, 548 SubscriptionManager.getDefaultVoiceSubscriptionId()); 549 mSm.setDefaultVoiceSubscriptionId(oldSubId); 550 assertEquals(oldSubId, SubscriptionManager.getDefaultVoiceSubscriptionId()); 551 552 // Remove the second SIM 553 mSm.removeSubscriptionInfoRecord(uniqueId, 554 SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); 555 assertNull(mSm.getActiveSubscriptionInfoForIcc(uniqueId)); 556 } finally { 557 InstrumentationRegistry.getInstrumentation().getUiAutomation() 558 .dropShellPermissionIdentity(); 559 } 560 } 561 562 @Test testSubscriptionPlansOverrideUnmetered()563 public void testSubscriptionPlansOverrideUnmetered() throws Exception { 564 final ConnectivityManager cm = InstrumentationRegistry.getContext() 565 .getSystemService(ConnectivityManager.class); 566 final Network net = findCellularNetwork(); 567 assumeNotNull("Active cellular network required", net); 568 569 // TODO: Remove this check after b/176119724 is fixed. 570 if (!isUnmetered5GSupported()) return; 571 572 // Cellular is metered by default 573 assertFalse(cm.getNetworkCapabilities(net).hasCapability( 574 NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 575 576 // Override should make it go temporarily unmetered 577 { 578 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 579 return caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 580 }); 581 mSm.setSubscriptionOverrideUnmetered( 582 mSubId, true, TelephonyManager.getAllNetworkTypes(), 0); 583 assertTrue(latch.await(10, TimeUnit.SECONDS)); 584 } 585 586 // Clearing override should make it go metered 587 { 588 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 589 return !caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 590 }); 591 mSm.setSubscriptionOverrideUnmetered( 592 mSubId, false, TelephonyManager.getAllNetworkTypes(), 0); 593 assertTrue(latch.await(10, TimeUnit.SECONDS)); 594 } 595 } 596 597 @Test testSubscriptionPlansUnmetered()598 public void testSubscriptionPlansUnmetered() throws Exception { 599 final ConnectivityManager cm = InstrumentationRegistry.getContext() 600 .getSystemService(ConnectivityManager.class); 601 final Network net = findCellularNetwork(); 602 assumeNotNull("Active cellular network required", net); 603 604 // TODO: Remove this check after b/176119724 is fixed. 605 if (!isUnmetered5GSupported()) return; 606 607 // Make ourselves the owner and define some plans 608 setSubPlanOwner(mSubId, mPackageName); 609 mSm.setSubscriptionPlans(mSubId, 610 Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis()))); 611 612 // Cellular is metered by default 613 assertFalse(cm.getNetworkCapabilities(net).hasCapability( 614 NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 615 616 SubscriptionPlan unmeteredPlan = SubscriptionPlan.Builder 617 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 618 Period.ofMonths(1)) 619 .setTitle("CTS") 620 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED, 621 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 622 .build(); 623 624 // Unmetered plan should make it go unmetered 625 { 626 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 627 return caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 628 }); 629 mSm.setSubscriptionPlans(mSubId, Arrays.asList(unmeteredPlan)); 630 assertTrue(latch.await(10, TimeUnit.SECONDS)); 631 } 632 633 // Metered plan should make it go metered 634 { 635 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 636 return !caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 637 }); 638 mSm.setSubscriptionPlans(mSubId, 639 Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis()))); 640 assertTrue(latch.await(10, TimeUnit.SECONDS)); 641 } 642 } 643 644 @Test testSubscriptionPlansInvalid()645 public void testSubscriptionPlansInvalid() throws Exception { 646 // Make ourselves the owner 647 setSubPlanOwner(mSubId, mPackageName); 648 649 // Empty plans can't override 650 assertOverrideFails(); 651 652 // Nonrecurring plan in the past can't override 653 assertOverrideFails(SubscriptionPlan.Builder 654 .createNonrecurring(ZonedDateTime.now().minusDays(14), 655 ZonedDateTime.now().minusDays(7)) 656 .setTitle("CTS") 657 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 658 .build()); 659 660 // Plan with undefined limit can't override 661 assertOverrideFails(SubscriptionPlan.Builder 662 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 663 Period.ofMonths(1)) 664 .setTitle("CTS") 665 .build()); 666 667 // We can override when there is an active plan somewhere 668 final SubscriptionPlan older = SubscriptionPlan.Builder 669 .createNonrecurring(ZonedDateTime.now().minusDays(14), 670 ZonedDateTime.now().minusDays(7)) 671 .setTitle("CTS") 672 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 673 .build(); 674 final SubscriptionPlan newer = SubscriptionPlan.Builder 675 .createNonrecurring(ZonedDateTime.now().minusDays(7), 676 ZonedDateTime.now().plusDays(7)) 677 .setTitle("CTS") 678 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 679 .build(); 680 assertOverrideSuccess(older, newer); 681 } 682 683 @Test testSubscriptionPlansNetworkTypeValidation()684 public void testSubscriptionPlansNetworkTypeValidation() throws Exception { 685 // Make ourselves the owner 686 setSubPlanOwner(mSubId, mPackageName); 687 688 // Error when adding 2 plans with the same network type 689 List<SubscriptionPlan> plans = new ArrayList<>(); 690 plans.add(buildValidSubscriptionPlan(System.currentTimeMillis())); 691 plans.add(SubscriptionPlan.Builder 692 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 693 Period.ofMonths(1)) 694 .setTitle("CTS") 695 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 696 .build()); 697 plans.add(SubscriptionPlan.Builder 698 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 699 Period.ofMonths(1)) 700 .setTitle("CTS") 701 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 702 .build()); 703 try { 704 mSm.setSubscriptionPlans(mSubId, plans); 705 fail(); 706 } catch (IllegalArgumentException expected) { 707 } 708 709 // Error when there is no general plan 710 plans.clear(); 711 plans.add(SubscriptionPlan.Builder 712 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 713 Period.ofMonths(1)) 714 .setTitle("CTS") 715 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 716 .build()); 717 try { 718 mSm.setSubscriptionPlans(mSubId, plans); 719 fail(); 720 } catch (IllegalArgumentException expected) { 721 } 722 } 723 724 @Test testSubscriptionPlanResetNetworkTypes()725 public void testSubscriptionPlanResetNetworkTypes() { 726 long time = System.currentTimeMillis(); 727 SubscriptionPlan.Builder builder = SubscriptionPlan.Builder 728 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 729 Period.ofMonths(1)) 730 .setTitle("CTS") 731 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 732 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 733 .setDataUsage(500_000_000, time) 734 .resetNetworkTypes(); 735 736 if (Flags.subscriptionPlanAllowStatusAndEndDate()) { 737 builder.setSubscriptionStatus(SubscriptionPlan.SUBSCRIPTION_STATUS_ACTIVE); 738 } 739 740 SubscriptionPlan plan = builder.build(); 741 assertEquals(plan, buildValidSubscriptionPlan(time)); 742 } 743 744 @Test 745 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have MODIFY_PHONE_STATE permission") testSubscriptionGrouping()746 public void testSubscriptionGrouping() throws Exception { 747 // Set subscription group with current sub Id. This should fail 748 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 749 List<Integer> subGroup = new ArrayList(); 750 subGroup.add(mSubId); 751 try { 752 mSm.createSubscriptionGroup(subGroup); 753 fail(); 754 } catch (SecurityException expected) { 755 } 756 757 // Getting subscriptions in group should return null as setSubscriptionGroup 758 // should fail. 759 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 760 assertNull(info.getGroupUuid()); 761 762 // Remove from subscription group with current sub Id. This should fail 763 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 764 try { 765 mSm.addSubscriptionsIntoGroup(subGroup, null); 766 fail(); 767 } catch (NullPointerException expected) { 768 } 769 770 // Add into subscription group that doesn't exist. This should fail 771 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 772 try { 773 ParcelUuid groupUuid = new ParcelUuid(UUID.randomUUID()); 774 mSm.addSubscriptionsIntoGroup(subGroup, groupUuid); 775 fail(); 776 } catch (SecurityException expected) { 777 } 778 779 // Remove from subscription group with current sub Id. This should fail 780 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 781 try { 782 mSm.removeSubscriptionsFromGroup(subGroup, null); 783 fail(); 784 } catch (NullPointerException expected) { 785 } 786 } 787 788 @Test 789 @ApiTest(apis = "android.telephony.SubscriptionManager#getSubscriptionsInGroup") 790 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testSubscriptionGroupingWithPermission()791 public void testSubscriptionGroupingWithPermission() throws Exception { 792 // Set subscription group with current sub Id. 793 List<Integer> subGroup = new ArrayList(); 794 subGroup.add(mSubId); 795 ParcelUuid uuid = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 796 (sm) -> sm.createSubscriptionGroup(subGroup)); 797 798 // Getting subscriptions in group. 799 List<SubscriptionInfo> infoList; 800 try { 801 mSm.getSubscriptionsInGroup(uuid); 802 fail("SecurityException should be thrown without device identifiers"); 803 } catch (SecurityException ex) { 804 // Expected 805 } 806 807 // has the READ_PRIVILEGED_PHONE_STATE permission 808 setIdentifierAccess(true); 809 try { 810 infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 811 (sm) -> sm.getSubscriptionsInGroup(uuid), READ_PRIVILEGED_PHONE_STATE); 812 } finally { 813 setIdentifierAccess(false); 814 } 815 assertNotNull(infoList); 816 assertEquals(1, infoList.size()); 817 assertEquals(uuid, infoList.get(0).getGroupUuid()); 818 819 infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 820 (sm) -> sm.getSubscriptionsInGroup(uuid)); 821 assertNotNull(infoList); 822 assertEquals(1, infoList.size()); 823 assertEquals(uuid, infoList.get(0).getGroupUuid()); 824 825 List<SubscriptionInfo> availableInfoList; 826 try { 827 mSm.getAvailableSubscriptionInfoList(); 828 fail("SecurityException should be thrown without READ_PRIVILEGED_PHONE_STATE"); 829 } catch (SecurityException ex) { 830 // Ignore 831 } 832 availableInfoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 833 (sm) -> sm.getAvailableSubscriptionInfoList()); 834 // has the OPSTR_READ_DEVICE_IDENTIFIERS permission 835 setIdentifierAccess(true); 836 try { 837 if (availableInfoList.size() > 1) { 838 List<Integer> availableSubGroup = availableInfoList.stream() 839 .map(info -> info.getSubscriptionId()) 840 .filter(subId -> subId != mSubId) 841 .collect(Collectors.toList()); 842 843 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 844 (sm) -> sm.addSubscriptionsIntoGroup(availableSubGroup, uuid)); 845 846 infoList = mSm.getSubscriptionsInGroup(uuid); 847 assertNotNull(infoList); 848 assertEquals(availableInfoList.size(), infoList.size()); 849 850 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 851 (sm) -> sm.removeSubscriptionsFromGroup(availableSubGroup, uuid)); 852 } 853 854 // Remove from subscription group with current sub Id. 855 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 856 (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid)); 857 858 infoList = mSm.getSubscriptionsInGroup(uuid); 859 assertNotNull(infoList); 860 assertTrue(infoList.isEmpty()); 861 } finally { 862 setIdentifierAccess(false); 863 } 864 } 865 866 @Test 867 @ApiTest(apis = "android.telephony.SubscriptionManager#getSubscriptionsInGroup") 868 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testAddSubscriptionIntoNewGroupWithPermission()869 public void testAddSubscriptionIntoNewGroupWithPermission() throws Exception { 870 // Set subscription group with current sub Id. 871 List<Integer> subGroup = new ArrayList(); 872 subGroup.add(mSubId); 873 ParcelUuid uuid = new ParcelUuid(UUID.randomUUID()); 874 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 875 (sm) -> sm.addSubscriptionsIntoGroup(subGroup, uuid)); 876 877 List<SubscriptionInfo> infoList; 878 try { 879 mSm.getSubscriptionsInGroup(uuid); 880 fail("SecurityException should be thrown without device identifiers"); 881 } catch (SecurityException ex) { 882 // Expected 883 } 884 885 // Getting subscriptions in group. 886 try { 887 setIdentifierAccess(true); 888 infoList = mSm.getSubscriptionsInGroup(uuid); 889 assertNotNull(infoList); 890 assertEquals(1, infoList.size()); 891 assertEquals(uuid, infoList.get(0).getGroupUuid()); 892 893 // Remove from subscription group with current sub Id. 894 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 895 (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid)); 896 897 infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 898 (sm) -> sm.getSubscriptionsInGroup(uuid)); 899 assertNotNull(infoList); 900 assertTrue(infoList.isEmpty()); 901 } finally { 902 setIdentifierAccess(false); 903 } 904 } 905 906 @Test 907 @ApiTest(apis = "android.telephony.SubscriptionManager#setOpportunistic") 908 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have MODIFY_PHONE_STATE permissions") testSettingOpportunisticSubscription()909 public void testSettingOpportunisticSubscription() throws Exception { 910 // Set subscription to be opportunistic. This should fail 911 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 912 try { 913 mSm.setOpportunistic(true, mSubId); 914 fail(); 915 } catch (SecurityException expected) { 916 } 917 918 // Shouldn't crash. 919 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 920 info.isOpportunistic(); 921 } 922 923 @Test 924 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testMccMncString()925 public void testMccMncString() { 926 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 927 String mcc = info.getMccString(); 928 String mnc = info.getMncString(); 929 assertTrue(mcc == null || mcc.length() <= 3); 930 assertTrue(mnc == null || mnc.length() <= 3); 931 } 932 933 @Test 934 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testSetUiccApplicationsEnabled()935 public void testSetUiccApplicationsEnabled() throws Exception { 936 boolean canDisable = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 937 (sm) -> sm.canDisablePhysicalSubscription()); 938 if (canDisable) { 939 Object lock = new Object(); 940 AtomicBoolean functionCallCompleted = new AtomicBoolean(false); 941 // enabled starts off as true 942 AtomicBoolean valueToWaitFor = new AtomicBoolean(false); 943 TestThread t = new TestThread(new Runnable() { 944 @Override 945 public void run() { 946 Looper.prepare(); 947 948 SubscriptionManager.OnSubscriptionsChangedListener listener = 949 new SubscriptionManager.OnSubscriptionsChangedListener() { 950 @Override 951 public void onSubscriptionsChanged() { 952 if (valueToWaitFor.get() == mSm.getActiveSubscriptionInfo( 953 mSubId).areUiccApplicationsEnabled()) { 954 synchronized (lock) { 955 functionCallCompleted.set(true); 956 lock.notifyAll(); 957 } 958 } 959 } 960 }; 961 mSm.addOnSubscriptionsChangedListener(listener); 962 963 Looper.loop(); 964 } 965 }); 966 967 // Disable the UICC application and wait until we detect the subscription change to 968 // verify 969 t.start(); 970 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 971 (sm) -> sm.setUiccApplicationsEnabled(mSubId, false)); 972 973 synchronized (lock) { 974 if (!functionCallCompleted.get()) { 975 lock.wait(SUBSCRIPTION_DISABLE_WAIT_MS); 976 } 977 } 978 if (!functionCallCompleted.get()) { 979 fail("testSetUiccApplicationsEnabled was not able to disable the UICC app on time"); 980 } 981 982 // Enable the UICC application and wait again 983 functionCallCompleted.set(false); 984 valueToWaitFor.set(true); 985 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 986 (sm) -> sm.setUiccApplicationsEnabled(mSubId, true)); 987 988 synchronized (lock) { 989 if (!functionCallCompleted.get()) { 990 lock.wait(SUBSCRIPTION_ENABLE_WAIT_MS); 991 } 992 } 993 if (!functionCallCompleted.get()) { 994 fail("testSetUiccApplicationsEnabled was not able to enable to UICC app on time"); 995 } 996 997 // Reset default data and voice subId as it may have been changed as part of the 998 // calls above 999 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1000 (sm) -> sm.setDefaultDataSubId(mSubId)); 1001 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1002 (sm) -> sm.setDefaultVoiceSubscriptionId(mDefaultVoiceSubId)); 1003 1004 // Other tests also expect that cellular data must be available if telephony is 1005 // supported. Wait for that before returning. 1006 final CountDownLatch latch = waitForCellularNetwork(); 1007 latch.await(10, TimeUnit.SECONDS); 1008 } 1009 } 1010 1011 @Test 1012 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testSubscriptionInfoCarrierId()1013 public void testSubscriptionInfoCarrierId() { 1014 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 1015 int carrierId = info.getCarrierId(); 1016 assertTrue(carrierId >= TelephonyManager.UNKNOWN_CARRIER_ID); 1017 } 1018 1019 @Test testGetOpportunisticSubscriptions()1020 public void testGetOpportunisticSubscriptions() throws Exception { 1021 List<SubscriptionInfo> infoList = mSm.getOpportunisticSubscriptions(); 1022 1023 for (SubscriptionInfo info : infoList) { 1024 assertTrue(info.isOpportunistic()); 1025 } 1026 } 1027 1028 @Test testGetEnabledSubscriptionId()1029 public void testGetEnabledSubscriptionId() { 1030 int slotId = SubscriptionManager.getSlotIndex(mSubId); 1031 if (!SubscriptionManager.isValidSlotIndex(slotId)) { 1032 fail("Invalid slot id " + slotId + " for subscription id " + mSubId); 1033 } 1034 int enabledSubId = executeWithShellPermissionAndDefault(-1, mSm, 1035 (sm) -> sm.getEnabledSubscriptionId(slotId)); 1036 assertEquals(mSubId, enabledSubId); 1037 } 1038 1039 @Test testGetActiveDataSubscriptionId()1040 public void testGetActiveDataSubscriptionId() { 1041 int activeDataSubIdCurrent = executeWithShellPermissionAndDefault( 1042 SubscriptionManager.INVALID_SUBSCRIPTION_ID, mSm, 1043 (sm) -> sm.getActiveDataSubscriptionId()); 1044 1045 if (activeDataSubIdCurrent != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 1046 List<SubscriptionInfo> subscriptionInfos = mSm.getCompleteActiveSubscriptionInfoList(); 1047 boolean foundSub = subscriptionInfos.stream() 1048 .anyMatch(x -> x.getSubscriptionId() == activeDataSubIdCurrent); 1049 assertTrue(foundSub); 1050 } 1051 } 1052 1053 @Test testSetPreferredDataSubscriptionId()1054 public void testSetPreferredDataSubscriptionId() { 1055 int preferredSubId = executeWithShellPermissionAndDefault(-1, mSm, 1056 (sm) -> sm.getPreferredDataSubscriptionId()); 1057 if (preferredSubId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 1058 // Make sure to switch back to primary/default data sub first. 1059 setPreferredDataSubId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 1060 } 1061 1062 List<SubscriptionInfo> subscriptionInfos = mSm.getCompleteActiveSubscriptionInfoList(); 1063 1064 for (SubscriptionInfo subInfo : subscriptionInfos) { 1065 // Only test on opportunistic subscriptions. 1066 if (!subInfo.isOpportunistic()) continue; 1067 setPreferredDataSubId(subInfo.getSubscriptionId()); 1068 } 1069 1070 // Switch data back to previous preferredSubId. 1071 setPreferredDataSubId(preferredSubId); 1072 } 1073 1074 @Test 1075 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testRestoreAllSimSpecificSettingsFromBackup()1076 public void testRestoreAllSimSpecificSettingsFromBackup() throws Throwable { 1077 int activeDataSubId = SubscriptionManager.getActiveDataSubscriptionId(); 1078 assertNotEquals(activeDataSubId, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1079 SubscriptionInfo activeSubInfo = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1080 (sm) -> sm.getActiveSubscriptionInfo(activeDataSubId)); 1081 String isoCountryCode = activeSubInfo.getCountryIso(); 1082 1083 byte[] backupData = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1084 SubscriptionManager::getAllSimSpecificSettingsForBackup); 1085 assertTrue(backupData.length > 0); 1086 1087 PersistableBundle bundle = new PersistableBundle(); 1088 bundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true); 1089 bundle.putBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL, false); 1090 1091 final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager(); 1092 assumeTrue(pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)); 1093 1094 overrideCarrierConfig(bundle, activeDataSubId); 1095 try { 1096 // Get the original ims values. 1097 ImsManager imsManager = InstrumentationRegistry.getContext().getSystemService( 1098 ImsManager.class); 1099 ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(activeDataSubId); 1100 boolean isVolteVtEnabledOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 1101 mMmTelManager, ImsMmTelManager::isAdvancedCallingSettingEnabled); 1102 boolean isVtImsEnabledOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 1103 mMmTelManager, ImsMmTelManager::isVtSettingEnabled); 1104 boolean isVoWiFiSettingEnabledOriginal = 1105 ShellIdentityUtils.invokeMethodWithShellPermissions( 1106 mMmTelManager, ImsMmTelManager::isVoWiFiSettingEnabled); 1107 int voWifiModeOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 1108 mMmTelManager, ImsMmTelManager::getVoWiFiModeSetting); 1109 int voWiFiRoamingModeOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 1110 mMmTelManager, ImsMmTelManager::getVoWiFiRoamingModeSetting); 1111 1112 // Get the original RcsUce values. 1113 ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(activeDataSubId); 1114 RcsUceAdapter rcsUceAdapter = imsRcsManager.getUceAdapter(); 1115 boolean isImsRcsUceEnabledOriginal = 1116 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 1117 rcsUceAdapter, RcsUceAdapter::isUceSettingEnabled, ImsException.class, 1118 android.Manifest.permission.READ_PHONE_STATE); 1119 1120 //Change values in DB. 1121 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 1122 (m) -> m.setAdvancedCallingSettingEnabled(!isVolteVtEnabledOriginal)); 1123 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 1124 (m) -> m.setVtSettingEnabled(!isVtImsEnabledOriginal)); 1125 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn( 1126 rcsUceAdapter, (a) -> a.setUceSettingEnabled(!isImsRcsUceEnabledOriginal), 1127 ImsException.class); 1128 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 1129 (m) -> m.setVoWiFiSettingEnabled(!isVoWiFiSettingEnabledOriginal)); 1130 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 1131 (m) -> m.setVoWiFiModeSetting((voWifiModeOriginal + 1) % 3)); 1132 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 1133 (m) -> m.setVoWiFiRoamingModeSetting((voWiFiRoamingModeOriginal + 1) % 3)); 1134 1135 // Restore back to original values. 1136 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1137 (sm) -> sm.restoreAllSimSpecificSettingsFromBackup(backupData)); 1138 1139 final long maxWaitMillis = 5000; 1140 try { 1141 waitForSubscriptionCondition( 1142 () -> isVolteVtEnabledOriginal == isAdvancedCallingSettingEnabled(mSubId), 1143 maxWaitMillis); 1144 assertEquals(isVolteVtEnabledOriginal, isAdvancedCallingSettingEnabled(mSubId)); 1145 } finally { 1146 overrideCarrierConfig(null, mSubId); 1147 } 1148 1149 // Get ims values to verify with. 1150 boolean isVolteVtEnabledAfterRestore = 1151 ShellIdentityUtils.invokeMethodWithShellPermissions( 1152 mMmTelManager, ImsMmTelManager::isAdvancedCallingSettingEnabled); 1153 boolean isVtImsEnabledAfterRestore = 1154 ShellIdentityUtils.invokeMethodWithShellPermissions( 1155 mMmTelManager, ImsMmTelManager::isVtSettingEnabled); 1156 boolean isVoWiFiSettingEnabledAfterRestore = 1157 ShellIdentityUtils.invokeMethodWithShellPermissions( 1158 mMmTelManager, ImsMmTelManager::isVoWiFiSettingEnabled); 1159 int voWifiModeAfterRestore = ShellIdentityUtils.invokeMethodWithShellPermissions( 1160 mMmTelManager, ImsMmTelManager::getVoWiFiModeSetting); 1161 int voWiFiRoamingModeAfterRestore = ShellIdentityUtils.invokeMethodWithShellPermissions( 1162 mMmTelManager, ImsMmTelManager::getVoWiFiRoamingModeSetting); 1163 // Get RcsUce values to verify with. 1164 boolean isImsRcsUceEnabledAfterRestore = 1165 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 1166 rcsUceAdapter, RcsUceAdapter::isUceSettingEnabled, ImsException.class, 1167 android.Manifest.permission.READ_PHONE_STATE); 1168 1169 assertEquals(isVolteVtEnabledOriginal, isVolteVtEnabledAfterRestore); 1170 if (isoCountryCode == null 1171 || isoCountryCode.equals("us") 1172 || isoCountryCode.equals("ca")) { 1173 assertEquals(!isVoWiFiSettingEnabledOriginal, isVoWiFiSettingEnabledAfterRestore); 1174 } else { 1175 assertEquals(isVoWiFiSettingEnabledOriginal, isVoWiFiSettingEnabledAfterRestore); 1176 } 1177 assertEquals(voWifiModeOriginal, voWifiModeAfterRestore); 1178 assertEquals(voWiFiRoamingModeOriginal, voWiFiRoamingModeAfterRestore); 1179 assertEquals(isVtImsEnabledOriginal, isVtImsEnabledAfterRestore); 1180 assertEquals(isImsRcsUceEnabledOriginal, isImsRcsUceEnabledAfterRestore); 1181 } finally { 1182 // restore original carrier config. 1183 overrideCarrierConfig(null, activeDataSubId); 1184 } 1185 1186 1187 try { 1188 // Check api call will fail without proper permissions. 1189 mSm.restoreAllSimSpecificSettingsFromBackup(backupData); 1190 fail("SecurityException expected"); 1191 } catch (SecurityException e) { 1192 // expected 1193 } 1194 } 1195 1196 @Test 1197 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testSetAndGetD2DStatusSharing()1198 public void testSetAndGetD2DStatusSharing() { 1199 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 1200 uiAutomation.adoptShellPermissionIdentity(MODIFY_PHONE_STATE); 1201 try { 1202 int originalD2DStatusSharing = mSm.getDeviceToDeviceStatusSharingPreference(mSubId); 1203 mSm.setDeviceToDeviceStatusSharingPreference(mSubId, 1204 SubscriptionManager.D2D_SHARING_ALL_CONTACTS); 1205 assertEquals(SubscriptionManager.D2D_SHARING_ALL_CONTACTS, 1206 mSm.getDeviceToDeviceStatusSharingPreference(mSubId)); 1207 mSm.setDeviceToDeviceStatusSharingPreference( 1208 mSubId, SubscriptionManager.D2D_SHARING_ALL); 1209 assertEquals(SubscriptionManager.D2D_SHARING_ALL, 1210 mSm.getDeviceToDeviceStatusSharingPreference(mSubId)); 1211 mSm.setDeviceToDeviceStatusSharingPreference(mSubId, originalD2DStatusSharing); 1212 } finally { 1213 uiAutomation.dropShellPermissionIdentity(); 1214 } 1215 } 1216 1217 @Test 1218 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testSetAndGetD2DSharingContacts()1219 public void testSetAndGetD2DSharingContacts() { 1220 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 1221 uiAutomation.adoptShellPermissionIdentity(MODIFY_PHONE_STATE); 1222 try { 1223 List<Uri> originalD2DSharingContacts = 1224 mSm.getDeviceToDeviceStatusSharingContacts(mSubId); 1225 mSm.setDeviceToDeviceStatusSharingContacts(mSubId, CONTACTS); 1226 try { 1227 assertEquals(CONTACTS, mSm.getDeviceToDeviceStatusSharingContacts(mSubId)); 1228 } finally { 1229 mSm.setDeviceToDeviceStatusSharingContacts(mSubId, originalD2DSharingContacts); 1230 } 1231 } finally { 1232 uiAutomation.dropShellPermissionIdentity(); 1233 } 1234 } 1235 1236 @Test 1237 @AppModeNonSdkSandbox( 1238 reason = "SDK sandboxes do not have READ_PRIVILEGED_PHONE_STATE permission") tetsSetAndGetPhoneNumber()1239 public void tetsSetAndGetPhoneNumber() throws Exception { 1240 // The phone number may be anything depends on the state of SIM and device. 1241 // Simply call the getter and make sure no exception. 1242 1243 // Getters accessiable with READ_PRIVILEGED_PHONE_STATE 1244 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1245 .adoptShellPermissionIdentity(READ_PRIVILEGED_PHONE_STATE); 1246 try { 1247 mSm.getPhoneNumber(mSubId); 1248 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_UICC); 1249 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER); 1250 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_IMS); 1251 } finally { 1252 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1253 .dropShellPermissionIdentity(); 1254 } 1255 1256 // Getters accessiable with READ_PHONE_NUMBERS 1257 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1258 .adoptShellPermissionIdentity(android.Manifest.permission.READ_PHONE_NUMBERS); 1259 try { 1260 mSm.getPhoneNumber(mSubId); 1261 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_UICC); 1262 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER); 1263 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_IMS); 1264 } finally { 1265 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1266 .dropShellPermissionIdentity(); 1267 } 1268 1269 // Getters and the setter accessiable with carrier privilege 1270 final String carrierNumber = "1234567890"; 1271 CarrierPrivilegeUtils.withCarrierPrivileges( 1272 InstrumentationRegistry.getContext(), 1273 mSubId, 1274 () -> { 1275 mSm.getPhoneNumber(mSubId); 1276 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_UICC); 1277 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_IMS); 1278 1279 mSm.setCarrierPhoneNumber(mSubId, carrierNumber); 1280 assertEquals( 1281 carrierNumber, 1282 mSm.getPhoneNumber( 1283 mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER)); 1284 }); 1285 1286 // Otherwise, getter and setter will hit SecurityException 1287 try { 1288 mSm.getPhoneNumber(mSubId); 1289 fail("Expect SecurityException from getPhoneNumber()"); 1290 } catch (SecurityException e) { 1291 // expected 1292 } 1293 try { 1294 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_UICC); 1295 fail("Expect SecurityException from getPhoneNumber()"); 1296 } catch (SecurityException e) { 1297 // expected 1298 } 1299 try { 1300 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_IMS); 1301 fail("Expect SecurityException from getPhoneNumber()"); 1302 } catch (SecurityException e) { 1303 // expected 1304 } 1305 try { 1306 mSm.getPhoneNumber(mSubId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER); 1307 fail("Expect SecurityException from getPhoneNumber()"); 1308 } catch (SecurityException e) { 1309 // expected 1310 } 1311 try { 1312 mSm.setCarrierPhoneNumber(mSubId, "987"); 1313 fail("Expect SecurityException from setCarrierPhoneNumber()"); 1314 } catch (SecurityException e) { 1315 // expected 1316 } 1317 } 1318 getSupportedUsageSettings()1319 private Set<Integer> getSupportedUsageSettings() throws Exception { 1320 final Set<Integer> supportedUsageSettings = new HashSet(); 1321 final Context context = InstrumentationRegistry.getContext(); 1322 1323 // Vendors can add supported usage settings by adding resources. 1324 try { 1325 int[] usageSettingsFromResource = 1326 context.getResources() 1327 .getIntArray( 1328 Resources.getSystem() 1329 .getIdentifier( 1330 "config_supported_cellular_usage_settings", 1331 "array", 1332 "android")); 1333 1334 for (int setting : usageSettingsFromResource) { 1335 supportedUsageSettings.add(setting); 1336 } 1337 1338 } catch (Resources.NotFoundException ignore) { 1339 } 1340 1341 // For devices shipping with Radio HAL 2.0 and/or non-HAL devices launching with T, 1342 // the usage settings are required to be supported if the rest of the telephony stack 1343 // has support for that mode of operation. 1344 if (PropertyUtil.isVendorApiLevelAtLeast(android.os.Build.VERSION_CODES.TIRAMISU)) { 1345 final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager(); 1346 1347 if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_DATA)) { 1348 supportedUsageSettings.add(SubscriptionManager.USAGE_SETTING_DATA_CENTRIC); 1349 } 1350 if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING)) { 1351 supportedUsageSettings.add(SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC); 1352 } 1353 } 1354 1355 return supportedUsageSettings; 1356 } 1357 getUsageSetting()1358 private int getUsageSetting() throws Exception { 1359 SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1360 (sm) -> sm.getActiveSubscriptionInfo(mSubId)); 1361 return info.getUsageSetting(); 1362 } 1363 checkUsageSetting(int inputSetting, boolean isSupported)1364 private void checkUsageSetting(int inputSetting, boolean isSupported) throws Exception { 1365 final int initialSetting = getUsageSetting(); 1366 1367 PersistableBundle bundle = new PersistableBundle(); 1368 bundle.putInt(CarrierConfigManager.KEY_CELLULAR_USAGE_SETTING_INT, inputSetting); 1369 overrideCarrierConfig(bundle, mSubId); 1370 1371 final int newSetting = getUsageSetting(); 1372 assertEquals(isSupported ? inputSetting : initialSetting, newSetting); 1373 } 1374 1375 @Test testCellularUsageSetting()1376 public void testCellularUsageSetting() throws Exception { 1377 Set<Integer> supportedUsageSettings = getSupportedUsageSettings(); 1378 1379 // If any setting works, default must be allowed. 1380 if (supportedUsageSettings.size() > 0) { 1381 supportedUsageSettings.add(SubscriptionManager.USAGE_SETTING_DEFAULT); 1382 } 1383 1384 final int[] allUsageSettings = new int[]{ 1385 SubscriptionManager.USAGE_SETTING_UNKNOWN, 1386 SubscriptionManager.USAGE_SETTING_DEFAULT, 1387 SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC, 1388 SubscriptionManager.USAGE_SETTING_DATA_CENTRIC, 1389 3 /* undefined value */}; 1390 1391 try { 1392 for (int setting : allUsageSettings) { 1393 checkUsageSetting(setting, supportedUsageSettings.contains(setting)); 1394 } 1395 } finally { 1396 overrideCarrierConfig(null, mSubId); 1397 } 1398 } 1399 1400 @Test testCreateSubscriptionChangedListenerWithoutLooper()1401 public void testCreateSubscriptionChangedListenerWithoutLooper() throws Throwable { 1402 CompletableFuture<Throwable> futureResult = new CompletableFuture<>(); 1403 1404 Thread t = new Thread(() -> { 1405 SubscriptionManager.OnSubscriptionsChangedListener oscl = 1406 new SubscriptionManager.OnSubscriptionsChangedListener(); 1407 try { 1408 mSm.addOnSubscriptionsChangedListener((r) -> {}, oscl); 1409 mSm.removeOnSubscriptionsChangedListener(oscl); 1410 futureResult.complete(null); 1411 } catch (Exception e) { 1412 futureResult.complete(e); 1413 try { 1414 mSm.removeOnSubscriptionsChangedListener(oscl); 1415 } catch (Exception likely) { 1416 // nothing to do 1417 } 1418 } 1419 1420 try { 1421 mSm.addOnSubscriptionsChangedListener(oscl); 1422 futureResult.complete( 1423 new Exception("Looper wasn't required as expected")); 1424 } catch (Exception expected) { 1425 futureResult.complete(null); 1426 } finally { 1427 mSm.removeOnSubscriptionsChangedListener(oscl); 1428 } 1429 }); 1430 1431 t.start(); 1432 t.join(5000 /*millis*/); 1433 1434 if (futureResult.get() != null) throw futureResult.get(); 1435 } 1436 getSubscriptionIso(int subId)1437 private String getSubscriptionIso(int subId) { 1438 SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1439 (sm) -> sm.getActiveSubscriptionInfo(subId)); 1440 return info.getCountryIso(); 1441 } 1442 isAdvancedCallingSettingEnabled(int subId)1443 private boolean isAdvancedCallingSettingEnabled(int subId) { 1444 ImsManager imsManager = InstrumentationRegistry.getContext().getSystemService( 1445 ImsManager.class); 1446 ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(subId); 1447 return ShellIdentityUtils.invokeMethodWithShellPermissions( 1448 mMmTelManager, ImsMmTelManager::isAdvancedCallingSettingEnabled); 1449 } 1450 1451 /** 1452 * Monitor the onSubscriptionsChangedListener until a condition is satisfied. 1453 */ waitForSubscriptionCondition( BooleanSupplier condition, long maxWaitMillis)1454 private void waitForSubscriptionCondition( 1455 BooleanSupplier condition, long maxWaitMillis) throws Throwable { 1456 final Object lock = new Object(); 1457 1458 TestThread t = new TestThread(() -> { 1459 Looper.prepare(); 1460 1461 SubscriptionManager.OnSubscriptionsChangedListener listener = 1462 new SubscriptionManager.OnSubscriptionsChangedListener() { 1463 @Override 1464 public void onSubscriptionsChanged() { 1465 synchronized (lock) { 1466 if (condition.getAsBoolean()) { 1467 lock.notifyAll(); 1468 Looper.myLooper().quitSafely(); 1469 } 1470 } 1471 } 1472 }; 1473 mSm.addOnSubscriptionsChangedListener(listener); 1474 try { 1475 synchronized (lock) { 1476 if (condition.getAsBoolean()) lock.notifyAll(); 1477 } 1478 if (!condition.getAsBoolean()) Looper.loop(); 1479 } finally { 1480 mSm.removeOnSubscriptionsChangedListener(listener); 1481 } 1482 }); 1483 1484 synchronized (lock) { 1485 if (condition.getAsBoolean()) return; 1486 t.start(); 1487 lock.wait(maxWaitMillis); 1488 t.joinAndCheck(5000); 1489 } 1490 } 1491 1492 @Test 1493 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testCountryIso()1494 public void testCountryIso() throws Throwable { 1495 final String liechtensteinIso = "li"; 1496 final String faroeIslandsIso = "fo"; 1497 1498 final TelephonyManager tm = InstrumentationRegistry.getContext() 1499 .getSystemService(TelephonyManager.class).createForSubscriptionId(mSubId); 1500 1501 final long maxWaitMillis = 5000; 1502 final String isoUT = liechtensteinIso.equals(getSubscriptionIso(mSubId)) 1503 ? faroeIslandsIso : liechtensteinIso; 1504 1505 PersistableBundle bundle = new PersistableBundle(); 1506 bundle.putString(CarrierConfigManager.KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING, isoUT); 1507 overrideCarrierConfig(bundle, mSubId); 1508 try { 1509 waitForSubscriptionCondition( 1510 () -> isoUT.equals(getSubscriptionIso(mSubId)), 1511 maxWaitMillis); 1512 1513 assertEquals(isoUT, getSubscriptionIso(mSubId)); 1514 assertEquals(isoUT, tm.getSimCountryIso()); 1515 } finally { 1516 overrideCarrierConfig(null, mSubId); 1517 } 1518 } 1519 1520 @Test 1521 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testIsNtn_enableFlag()1522 public void testIsNtn_enableFlag() throws Exception { 1523 if (!InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature( 1524 PackageManager.FEATURE_TELEPHONY_SATELLITE)) { 1525 return; 1526 } 1527 SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1528 (sm) -> sm.getActiveSubscriptionInfo(mSubId)); 1529 boolean unused = info.isOnlyNonTerrestrialNetwork(); 1530 } 1531 1532 @Test 1533 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testIsNtn_disableFlag()1534 public void testIsNtn_disableFlag() throws Exception { 1535 if (!InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature( 1536 PackageManager.FEATURE_TELEPHONY_SATELLITE)) { 1537 return; 1538 } 1539 SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1540 (sm) -> sm.getActiveSubscriptionInfo(mSubId)); 1541 assertThat(info.isOnlyNonTerrestrialNetwork()).isFalse(); 1542 } 1543 1544 @Test 1545 @ApiTest(apis = {"android.telephony.SubscriptionInfo#getServiceCapabilities"}) testSubscriptionInfo_getServiceCapabilities()1546 public void testSubscriptionInfo_getServiceCapabilities() throws Exception { 1547 final List<SubscriptionInfo> allSubInfos = 1548 ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1549 (sm) -> sm.getAllSubscriptionInfoList()); 1550 for (SubscriptionInfo subInfo : allSubInfos) { 1551 final Set<Integer> capabilities = subInfo.getServiceCapabilities(); 1552 1553 assertThat(capabilities).isNotNull(); 1554 for (int capability : capabilities) { 1555 assertTrue(isValidServiceCapability(capability)); 1556 } 1557 } 1558 } 1559 1560 @Test 1561 @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION) 1562 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have READ_PHONE_STATE permission") testUpdateSubscription_transferStatus()1563 public void testUpdateSubscription_transferStatus() throws Exception { 1564 // Testing permission fail 1565 try { 1566 mSm.setTransferStatus(mSubId, TRANSFER_STATUS_TRANSFERRED_OUT); 1567 } catch (SecurityException expected) { 1568 fail(); 1569 } 1570 1571 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1572 (sm) -> sm.setTransferStatus(mSubId, TRANSFER_STATUS_TRANSFERRED_OUT)); 1573 SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1574 (sm) -> sm.getActiveSubscriptionInfo(mSubId)); 1575 assertEquals(info.getTransferStatus(), TRANSFER_STATUS_TRANSFERRED_OUT); 1576 } 1577 1578 @Test 1579 @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have the required permissions") testIsSubscriptionAssociatedWithUser()1580 public void testIsSubscriptionAssociatedWithUser() throws Exception { 1581 1582 UserHandle oldAssociatedUser = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1583 (sm) -> sm.getSubscriptionUserHandle(mSubId)); 1584 1585 // Testing with the current context user. 1586 UserHandle currentUserHandle = InstrumentationRegistry.getContext().getUser(); 1587 1588 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1589 (sm) -> sm.setSubscriptionUserHandle(mSubId, currentUserHandle)); 1590 1591 assertTrue(ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1592 (sm) -> sm.isSubscriptionAssociatedWithUser(mSubId))); 1593 1594 // Testing with any random user which is not the current context user. 1595 UserHandle nonCurrentUserHandle = UserHandle.of(currentUserHandle.getIdentifier() + 1); 1596 1597 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1598 (sm) -> sm.setSubscriptionUserHandle(mSubId, nonCurrentUserHandle)); 1599 1600 assertFalse(ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 1601 (sm) -> sm.isSubscriptionAssociatedWithUser(mSubId))); 1602 1603 // Resetting it to the state before test. 1604 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1605 (sm) -> sm.setSubscriptionUserHandle(mSubId, oldAssociatedUser)); 1606 1607 } 1608 isValidServiceCapability(int capability)1609 private boolean isValidServiceCapability(int capability) { 1610 return capability >= SubscriptionManager.SERVICE_CAPABILITY_VOICE 1611 && capability <= SubscriptionManager.SERVICE_CAPABILITY_MAX; 1612 } 1613 1614 @Nullable getBundleFromBackupData(byte[] data)1615 private PersistableBundle getBundleFromBackupData(byte[] data) { 1616 try (ByteArrayInputStream bis = new ByteArrayInputStream(data)) { 1617 return PersistableBundle.readFromStream(bis); 1618 } catch (IOException e) { 1619 return null; 1620 } 1621 } 1622 setPreferredDataSubId(int subId)1623 private void setPreferredDataSubId(int subId) { 1624 final LinkedBlockingQueue<Integer> resultQueue = new LinkedBlockingQueue<>(1); 1625 Executor executor = (command)-> command.run(); 1626 Consumer<Integer> consumer = (res)-> { 1627 if (res == null) { 1628 resultQueue.offer(-1); 1629 } else { 1630 resultQueue.offer(res); 1631 } 1632 }; 1633 1634 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1635 (sm) -> sm.setPreferredDataSubscriptionId(subId, false, 1636 executor, consumer)); 1637 int res = -1; 1638 try { 1639 res = resultQueue.poll(2, TimeUnit.SECONDS); 1640 } catch (InterruptedException e) { 1641 fail("Cannot get the modem result in time"); 1642 } 1643 1644 assertEquals(SET_OPPORTUNISTIC_SUB_SUCCESS, res); 1645 int getValue = executeWithShellPermissionAndDefault(-1, mSm, 1646 (sm) -> sm.getPreferredDataSubscriptionId()); 1647 assertEquals(subId, getValue); 1648 } 1649 executeWithShellPermissionAndDefault(T defaultValue, U targetObject, ShellIdentityUtils.ShellPermissionMethodHelper<T, U> helper)1650 private <T, U> T executeWithShellPermissionAndDefault(T defaultValue, U targetObject, 1651 ShellIdentityUtils.ShellPermissionMethodHelper<T, U> helper) { 1652 try { 1653 return ShellIdentityUtils.invokeMethodWithShellPermissions(targetObject, helper); 1654 } catch (Exception e) { 1655 // do nothing, return default 1656 } 1657 return defaultValue; 1658 } 1659 assertOverrideSuccess(SubscriptionPlan... plans)1660 private void assertOverrideSuccess(SubscriptionPlan... plans) { 1661 mSm.setSubscriptionPlans(mSubId, Arrays.asList(plans)); 1662 mSm.setSubscriptionOverrideCongested(mSubId, false, 0); 1663 } 1664 assertOverrideFails(SubscriptionPlan... plans)1665 private void assertOverrideFails(SubscriptionPlan... plans) { 1666 mSm.setSubscriptionPlans(mSubId, Arrays.asList(plans)); 1667 try { 1668 mSm.setSubscriptionOverrideCongested(mSubId, false, 0); 1669 fail(); 1670 } catch (SecurityException | IllegalStateException expected) { 1671 } 1672 } 1673 waitForNetworkCapabilities(Network network, Predicate<NetworkCapabilities> predicate)1674 public static CountDownLatch waitForNetworkCapabilities(Network network, 1675 Predicate<NetworkCapabilities> predicate) { 1676 final CountDownLatch latch = new CountDownLatch(1); 1677 final ConnectivityManager cm = InstrumentationRegistry.getContext() 1678 .getSystemService(ConnectivityManager.class); 1679 cm.registerNetworkCallback(new NetworkRequest.Builder().build(), 1680 new NetworkCallback() { 1681 @Override 1682 public void onCapabilitiesChanged(Network net, NetworkCapabilities caps) { 1683 if (net.equals(network) && predicate.test(caps)) { 1684 latch.countDown(); 1685 cm.unregisterNetworkCallback(this); 1686 } 1687 } 1688 }); 1689 return latch; 1690 } 1691 1692 /** 1693 * Corresponding to findCellularNetwork() 1694 */ waitForCellularNetwork()1695 private static CountDownLatch waitForCellularNetwork() { 1696 final CountDownLatch latch = new CountDownLatch(1); 1697 final ConnectivityManager cm = InstrumentationRegistry.getContext() 1698 .getSystemService(ConnectivityManager.class); 1699 cm.registerNetworkCallback(new NetworkRequest.Builder().build(), 1700 new NetworkCallback() { 1701 @Override 1702 public void onCapabilitiesChanged(Network net, NetworkCapabilities caps) { 1703 if (caps.hasTransport(TRANSPORT_CELLULAR) 1704 && caps.hasCapability(NET_CAPABILITY_INTERNET) 1705 && caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 1706 latch.countDown(); 1707 cm.unregisterNetworkCallback(this); 1708 } 1709 } 1710 }); 1711 return latch; 1712 } 1713 buildValidSubscriptionPlan(long dataUsageTime)1714 private static SubscriptionPlan buildValidSubscriptionPlan(long dataUsageTime) { 1715 return buildValidSubscriptionPlanRecurring( 1716 dataUsageTime, ZonedDateTime.parse("2007-03-14T00:00:00.000Z")); 1717 } 1718 buildValidSubscriptionPlanRecurring( long dataUsageTime, ZonedDateTime start)1719 private static SubscriptionPlan buildValidSubscriptionPlanRecurring( 1720 long dataUsageTime, ZonedDateTime start) { 1721 return buildValidSubscriptionPlanCommon( 1722 SubscriptionPlan.Builder.createRecurring(start, Period.ofMonths(1)), dataUsageTime); 1723 } 1724 buildValidSubscriptionPlanNonRecurring( long dataUsageTime, ZonedDateTime start, ZonedDateTime end)1725 private static SubscriptionPlan buildValidSubscriptionPlanNonRecurring( 1726 long dataUsageTime, ZonedDateTime start, ZonedDateTime end) { 1727 return buildValidSubscriptionPlanCommon( 1728 SubscriptionPlan.Builder.createNonrecurring(start, end), dataUsageTime); 1729 } 1730 buildValidSubscriptionPlanCommon( SubscriptionPlan.Builder builder, long dataUsageTime)1731 private static SubscriptionPlan buildValidSubscriptionPlanCommon( 1732 SubscriptionPlan.Builder builder, long dataUsageTime) { 1733 builder.setTitle("CTS") 1734 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 1735 .setDataUsage(500_000_000, dataUsageTime); 1736 1737 if (Flags.subscriptionPlanAllowStatusAndEndDate()) { 1738 builder.setSubscriptionStatus(SubscriptionPlan.SUBSCRIPTION_STATUS_ACTIVE); 1739 } 1740 1741 return builder.build(); 1742 } 1743 findCellularNetwork()1744 private static @Nullable Network findCellularNetwork() { 1745 final ConnectivityManager cm = InstrumentationRegistry.getContext() 1746 .getSystemService(ConnectivityManager.class); 1747 for (Network net : cm.getAllNetworks()) { 1748 final NetworkCapabilities caps = cm.getNetworkCapabilities(net); 1749 if (caps != null && caps.hasTransport(TRANSPORT_CELLULAR) 1750 && caps.hasCapability(NET_CAPABILITY_INTERNET) 1751 && caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 1752 return net; 1753 } 1754 } 1755 return null; 1756 } 1757 isSupported()1758 private static boolean isSupported() { 1759 return InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature( 1760 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION); 1761 } 1762 isAutomotive()1763 private static boolean isAutomotive() { 1764 return InstrumentationRegistry.getContext().getPackageManager() 1765 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 1766 } 1767 isDSDS()1768 private static boolean isDSDS() { 1769 TelephonyManager tm = InstrumentationRegistry.getContext() 1770 .getSystemService(TelephonyManager.class); 1771 return tm != null && tm.getPhoneCount() > 1; 1772 } 1773 setSubPlanOwner(int subId, String packageName)1774 private static void setSubPlanOwner(int subId, String packageName) throws Exception { 1775 SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), 1776 "cmd netpolicy set sub-plan-owner " + subId + " " + packageName); 1777 } 1778 isUnmetered5GSupported()1779 private boolean isUnmetered5GSupported() { 1780 final CarrierConfigManager ccm = InstrumentationRegistry.getContext() 1781 .getSystemService(CarrierConfigManager.class); 1782 PersistableBundle carrierConfig = ccm.getConfigForSubId(mSubId); 1783 1784 final TelephonyManager tm = InstrumentationRegistry.getContext() 1785 .getSystemService(TelephonyManager.class); 1786 1787 int dataNetworkType; 1788 if (InstrumentationRegistry.getContext() 1789 .getPackageManager() 1790 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)) { 1791 dataNetworkType = tm.getDataNetworkType(mSubId); 1792 } else { 1793 dataNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 1794 } 1795 long supportedRats = ShellIdentityUtils.invokeMethodWithShellPermissions(tm, 1796 TelephonyManager::getSupportedRadioAccessFamily); 1797 1798 boolean validCarrier = carrierConfig.getBoolean( 1799 CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL); 1800 boolean validCapabilities = (supportedRats & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0; 1801 // TODO: need to check for TelephonyDisplayInfo override for NR NSA 1802 boolean validNetworkType = dataNetworkType == TelephonyManager.NETWORK_TYPE_NR; 1803 1804 return validCarrier && validNetworkType && validCapabilities; 1805 } 1806 setIdentifierAccess(boolean allowed)1807 private void setIdentifierAccess(boolean allowed) { 1808 CountDownLatch changeLatch = new CountDownLatch(1); 1809 String op = AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS; 1810 AppOpsManager appOpsManager = InstrumentationRegistry.getContext().getSystemService( 1811 AppOpsManager.class); 1812 int mode = allowed ? AppOpsManager.MODE_ALLOWED : AppOpsManager.opToDefaultMode(op); 1813 if (appOpsManager.unsafeCheckOpNoThrow(op, Process.myUid(), 1814 InstrumentationRegistry.getContext().getOpPackageName()) == mode) { 1815 return; 1816 } 1817 AppOpsManager.OnOpChangedListener opListener = 1818 (String appOp, String packageName) -> changeLatch.countDown(); 1819 appOpsManager.startWatchingMode(op, InstrumentationRegistry.getContext().getOpPackageName(), 1820 opListener); 1821 try { 1822 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn( 1823 appOpsManager, (appOps) -> appOps.setUidMode(op, Process.myUid(), mode)); 1824 changeLatch.await(5000, TimeUnit.MILLISECONDS); 1825 } catch (InterruptedException ie) { 1826 fail("Never received appOp change for Identifier Access"); 1827 } finally { 1828 appOpsManager.stopWatchingMode(opListener); 1829 } 1830 } 1831 } 1832