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