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