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