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