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.TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertFalse; 28 import static org.junit.Assert.assertNotEquals; 29 import static org.junit.Assert.assertNotNull; 30 import static org.junit.Assert.assertNull; 31 import static org.junit.Assert.assertTrue; 32 import static org.junit.Assert.fail; 33 34 import android.annotation.Nullable; 35 import android.app.UiAutomation; 36 import android.content.pm.PackageManager; 37 import android.content.res.Resources; 38 import android.net.ConnectivityManager; 39 import android.net.ConnectivityManager.NetworkCallback; 40 import android.net.Network; 41 import android.net.NetworkCapabilities; 42 import android.net.NetworkRequest; 43 import android.net.Uri; 44 import android.os.Looper; 45 import android.os.ParcelUuid; 46 import android.os.PersistableBundle; 47 import android.telephony.CarrierConfigManager; 48 import android.telephony.SubscriptionInfo; 49 import android.telephony.SubscriptionManager; 50 import android.telephony.SubscriptionPlan; 51 import android.telephony.TelephonyManager; 52 import android.telephony.ims.ImsException; 53 import android.telephony.ims.ImsManager; 54 import android.telephony.ims.ImsMmTelManager; 55 import android.telephony.ims.ImsRcsManager; 56 import android.telephony.ims.RcsUceAdapter; 57 import android.util.Log; 58 59 import androidx.test.InstrumentationRegistry; 60 61 import com.android.compatibility.common.util.ShellIdentityUtils; 62 import com.android.compatibility.common.util.SystemUtil; 63 import com.android.compatibility.common.util.TestThread; 64 import com.android.internal.util.ArrayUtils; 65 66 import org.junit.AfterClass; 67 import org.junit.Before; 68 import org.junit.BeforeClass; 69 import org.junit.Test; 70 71 import java.io.ByteArrayInputStream; 72 import java.io.IOException; 73 import java.time.Period; 74 import java.time.ZonedDateTime; 75 import java.util.ArrayList; 76 import java.util.Arrays; 77 import java.util.List; 78 import java.util.UUID; 79 import java.util.concurrent.CountDownLatch; 80 import java.util.concurrent.Executor; 81 import java.util.concurrent.LinkedBlockingQueue; 82 import java.util.concurrent.TimeUnit; 83 import java.util.concurrent.atomic.AtomicBoolean; 84 import java.util.function.Consumer; 85 import java.util.function.Predicate; 86 import java.util.stream.Collectors; 87 88 89 public class SubscriptionManagerTest { 90 private static final String TAG = "SubscriptionManagerTest"; 91 private static final String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE"; 92 private SubscriptionManager mSm; 93 private static final List<Uri> CONTACTS = new ArrayList<>(); 94 static { 95 CONTACTS.add(Uri.fromParts("tel", "+16505551212", null)); 96 CONTACTS.add(Uri.fromParts("tel", "+16505552323", null)); 97 } 98 99 private int mSubId; 100 private String mPackageName; 101 102 /** 103 * Callback used in testRegisterNetworkCallback that allows caller to block on 104 * {@code onAvailable}. 105 */ 106 private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { 107 private final CountDownLatch mAvailableLatch = new CountDownLatch(1); 108 waitForAvailable()109 public void waitForAvailable() throws InterruptedException { 110 assertTrue("Cellular network did not come up after 5 seconds", 111 mAvailableLatch.await(5, TimeUnit.SECONDS)); 112 } 113 114 @Override onAvailable(Network network)115 public void onAvailable(Network network) { 116 mAvailableLatch.countDown(); 117 } 118 } 119 120 @BeforeClass setUpClass()121 public static void setUpClass() throws Exception { 122 if (!isSupported()) return; 123 124 final TestNetworkCallback callback = new TestNetworkCallback(); 125 final ConnectivityManager cm = InstrumentationRegistry.getContext() 126 .getSystemService(ConnectivityManager.class); 127 cm.registerNetworkCallback(new NetworkRequest.Builder() 128 .addTransportType(TRANSPORT_CELLULAR) 129 .addCapability(NET_CAPABILITY_INTERNET) 130 .build(), callback); 131 try { 132 // Wait to get callback for availability of internet 133 callback.waitForAvailable(); 134 } catch (InterruptedException e) { 135 fail("NetworkCallback wait was interrupted."); 136 } finally { 137 cm.unregisterNetworkCallback(callback); 138 } 139 } 140 141 @AfterClass tearDownClass()142 public static void tearDownClass() throws Exception { 143 if (!isSupported()) return; 144 TelephonyUtils.flushTelephonyMetrics(InstrumentationRegistry.getInstrumentation()); 145 } 146 147 @Before setUp()148 public void setUp() throws Exception { 149 if (!isSupported()) return; 150 151 mSm = InstrumentationRegistry.getContext().getSystemService(SubscriptionManager.class); 152 mSubId = SubscriptionManager.getDefaultDataSubscriptionId(); 153 mPackageName = InstrumentationRegistry.getContext().getPackageName(); 154 } 155 156 /** 157 * Correctness check that both {@link PackageManager#FEATURE_TELEPHONY} and 158 * {@link NetworkCapabilities#TRANSPORT_CELLULAR} network must both be 159 * either defined or undefined; you can't cross the streams. 160 */ 161 @Test testCorrectness()162 public void testCorrectness() throws Exception { 163 if (!isSupported()) return; 164 165 final boolean hasCellular = findCellularNetwork() != null; 166 if (isSupported() && !hasCellular) { 167 fail("Device claims to support " + PackageManager.FEATURE_TELEPHONY 168 + " but has no active cellular network, which is required for validation"); 169 } else if (!isSupported() && hasCellular) { 170 fail("Device has active cellular network, but claims to not support " 171 + PackageManager.FEATURE_TELEPHONY); 172 } 173 174 if (isSupported()) { 175 if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 176 fail("Device must have a valid default data subId for validation"); 177 } 178 } 179 } 180 181 @Test testGetActiveSubscriptionInfoCount()182 public void testGetActiveSubscriptionInfoCount() throws Exception { 183 if (!isSupported()) return; 184 assertTrue(mSm.getActiveSubscriptionInfoCount() <= 185 mSm.getActiveSubscriptionInfoCountMax()); 186 } 187 188 @Test testGetActiveSubscriptionInfoForIcc()189 public void testGetActiveSubscriptionInfoForIcc() throws Exception { 190 if (!isSupported()) return; 191 SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 192 (sm) -> sm.getActiveSubscriptionInfo(mSubId)); 193 assertNotNull(ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 194 (sm) -> sm.getActiveSubscriptionInfoForIcc(info.getIccId()))); 195 } 196 197 @Test testIsActiveSubscriptionId()198 public void testIsActiveSubscriptionId() throws Exception { 199 if (!isSupported()) return; 200 assertTrue(mSm.isActiveSubscriptionId(mSubId)); 201 } 202 203 @Test testGetSubscriptionIds()204 public void testGetSubscriptionIds() throws Exception { 205 if (!isSupported()) return; 206 int slotId = SubscriptionManager.getSlotIndex(mSubId); 207 int[] subIds = mSm.getSubscriptionIds(slotId); 208 assertNotNull(subIds); 209 assertTrue(ArrayUtils.contains(subIds, mSubId)); 210 } 211 212 @Test testGetResourcesForSubId()213 public void testGetResourcesForSubId() { 214 if (!isSupported()) return; 215 Resources r = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 216 (sm) -> sm.getResourcesForSubId(InstrumentationRegistry.getContext(), mSubId)); 217 // this is an old method which returns mcc/mnc as ints, so use the old SM.getMcc/Mnc methods 218 // because they also use ints 219 assertEquals(mSm.getActiveSubscriptionInfo(mSubId).getMcc(), r.getConfiguration().mcc); 220 assertEquals(mSm.getActiveSubscriptionInfo(mSubId).getMnc(), r.getConfiguration().mnc); 221 } 222 223 @Test testIsUsableSubscriptionId()224 public void testIsUsableSubscriptionId() throws Exception { 225 if (!isSupported()) return; 226 assertTrue(SubscriptionManager.isUsableSubscriptionId(mSubId)); 227 } 228 229 @Test testActiveSubscriptions()230 public void testActiveSubscriptions() throws Exception { 231 if (!isSupported()) return; 232 233 List<SubscriptionInfo> subList = mSm.getActiveSubscriptionInfoList(); 234 int[] idList = mSm.getActiveSubscriptionIdList(); 235 // Assert when there is no sim card present or detected 236 assertNotNull("Active subscriber required", subList); 237 assertNotNull("Active subscriber required", idList); 238 assertFalse("Active subscriber required", subList.isEmpty()); 239 assertNotEquals("Active subscriber required", 0, idList.length); 240 for (int i = 0; i < subList.size(); i++) { 241 assertTrue(subList.get(i).getSubscriptionId() >= 0); 242 assertTrue(subList.get(i).getSimSlotIndex() >= 0); 243 assertTrue(ArrayUtils.contains(idList, subList.get(i).getSubscriptionId())); 244 if (i >= 1) { 245 assertTrue(subList.get(i - 1).getSimSlotIndex() 246 <= subList.get(i).getSimSlotIndex()); 247 assertTrue(subList.get(i - 1).getSimSlotIndex() < subList.get(i).getSimSlotIndex() 248 || subList.get(i - 1).getSubscriptionId() 249 < subList.get(i).getSubscriptionId()); 250 } 251 } 252 } 253 254 @Test 255 public void testSubscriptionPlans() throws Exception { 256 if (!isSupported()) return; 257 258 // Make ourselves the owner 259 setSubPlanOwner(mSubId, mPackageName); 260 261 // Push empty list and we get empty back 262 mSm.setSubscriptionPlans(mSubId, Arrays.asList()); 263 assertEquals(Arrays.asList(), mSm.getSubscriptionPlans(mSubId)); 264 265 // Push simple plan and get it back 266 final SubscriptionPlan plan = buildValidSubscriptionPlan(System.currentTimeMillis()); 267 mSm.setSubscriptionPlans(mSubId, Arrays.asList(plan)); 268 assertEquals(Arrays.asList(plan), mSm.getSubscriptionPlans(mSubId)); 269 270 // Now revoke our access 271 setSubPlanOwner(mSubId, null); 272 try { 273 mSm.setSubscriptionPlans(mSubId, Arrays.asList()); 274 fail(); 275 } catch (SecurityException expected) { 276 } 277 try { 278 mSm.getSubscriptionPlans(mSubId); 279 fail(); 280 } catch (SecurityException expected) { 281 } 282 } 283 284 @Test 285 public void testSubscriptionPlansOverrideCongested() throws Exception { 286 if (!isSupported()) return; 287 288 final ConnectivityManager cm = InstrumentationRegistry.getContext() 289 .getSystemService(ConnectivityManager.class); 290 final Network net = findCellularNetwork(); 291 assertNotNull("Active cellular network required", net); 292 293 // Make ourselves the owner 294 setSubPlanOwner(mSubId, mPackageName); 295 296 // Missing plans means no overrides 297 mSm.setSubscriptionPlans(mSubId, Arrays.asList()); 298 try { 299 mSm.setSubscriptionOverrideCongested(mSubId, true, 0); 300 fail(); 301 } catch (SecurityException | IllegalStateException expected) { 302 } 303 304 // Defining plans means we get to override 305 mSm.setSubscriptionPlans(mSubId, 306 Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis()))); 307 308 // Cellular is uncongested by default 309 assertTrue(cm.getNetworkCapabilities(net).hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 310 311 // Override should make it go congested 312 { 313 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 314 return !caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 315 }); 316 mSm.setSubscriptionOverrideCongested( 317 mSubId, true, TelephonyManager.getAllNetworkTypes(), 0); 318 assertTrue(latch.await(10, TimeUnit.SECONDS)); 319 } 320 321 // Clearing override should make it go uncongested 322 { 323 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 324 return caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); 325 }); 326 mSm.setSubscriptionOverrideCongested(mSubId, false, 0); 327 assertTrue(latch.await(10, TimeUnit.SECONDS)); 328 } 329 330 // Now revoke our access 331 setSubPlanOwner(mSubId, null); 332 try { 333 mSm.setSubscriptionOverrideCongested( 334 mSubId, true, TelephonyManager.getAllNetworkTypes(), 0); 335 fail(); 336 } catch (SecurityException | IllegalStateException expected) { 337 } 338 } 339 340 @Test testSetDefaultVoiceSubId()341 public void testSetDefaultVoiceSubId() { 342 if (!isSupported()) return; 343 344 int oldSubId = SubscriptionManager.getDefaultVoiceSubscriptionId(); 345 InstrumentationRegistry.getInstrumentation().getUiAutomation() 346 .adoptShellPermissionIdentity(); 347 try { 348 mSm.setDefaultVoiceSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 349 assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, 350 SubscriptionManager.getDefaultVoiceSubscriptionId()); 351 mSm.setDefaultVoiceSubscriptionId(oldSubId); 352 assertEquals(oldSubId, SubscriptionManager.getDefaultVoiceSubscriptionId()); 353 } finally { 354 InstrumentationRegistry.getInstrumentation().getUiAutomation() 355 .dropShellPermissionIdentity(); 356 } 357 } 358 359 @Test testSubscriptionPlansOverrideUnmetered()360 public void testSubscriptionPlansOverrideUnmetered() throws Exception { 361 if (!isSupported()) return; 362 363 final ConnectivityManager cm = InstrumentationRegistry.getContext() 364 .getSystemService(ConnectivityManager.class); 365 final Network net = findCellularNetwork(); 366 assertNotNull("Active cellular network required", net); 367 368 // TODO: Remove this check after b/176119724 is fixed. 369 if (!isUnmetered5GSupported()) return; 370 371 // Cellular is metered by default 372 assertFalse(cm.getNetworkCapabilities(net).hasCapability( 373 NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 374 375 // Override should make it go temporarily unmetered 376 { 377 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 378 return caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 379 }); 380 mSm.setSubscriptionOverrideUnmetered( 381 mSubId, true, TelephonyManager.getAllNetworkTypes(), 0); 382 assertTrue(latch.await(10, TimeUnit.SECONDS)); 383 } 384 385 // Clearing override should make it go metered 386 { 387 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 388 return !caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 389 }); 390 mSm.setSubscriptionOverrideUnmetered( 391 mSubId, false, TelephonyManager.getAllNetworkTypes(), 0); 392 assertTrue(latch.await(10, TimeUnit.SECONDS)); 393 } 394 } 395 396 @Test testSubscriptionPlansUnmetered()397 public void testSubscriptionPlansUnmetered() throws Exception { 398 if (!isSupported()) return; 399 400 final ConnectivityManager cm = InstrumentationRegistry.getContext() 401 .getSystemService(ConnectivityManager.class); 402 final Network net = findCellularNetwork(); 403 assertNotNull("Active cellular network required", net); 404 405 // TODO: Remove this check after b/176119724 is fixed. 406 if (!isUnmetered5GSupported()) return; 407 408 // Make ourselves the owner and define some plans 409 setSubPlanOwner(mSubId, mPackageName); 410 mSm.setSubscriptionPlans(mSubId, 411 Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis()))); 412 413 // Cellular is metered by default 414 assertFalse(cm.getNetworkCapabilities(net).hasCapability( 415 NET_CAPABILITY_TEMPORARILY_NOT_METERED)); 416 417 SubscriptionPlan unmeteredPlan = SubscriptionPlan.Builder 418 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 419 Period.ofMonths(1)) 420 .setTitle("CTS") 421 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED, 422 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) 423 .build(); 424 425 // Unmetered plan should make it go unmetered 426 { 427 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 428 return caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 429 }); 430 mSm.setSubscriptionPlans(mSubId, Arrays.asList(unmeteredPlan)); 431 assertTrue(latch.await(10, TimeUnit.SECONDS)); 432 } 433 434 // Metered plan should make it go metered 435 { 436 final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> { 437 return !caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 438 }); 439 mSm.setSubscriptionPlans(mSubId, 440 Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis()))); 441 assertTrue(latch.await(10, TimeUnit.SECONDS)); 442 } 443 } 444 445 @Test testSubscriptionPlansInvalid()446 public void testSubscriptionPlansInvalid() throws Exception { 447 if (!isSupported()) return; 448 449 // Make ourselves the owner 450 setSubPlanOwner(mSubId, mPackageName); 451 452 // Empty plans can't override 453 assertOverrideFails(); 454 455 // Nonrecurring plan in the past can't override 456 assertOverrideFails(SubscriptionPlan.Builder 457 .createNonrecurring(ZonedDateTime.now().minusDays(14), 458 ZonedDateTime.now().minusDays(7)) 459 .setTitle("CTS") 460 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 461 .build()); 462 463 // Plan with undefined limit can't override 464 assertOverrideFails(SubscriptionPlan.Builder 465 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 466 Period.ofMonths(1)) 467 .setTitle("CTS") 468 .build()); 469 470 // We can override when there is an active plan somewhere 471 final SubscriptionPlan older = SubscriptionPlan.Builder 472 .createNonrecurring(ZonedDateTime.now().minusDays(14), 473 ZonedDateTime.now().minusDays(7)) 474 .setTitle("CTS") 475 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 476 .build(); 477 final SubscriptionPlan newer = SubscriptionPlan.Builder 478 .createNonrecurring(ZonedDateTime.now().minusDays(7), 479 ZonedDateTime.now().plusDays(7)) 480 .setTitle("CTS") 481 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 482 .build(); 483 assertOverrideSuccess(older, newer); 484 } 485 486 @Test testSubscriptionPlansNetworkTypeValidation()487 public void testSubscriptionPlansNetworkTypeValidation() throws Exception { 488 if (!isSupported()) return; 489 490 // Make ourselves the owner 491 setSubPlanOwner(mSubId, mPackageName); 492 493 // Error when adding 2 plans with the same network type 494 List<SubscriptionPlan> plans = new ArrayList<>(); 495 plans.add(buildValidSubscriptionPlan(System.currentTimeMillis())); 496 plans.add(SubscriptionPlan.Builder 497 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 498 Period.ofMonths(1)) 499 .setTitle("CTS") 500 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 501 .build()); 502 plans.add(SubscriptionPlan.Builder 503 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 504 Period.ofMonths(1)) 505 .setTitle("CTS") 506 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 507 .build()); 508 try { 509 mSm.setSubscriptionPlans(mSubId, plans); 510 fail(); 511 } catch (IllegalArgumentException expected) { 512 } 513 514 // Error when there is no general plan 515 plans.clear(); 516 plans.add(SubscriptionPlan.Builder 517 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 518 Period.ofMonths(1)) 519 .setTitle("CTS") 520 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 521 .build()); 522 try { 523 mSm.setSubscriptionPlans(mSubId, plans); 524 fail(); 525 } catch (IllegalArgumentException expected) { 526 } 527 } 528 529 @Test testSubscriptionPlanResetNetworkTypes()530 public void testSubscriptionPlanResetNetworkTypes() { 531 long time = System.currentTimeMillis(); 532 SubscriptionPlan plan = SubscriptionPlan.Builder 533 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 534 Period.ofMonths(1)) 535 .setTitle("CTS") 536 .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_LTE}) 537 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 538 .setDataUsage(500_000_000, time) 539 .resetNetworkTypes() 540 .build(); 541 assertEquals(plan, buildValidSubscriptionPlan(time)); 542 } 543 544 @Test testSubscriptionGrouping()545 public void testSubscriptionGrouping() throws Exception { 546 if (!isSupported()) return; 547 548 // Set subscription group with current sub Id. This should fail 549 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 550 List<Integer> subGroup = new ArrayList(); 551 subGroup.add(mSubId); 552 try { 553 mSm.createSubscriptionGroup(subGroup); 554 fail(); 555 } catch (SecurityException expected) { 556 } 557 558 // Getting subscriptions in group should return null as setSubscriptionGroup 559 // should fail. 560 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 561 assertNull(info.getGroupUuid()); 562 563 // Remove from subscription group with current sub Id. This should fail 564 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 565 try { 566 mSm.addSubscriptionsIntoGroup(subGroup, null); 567 fail(); 568 } catch (NullPointerException expected) { 569 } 570 571 // Add into subscription group that doesn't exist. This should fail 572 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 573 try { 574 ParcelUuid groupUuid = new ParcelUuid(UUID.randomUUID()); 575 mSm.addSubscriptionsIntoGroup(subGroup, groupUuid); 576 fail(); 577 } catch (SecurityException expected) { 578 } 579 580 // Remove from subscription group with current sub Id. This should fail 581 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 582 try { 583 mSm.removeSubscriptionsFromGroup(subGroup, null); 584 fail(); 585 } catch (NullPointerException expected) { 586 } 587 } 588 589 @Test testSubscriptionGroupingWithPermission()590 public void testSubscriptionGroupingWithPermission() throws Exception { 591 if (!isSupported()) return; 592 593 // Set subscription group with current sub Id. 594 List<Integer> subGroup = new ArrayList(); 595 subGroup.add(mSubId); 596 ParcelUuid uuid = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 597 (sm) -> sm.createSubscriptionGroup(subGroup)); 598 599 // Getting subscriptions in group. 600 List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(uuid); 601 assertNotNull(infoList); 602 assertEquals(1, infoList.size()); 603 assertNull(infoList.get(0).getGroupUuid()); 604 605 infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 606 (sm) -> sm.getSubscriptionsInGroup(uuid)); 607 assertNotNull(infoList); 608 assertEquals(1, infoList.size()); 609 assertEquals(uuid, infoList.get(0).getGroupUuid()); 610 611 List<SubscriptionInfo> availableInfoList; 612 try { 613 mSm.getAvailableSubscriptionInfoList(); 614 fail("SecurityException should be thrown without READ_PRIVILEGED_PHONE_STATE"); 615 } catch (SecurityException ex) { 616 // Ignore 617 } 618 availableInfoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 619 (sm) -> sm.getAvailableSubscriptionInfoList()); 620 if (availableInfoList.size() > 1) { 621 List<Integer> availableSubGroup = availableInfoList.stream() 622 .map(info -> info.getSubscriptionId()) 623 .filter(subId -> subId != mSubId) 624 .collect(Collectors.toList()); 625 626 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 627 (sm) -> sm.addSubscriptionsIntoGroup(availableSubGroup, uuid)); 628 629 infoList = mSm.getSubscriptionsInGroup(uuid); 630 assertNotNull(infoList); 631 assertEquals(availableInfoList.size(), infoList.size()); 632 633 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 634 (sm) -> sm.removeSubscriptionsFromGroup(availableSubGroup, uuid)); 635 } 636 637 // Remove from subscription group with current sub Id. 638 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 639 (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid)); 640 641 infoList = mSm.getSubscriptionsInGroup(uuid); 642 assertNotNull(infoList); 643 assertTrue(infoList.isEmpty()); 644 } 645 646 @Test testAddSubscriptionIntoNewGroupWithPermission()647 public void testAddSubscriptionIntoNewGroupWithPermission() throws Exception { 648 if (!isSupported()) return; 649 650 // Set subscription group with current sub Id. 651 List<Integer> subGroup = new ArrayList(); 652 subGroup.add(mSubId); 653 ParcelUuid uuid = new ParcelUuid(UUID.randomUUID()); 654 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 655 (sm) -> sm.addSubscriptionsIntoGroup(subGroup, uuid)); 656 657 // Getting subscriptions in group. 658 List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(uuid); 659 assertNotNull(infoList); 660 assertEquals(1, infoList.size()); 661 assertNull(infoList.get(0).getGroupUuid()); 662 663 infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 664 (sm) -> sm.getSubscriptionsInGroup(uuid)); 665 assertNotNull(infoList); 666 assertEquals(1, infoList.size()); 667 assertEquals(uuid, infoList.get(0).getGroupUuid()); 668 669 // Remove from subscription group with current sub Id. 670 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 671 (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid)); 672 673 infoList = mSm.getSubscriptionsInGroup(uuid); 674 assertNotNull(infoList); 675 assertTrue(infoList.isEmpty()); 676 } 677 678 @Test testSettingOpportunisticSubscription()679 public void testSettingOpportunisticSubscription() throws Exception { 680 if (!isSupported()) return; 681 682 // Set subscription to be opportunistic. This should fail 683 // because we don't have MODIFY_PHONE_STATE or carrier privilege permission. 684 try { 685 mSm.setOpportunistic(true, mSubId); 686 fail(); 687 } catch (SecurityException expected) { 688 } 689 690 // Shouldn't crash. 691 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 692 info.isOpportunistic(); 693 } 694 695 @Test testMccMncString()696 public void testMccMncString() { 697 if (!isSupported()) return; 698 699 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 700 String mcc = info.getMccString(); 701 String mnc = info.getMncString(); 702 assertTrue(mcc == null || mcc.length() <= 3); 703 assertTrue(mnc == null || mnc.length() <= 3); 704 } 705 706 @Test testSetUiccApplicationsEnabled()707 public void testSetUiccApplicationsEnabled() { 708 if (!isSupported()) return; 709 710 boolean canDisable = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 711 (sm) -> sm.canDisablePhysicalSubscription()); 712 if (canDisable) { 713 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 714 (sm) -> sm.setUiccApplicationsEnabled(mSubId, false)); 715 assertFalse(mSm.getActiveSubscriptionInfo(mSubId).areUiccApplicationsEnabled()); 716 717 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 718 (sm) -> sm.setUiccApplicationsEnabled(mSubId, true)); 719 assertTrue(mSm.getActiveSubscriptionInfo(mSubId).areUiccApplicationsEnabled()); 720 } 721 } 722 723 @Test testSubscriptionInfoCarrierId()724 public void testSubscriptionInfoCarrierId() { 725 if (!isSupported()) return; 726 727 SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId); 728 int carrierId = info.getCarrierId(); 729 assertTrue(carrierId >= TelephonyManager.UNKNOWN_CARRIER_ID); 730 } 731 732 @Test testGetOpportunisticSubscriptions()733 public void testGetOpportunisticSubscriptions() throws Exception { 734 if (!isSupported()) return; 735 736 List<SubscriptionInfo> infoList = mSm.getOpportunisticSubscriptions(); 737 738 for (SubscriptionInfo info : infoList) { 739 assertTrue(info.isOpportunistic()); 740 } 741 } 742 743 @Test testGetEnabledSubscriptionId()744 public void testGetEnabledSubscriptionId() { 745 if (!isSupported()) return; 746 int slotId = SubscriptionManager.getSlotIndex(mSubId); 747 if (!SubscriptionManager.isValidSlotIndex(slotId)) { 748 fail("Invalid slot id " + slotId + " for subscription id " + mSubId); 749 } 750 int enabledSubId = executeWithShellPermissionAndDefault(-1, mSm, 751 (sm) -> sm.getEnabledSubscriptionId(slotId)); 752 assertEquals(mSubId, enabledSubId); 753 } 754 755 @Test testSetAndCheckSubscriptionEnabled()756 public void testSetAndCheckSubscriptionEnabled() { 757 if (!isSupported()) return; 758 boolean enabled = executeWithShellPermissionAndDefault(false, mSm, 759 (sm) -> sm.isSubscriptionEnabled(mSubId)); 760 761 AtomicBoolean waitForIsEnabledValue = new AtomicBoolean(!enabled); 762 // wait for the first call to take effect 763 Object lock = new Object(); 764 AtomicBoolean setSubscriptionEnabledCallCompleted = new AtomicBoolean(false); 765 TestThread t = new TestThread(new Runnable() { 766 @Override 767 public void run() { 768 Looper.prepare(); 769 770 SubscriptionManager.OnSubscriptionsChangedListener listener = 771 new SubscriptionManager.OnSubscriptionsChangedListener() { 772 @Override 773 public void onSubscriptionsChanged() { 774 boolean waitForValue = waitForIsEnabledValue.get(); 775 if (executeWithShellPermissionAndDefault(!waitForValue, mSm, 776 (sm) -> sm.isSubscriptionEnabled(mSubId)) == waitForValue) { 777 synchronized (lock) { 778 setSubscriptionEnabledCallCompleted.set(true); 779 lock.notifyAll(); 780 } 781 } 782 } 783 }; 784 mSm.addOnSubscriptionsChangedListener(listener); 785 786 Looper.loop(); 787 } 788 }); 789 790 try { 791 t.start(); 792 // Enable or disable subscription may require users UX confirmation or may not be 793 // supported. Call APIs to make sure there's no crash. 794 executeWithShellPermissionAndDefault(false, mSm, 795 (sm) -> sm.setSubscriptionEnabled(mSubId, !enabled)); 796 797 synchronized (lock) { 798 if (!setSubscriptionEnabledCallCompleted.get()) { 799 lock.wait(5000); 800 } 801 } 802 if (!setSubscriptionEnabledCallCompleted.get()) { 803 // not treating this as test failure as it may be due to UX confirmation or may not 804 // be supported 805 Log.e(TAG, "setSubscriptionEnabled() did not complete"); 806 executeWithShellPermissionAndDefault(false, mSm, 807 (sm) -> sm.setSubscriptionEnabled(mSubId, enabled)); 808 return; 809 } 810 811 // switch back to the original value 812 waitForIsEnabledValue.set(enabled); 813 setSubscriptionEnabledCallCompleted.set(false); 814 executeWithShellPermissionAndDefault(false, mSm, 815 (sm) -> sm.setSubscriptionEnabled(mSubId, enabled)); 816 817 // wait to make sure device is left in the same state after the test as it was before 818 // the test 819 synchronized (lock) { 820 if (!setSubscriptionEnabledCallCompleted.get()) { 821 // longer wait time on purpose as re-enabling can take a longer time 822 lock.wait(50000); 823 } 824 } 825 if (!setSubscriptionEnabledCallCompleted.get()) { 826 // treat this as failure because it worked the first time 827 fail("setSubscriptionEnabled() did not work second time"); 828 } 829 830 // Reset default data subId as it may have been changed as part of the calls above 831 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 832 (sm) -> sm.setDefaultDataSubId(mSubId)); 833 834 // Other tests also expect that cellular data must be available if telephony is 835 // supported. Wait for that before returning. 836 final CountDownLatch latch = waitForCellularNetwork(); 837 latch.await(10, TimeUnit.SECONDS); 838 } catch (InterruptedException e) { 839 fail("InterruptedException"); 840 } 841 } 842 843 @Test testGetActiveDataSubscriptionId()844 public void testGetActiveDataSubscriptionId() { 845 if (!isSupported()) return; 846 847 int activeDataSubIdCurrent = executeWithShellPermissionAndDefault( 848 SubscriptionManager.INVALID_SUBSCRIPTION_ID, mSm, 849 (sm) -> sm.getActiveDataSubscriptionId()); 850 851 if (activeDataSubIdCurrent != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 852 List<SubscriptionInfo> subscriptionInfos = mSm.getCompleteActiveSubscriptionInfoList(); 853 boolean foundSub = subscriptionInfos.stream() 854 .anyMatch(x -> x.getSubscriptionId() == activeDataSubIdCurrent); 855 assertTrue(foundSub); 856 } 857 } 858 859 @Test testSetPreferredDataSubscriptionId()860 public void testSetPreferredDataSubscriptionId() { 861 if (!isSupported()) return; 862 int preferredSubId = executeWithShellPermissionAndDefault(-1, mSm, 863 (sm) -> sm.getPreferredDataSubscriptionId()); 864 if (preferredSubId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 865 // Make sure to switch back to primary/default data sub first. 866 setPreferredDataSubId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 867 } 868 869 List<SubscriptionInfo> subscriptionInfos = mSm.getCompleteActiveSubscriptionInfoList(); 870 871 for (SubscriptionInfo subInfo : subscriptionInfos) { 872 // Only test on opportunistic subscriptions. 873 if (!subInfo.isOpportunistic()) continue; 874 setPreferredDataSubId(subInfo.getSubscriptionId()); 875 } 876 877 // Switch data back to previous preferredSubId. 878 setPreferredDataSubId(preferredSubId); 879 } 880 881 @Test testRestoreAllSimSpecificSettingsFromBackup()882 public void testRestoreAllSimSpecificSettingsFromBackup() throws Exception { 883 if (!isSupported()) return; 884 885 int activeDataSubId = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 886 (sm) -> sm.getActiveDataSubscriptionId()); 887 assertNotEquals(activeDataSubId, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 888 SubscriptionInfo activeSubInfo = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 889 (sm) -> sm.getActiveSubscriptionInfo(activeDataSubId)); 890 String isoCountryCode = activeSubInfo.getCountryIso(); 891 892 byte[] backupData = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm, 893 (sm) -> sm.getAllSimSpecificSettingsForBackup()); 894 assertTrue(backupData.length > 0); 895 896 PersistableBundle bundle = new PersistableBundle(); 897 bundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true); 898 bundle.putBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL, false); 899 overrideCarrierConfig(bundle, activeDataSubId); 900 901 // Get the original ims values. 902 ImsManager imsManager = InstrumentationRegistry.getContext().getSystemService( 903 ImsManager.class); 904 ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(activeDataSubId); 905 boolean isVolteVtEnabledOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 906 mMmTelManager, (m) -> m.isAdvancedCallingSettingEnabled()); 907 boolean isVtImsEnabledOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 908 mMmTelManager, (m) -> m.isVtSettingEnabled()); 909 boolean isVoWiFiSettingEnabledOriginal = 910 ShellIdentityUtils.invokeMethodWithShellPermissions( 911 mMmTelManager, (m) -> m.isVoWiFiSettingEnabled()); 912 int voWifiModeOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 913 mMmTelManager, (m) -> m.getVoWiFiModeSetting()); 914 int voWiFiRoamingModeOriginal = ShellIdentityUtils.invokeMethodWithShellPermissions( 915 mMmTelManager, (m) -> m.getVoWiFiRoamingModeSetting()); 916 917 // Get the original RcsUce values. 918 ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(activeDataSubId); 919 RcsUceAdapter rcsUceAdapter = imsRcsManager.getUceAdapter(); 920 boolean isImsRcsUceEnabledOriginal = 921 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 922 rcsUceAdapter, (a) -> a.isUceSettingEnabled(), ImsException.class, 923 android.Manifest.permission.READ_PHONE_STATE); 924 925 //Change values in DB. 926 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 927 (m) -> m.setAdvancedCallingSettingEnabled(!isVolteVtEnabledOriginal)); 928 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 929 (m) -> m.setVtSettingEnabled(!isVtImsEnabledOriginal)); 930 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn( 931 rcsUceAdapter, (a) -> a.setUceSettingEnabled(!isImsRcsUceEnabledOriginal), 932 ImsException.class); 933 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 934 (m) -> m.setVoWiFiSettingEnabled(!isVoWiFiSettingEnabledOriginal)); 935 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 936 (m) -> m.setVoWiFiModeSetting((voWifiModeOriginal + 1) % 3)); 937 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager, 938 (m) -> m.setVoWiFiRoamingModeSetting((voWiFiRoamingModeOriginal + 1) % 3)); 939 940 // Restore back to original values. 941 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 942 (sm) -> sm.restoreAllSimSpecificSettingsFromBackup(backupData)); 943 944 // Get ims values to verify with. 945 boolean isVolteVtEnabledAfterRestore = ShellIdentityUtils.invokeMethodWithShellPermissions( 946 mMmTelManager, (m) -> m.isAdvancedCallingSettingEnabled()); 947 boolean isVtImsEnabledAfterRestore = ShellIdentityUtils.invokeMethodWithShellPermissions( 948 mMmTelManager, (m) -> m.isVtSettingEnabled()); 949 boolean isVoWiFiSettingEnabledAfterRestore = 950 ShellIdentityUtils.invokeMethodWithShellPermissions( 951 mMmTelManager, (m) -> m.isVoWiFiSettingEnabled()); 952 int voWifiModeAfterRestore = ShellIdentityUtils.invokeMethodWithShellPermissions( 953 mMmTelManager, (m) -> m.getVoWiFiModeSetting()); 954 int voWiFiRoamingModeAfterRestore = ShellIdentityUtils.invokeMethodWithShellPermissions( 955 mMmTelManager, (m) -> m.getVoWiFiRoamingModeSetting()); 956 // Get RcsUce values to verify with. 957 boolean isImsRcsUceEnabledAfterRestore = 958 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 959 rcsUceAdapter, (a) -> a.isUceSettingEnabled(), ImsException.class, 960 android.Manifest.permission.READ_PHONE_STATE); 961 962 assertEquals(isVolteVtEnabledOriginal, isVolteVtEnabledAfterRestore); 963 if (isoCountryCode == null || isoCountryCode.equals("us") || isoCountryCode.equals("ca")) { 964 assertEquals(!isVoWiFiSettingEnabledOriginal, isVoWiFiSettingEnabledAfterRestore); 965 } else { 966 assertEquals(isVoWiFiSettingEnabledOriginal, isVoWiFiSettingEnabledAfterRestore); 967 } 968 assertEquals(voWifiModeOriginal, voWifiModeAfterRestore); 969 assertEquals(voWiFiRoamingModeOriginal, voWiFiRoamingModeAfterRestore); 970 assertEquals(isVtImsEnabledOriginal, isVtImsEnabledAfterRestore); 971 assertEquals(isImsRcsUceEnabledOriginal, isImsRcsUceEnabledAfterRestore); 972 973 // restore original carrier config. 974 overrideCarrierConfig(null, activeDataSubId); 975 976 977 try { 978 // Check api call will fail without proper permissions. 979 mSm.restoreAllSimSpecificSettingsFromBackup(backupData); 980 fail("SecurityException expected"); 981 } catch (SecurityException e) { 982 // expected 983 } 984 } 985 986 @Test testSetAndGetD2DStatusSharing()987 public void testSetAndGetD2DStatusSharing() { 988 if (!isSupported()) return; 989 990 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 991 uiAutomation.adoptShellPermissionIdentity(MODIFY_PHONE_STATE); 992 int originalD2DStatusSharing = mSm.getDeviceToDeviceStatusSharingPreference(mSubId); 993 mSm.setDeviceToDeviceStatusSharingPreference(mSubId, 994 SubscriptionManager.D2D_SHARING_ALL_CONTACTS); 995 assertEquals(SubscriptionManager.D2D_SHARING_ALL_CONTACTS, 996 mSm.getDeviceToDeviceStatusSharingPreference(mSubId)); 997 mSm.setDeviceToDeviceStatusSharingPreference(mSubId, SubscriptionManager.D2D_SHARING_ALL); 998 assertEquals(SubscriptionManager.D2D_SHARING_ALL, 999 mSm.getDeviceToDeviceStatusSharingPreference(mSubId)); 1000 mSm.setDeviceToDeviceStatusSharingPreference(mSubId, originalD2DStatusSharing); 1001 uiAutomation.dropShellPermissionIdentity(); 1002 } 1003 1004 @Test testSetAndGetD2DSharingContacts()1005 public void testSetAndGetD2DSharingContacts() { 1006 if (!isSupported()) return; 1007 1008 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 1009 uiAutomation.adoptShellPermissionIdentity(MODIFY_PHONE_STATE); 1010 List<Uri> originalD2DSharingContacts = mSm.getDeviceToDeviceStatusSharingContacts(mSubId); 1011 mSm.setDeviceToDeviceStatusSharingContacts(mSubId, CONTACTS); 1012 assertEquals(CONTACTS, mSm.getDeviceToDeviceStatusSharingContacts(mSubId)); 1013 mSm.setDeviceToDeviceStatusSharingContacts(mSubId, originalD2DSharingContacts); 1014 uiAutomation.dropShellPermissionIdentity(); 1015 } 1016 1017 @Nullable getBundleFromBackupData(byte[] data)1018 private PersistableBundle getBundleFromBackupData(byte[] data) { 1019 try (ByteArrayInputStream bis = new ByteArrayInputStream(data)) { 1020 return PersistableBundle.readFromStream(bis); 1021 } catch (IOException e) { 1022 return null; 1023 } 1024 } 1025 overrideCarrierConfig(PersistableBundle bundle, int subId)1026 private void overrideCarrierConfig(PersistableBundle bundle, int subId) throws Exception { 1027 CarrierConfigManager carrierConfigManager = InstrumentationRegistry.getContext() 1028 .getSystemService(CarrierConfigManager.class); 1029 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(carrierConfigManager, 1030 (m) -> m.overrideConfig(subId, bundle)); 1031 } 1032 setPreferredDataSubId(int subId)1033 private void setPreferredDataSubId(int subId) { 1034 final LinkedBlockingQueue<Integer> resultQueue = new LinkedBlockingQueue<>(1); 1035 Executor executor = (command)-> command.run(); 1036 Consumer<Integer> consumer = (res)-> { 1037 if (res == null) { 1038 resultQueue.offer(-1); 1039 } else { 1040 resultQueue.offer(res); 1041 } 1042 }; 1043 1044 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm, 1045 (sm) -> sm.setPreferredDataSubscriptionId(subId, false, 1046 executor, consumer)); 1047 int res = -1; 1048 try { 1049 res = resultQueue.poll(2, TimeUnit.SECONDS); 1050 } catch (InterruptedException e) { 1051 fail("Cannot get the modem result in time"); 1052 } 1053 1054 assertEquals(SET_OPPORTUNISTIC_SUB_SUCCESS, res); 1055 int getValue = executeWithShellPermissionAndDefault(-1, mSm, 1056 (sm) -> sm.getPreferredDataSubscriptionId()); 1057 assertEquals(subId, getValue); 1058 } 1059 executeWithShellPermissionAndDefault(T defaultValue, U targetObject, ShellIdentityUtils.ShellPermissionMethodHelper<T, U> helper)1060 private <T, U> T executeWithShellPermissionAndDefault(T defaultValue, U targetObject, 1061 ShellIdentityUtils.ShellPermissionMethodHelper<T, U> helper) { 1062 try { 1063 return ShellIdentityUtils.invokeMethodWithShellPermissions(targetObject, helper); 1064 } catch (Exception e) { 1065 // do nothing, return default 1066 } 1067 return defaultValue; 1068 } 1069 assertOverrideSuccess(SubscriptionPlan... plans)1070 private void assertOverrideSuccess(SubscriptionPlan... plans) { 1071 mSm.setSubscriptionPlans(mSubId, Arrays.asList(plans)); 1072 mSm.setSubscriptionOverrideCongested(mSubId, false, 0); 1073 } 1074 assertOverrideFails(SubscriptionPlan... plans)1075 private void assertOverrideFails(SubscriptionPlan... plans) { 1076 mSm.setSubscriptionPlans(mSubId, Arrays.asList(plans)); 1077 try { 1078 mSm.setSubscriptionOverrideCongested(mSubId, false, 0); 1079 fail(); 1080 } catch (SecurityException | IllegalStateException expected) { 1081 } 1082 } 1083 waitForNetworkCapabilities(Network network, Predicate<NetworkCapabilities> predicate)1084 public static CountDownLatch waitForNetworkCapabilities(Network network, 1085 Predicate<NetworkCapabilities> predicate) { 1086 final CountDownLatch latch = new CountDownLatch(1); 1087 final ConnectivityManager cm = InstrumentationRegistry.getContext() 1088 .getSystemService(ConnectivityManager.class); 1089 cm.registerNetworkCallback(new NetworkRequest.Builder().build(), 1090 new NetworkCallback() { 1091 @Override 1092 public void onCapabilitiesChanged(Network net, NetworkCapabilities caps) { 1093 if (net.equals(network) && predicate.test(caps)) { 1094 latch.countDown(); 1095 cm.unregisterNetworkCallback(this); 1096 } 1097 } 1098 }); 1099 return latch; 1100 } 1101 1102 /** 1103 * Corresponding to findCellularNetwork() 1104 */ waitForCellularNetwork()1105 private static CountDownLatch waitForCellularNetwork() { 1106 final CountDownLatch latch = new CountDownLatch(1); 1107 final ConnectivityManager cm = InstrumentationRegistry.getContext() 1108 .getSystemService(ConnectivityManager.class); 1109 cm.registerNetworkCallback(new NetworkRequest.Builder().build(), 1110 new NetworkCallback() { 1111 @Override 1112 public void onCapabilitiesChanged(Network net, NetworkCapabilities caps) { 1113 if (caps.hasTransport(TRANSPORT_CELLULAR) 1114 && caps.hasCapability(NET_CAPABILITY_INTERNET) 1115 && caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 1116 latch.countDown(); 1117 cm.unregisterNetworkCallback(this); 1118 } 1119 } 1120 }); 1121 return latch; 1122 } 1123 buildValidSubscriptionPlan(long dataUsageTime)1124 private static SubscriptionPlan buildValidSubscriptionPlan(long dataUsageTime) { 1125 return SubscriptionPlan.Builder 1126 .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), 1127 Period.ofMonths(1)) 1128 .setTitle("CTS") 1129 .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) 1130 .setDataUsage(500_000_000, dataUsageTime) 1131 .build(); 1132 } 1133 findCellularNetwork()1134 private static @Nullable Network findCellularNetwork() { 1135 final ConnectivityManager cm = InstrumentationRegistry.getContext() 1136 .getSystemService(ConnectivityManager.class); 1137 for (Network net : cm.getAllNetworks()) { 1138 final NetworkCapabilities caps = cm.getNetworkCapabilities(net); 1139 if (caps != null && caps.hasTransport(TRANSPORT_CELLULAR) 1140 && caps.hasCapability(NET_CAPABILITY_INTERNET) 1141 && caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 1142 return net; 1143 } 1144 } 1145 return null; 1146 } 1147 isSupported()1148 private static boolean isSupported() { 1149 return InstrumentationRegistry.getContext().getPackageManager() 1150 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY); 1151 } 1152 isDSDS()1153 private static boolean isDSDS() { 1154 TelephonyManager tm = InstrumentationRegistry.getContext() 1155 .getSystemService(TelephonyManager.class); 1156 return tm != null && tm.getPhoneCount() > 1; 1157 } 1158 setSubPlanOwner(int subId, String packageName)1159 private static void setSubPlanOwner(int subId, String packageName) throws Exception { 1160 SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), 1161 "cmd netpolicy set sub-plan-owner " + subId + " " + packageName); 1162 } 1163 isUnmetered5GSupported()1164 private boolean isUnmetered5GSupported() { 1165 final CarrierConfigManager ccm = InstrumentationRegistry.getContext() 1166 .getSystemService(CarrierConfigManager.class); 1167 PersistableBundle carrierConfig = ccm.getConfigForSubId(mSubId); 1168 1169 final TelephonyManager tm = InstrumentationRegistry.getContext() 1170 .getSystemService(TelephonyManager.class); 1171 int dataNetworkType = tm.getDataNetworkType(mSubId); 1172 long supportedRats = ShellIdentityUtils.invokeMethodWithShellPermissions(tm, 1173 TelephonyManager::getSupportedRadioAccessFamily); 1174 1175 boolean validCarrier = carrierConfig.getBoolean( 1176 CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL); 1177 boolean validCapabilities = (supportedRats & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0; 1178 // TODO: need to check for TelephonyDisplayInfo override for NR NSA 1179 boolean validNetworkType = dataNetworkType == TelephonyManager.NETWORK_TYPE_NR; 1180 1181 return validCarrier && validNetworkType && validCapabilities; 1182 } 1183 } 1184