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