1 /*
2  * Copyright (C) 2021 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 package android.telephony.cts;
17 
18 import static android.telephony.CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED;
19 import static android.telephony.CarrierRestrictionRules.MULTISIM_POLICY_NONE;
20 import static android.telephony.PreciseDisconnectCause.NO_DISCONNECT_CAUSE_AVAILABLE;
21 import static android.telephony.PreciseDisconnectCause.TEMPORARY_FAILURE;
22 import static android.telephony.TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED;
23 import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_TWN_CHT;
24 import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_TWN_FET;
25 
26 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
27 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RADIO_POWER;
28 
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.assertTrue;
32 import static org.junit.Assert.fail;
33 import static org.junit.Assume.assumeNoException;
34 import static org.junit.Assume.assumeTrue;
35 
36 import android.Manifest;
37 import android.content.Context;
38 import android.content.pm.PackageInfo;
39 import android.content.pm.PackageManager;
40 import android.content.pm.Signature;
41 import android.hardware.radio.network.Domain;
42 import android.hardware.radio.sim.Carrier;
43 import android.hardware.radio.sim.CarrierRestrictions;
44 import android.hardware.radio.sim.SimLockMultiSimPolicy;
45 import android.hardware.radio.voice.LastCallFailCause;
46 import android.hardware.radio.voice.UusInfo;
47 import android.net.Uri;
48 import android.os.Build;
49 import android.os.Handler;
50 import android.os.HandlerThread;
51 import android.os.SystemProperties;
52 import android.platform.test.annotations.RequiresFlagsEnabled;
53 import android.platform.test.flag.junit.CheckFlagsRule;
54 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
55 import android.telecom.PhoneAccount;
56 import android.telecom.TelecomManager;
57 import android.telephony.AccessNetworkConstants;
58 import android.telephony.CarrierInfo;
59 import android.telephony.CarrierRestrictionRules;
60 import android.telephony.NetworkRegistrationInfo;
61 import android.telephony.ServiceState;
62 import android.telephony.SubscriptionManager;
63 import android.telephony.TelephonyCallback;
64 import android.telephony.TelephonyManager;
65 import android.telephony.cts.util.TelephonyUtils;
66 import android.telephony.mockmodem.MockCallControlInfo;
67 import android.telephony.mockmodem.MockModemConfigInterface;
68 import android.telephony.mockmodem.MockModemManager;
69 import android.util.Log;
70 
71 import androidx.annotation.RequiresApi;
72 import androidx.test.InstrumentationRegistry;
73 import androidx.test.filters.SdkSuppress;
74 
75 import com.android.compatibility.common.util.ShellIdentityUtils;
76 import com.android.internal.telephony.flags.Flags;
77 import com.android.internal.telephony.uicc.IccUtils;
78 
79 import org.junit.After;
80 import org.junit.AfterClass;
81 import org.junit.Before;
82 import org.junit.BeforeClass;
83 import org.junit.Rule;
84 import org.junit.Test;
85 
86 import java.security.MessageDigest;
87 import java.security.NoSuchAlgorithmException;
88 import java.util.ArrayList;
89 import java.util.Arrays;
90 import java.util.Collections;
91 import java.util.List;
92 import java.util.concurrent.Executor;
93 import java.util.concurrent.LinkedBlockingQueue;
94 import java.util.concurrent.TimeUnit;
95 import java.util.function.BooleanSupplier;
96 
97 /** Test MockModemService interfaces. */
98 public class TelephonyManagerTestOnMockModem {
99     @Rule
100     public final CheckFlagsRule mCheckFlagsRule =
101             DeviceFlagsValueProvider.createCheckFlagsRule();
102 
103     private static final String TAG = "TelephonyManagerTestOnMockModem";
104     private static final long WAIT_TIME_MS = 20000;
105     private static MockModemManager sMockModemManager;
106     private static TelephonyManager sTelephonyManager;
107     private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
108     private static final String BOOT_ALLOW_MOCK_MODEM_PROPERTY = "ro.boot.radio.allow_mock_modem";
109     private static final boolean DEBUG = !"user".equals(Build.TYPE);
110     private static final String RESOURCE_PACKAGE_NAME = "android";
111     private static boolean sIsMultiSimDevice;
112     private static HandlerThread sServiceStateChangeCallbackHandlerThread;
113     private static Handler sServiceStateChangeCallbackHandler;
114     private static HandlerThread sCallDisconnectCauseCallbackHandlerThread;
115     private static Handler sCallDisconnectCauseCallbackHandler;
116     private static HandlerThread sCallStateChangeCallbackHandlerThread;
117     private static Handler sCallStateChangeCallbackHandler;
118     private static ServiceStateListener sServiceStateCallback;
119     private static CallDisconnectCauseListener sCallDisconnectCauseCallback;
120     private static CallStateListener sCallStateCallback;
121     private int mServiceState;
122     private int mExpectedRegState;
123     private int mExpectedRegFailCause;
124     private int mPreciseCallDisconnectCause;
125     private int mCallState;
126     private final Object mServiceStateChangeLock = new Object();
127     private final Object mCallDisconnectCauseLock = new Object();
128     private final Object mCallStateChangeLock = new Object();
129     private final Executor mServiceStateChangeExecutor = Runnable::run;
130     private final Executor mCallDisconnectCauseExecutor = Runnable::run;
131     private final Executor mCallStateChangeExecutor = Runnable::run;
132     private boolean mResetCarrierStatusInfo;
133     private static String mShaId;
134     private static final int TIMEOUT_IN_SEC_FOR_MODEM_CB = 10;
135     @BeforeClass
beforeAllTests()136     public static void beforeAllTests() throws Exception {
137         Log.d(TAG, "TelephonyManagerTestOnMockModem#beforeAllTests()");
138 
139         if (!hasTelephonyFeature()) {
140             return;
141         }
142 
143         enforceMockModemDeveloperSetting();
144         sTelephonyManager =
145                 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
146 
147         sIsMultiSimDevice = isMultiSim(sTelephonyManager);
148 
149         sMockModemManager = new MockModemManager();
150         assertNotNull(sMockModemManager);
151         assertTrue(sMockModemManager.connectMockModemService());
152 
153         sServiceStateChangeCallbackHandlerThread =
154                 new HandlerThread("TelephonyManagerServiceStateChangeCallbackTest");
155         sServiceStateChangeCallbackHandlerThread.start();
156         sServiceStateChangeCallbackHandler =
157                 new Handler(sServiceStateChangeCallbackHandlerThread.getLooper());
158 
159         sCallDisconnectCauseCallbackHandlerThread =
160                 new HandlerThread("TelephonyManagerCallDisconnectCauseCallbackTest");
161         sCallDisconnectCauseCallbackHandlerThread.start();
162         sCallDisconnectCauseCallbackHandler =
163                 new Handler(sCallDisconnectCauseCallbackHandlerThread.getLooper());
164 
165         sCallStateChangeCallbackHandlerThread =
166                 new HandlerThread("TelephonyManagerCallStateChangeCallbackTest");
167         sCallStateChangeCallbackHandlerThread.start();
168         sCallStateChangeCallbackHandler =
169                 new Handler(sCallStateChangeCallbackHandlerThread.getLooper());
170         mShaId = getShaId(TelephonyUtils.CTS_APP_PACKAGE);
171 
172         final PackageManager pm = getContext().getPackageManager();
173         if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
174             //Wait for Telephony FW and RIL initialization are done
175             TimeUnit.SECONDS.sleep(4);
176         }
177     }
178 
179     @AfterClass
afterAllTests()180     public static void afterAllTests() throws Exception {
181         Log.d(TAG, "TelephonyManagerTestOnMockModem#afterAllTests()");
182 
183         if (!hasTelephonyFeature()) {
184             return;
185         }
186 
187         if (sServiceStateChangeCallbackHandlerThread != null) {
188             sServiceStateChangeCallbackHandlerThread.quitSafely();
189             sServiceStateChangeCallbackHandlerThread = null;
190         }
191 
192         if (sCallDisconnectCauseCallbackHandlerThread != null) {
193             sCallDisconnectCauseCallbackHandlerThread.quitSafely();
194             sCallDisconnectCauseCallbackHandlerThread = null;
195         }
196 
197         if (sCallStateChangeCallbackHandlerThread != null) {
198             sCallStateChangeCallbackHandlerThread.quitSafely();
199             sCallStateChangeCallbackHandlerThread = null;
200         }
201 
202         if (sServiceStateCallback != null) {
203             sTelephonyManager.unregisterTelephonyCallback(sServiceStateCallback);
204             sServiceStateCallback = null;
205         }
206 
207         if (sCallDisconnectCauseCallback != null) {
208             sTelephonyManager.unregisterTelephonyCallback(sCallDisconnectCauseCallback);
209             sCallDisconnectCauseCallback = null;
210         }
211 
212         if (sCallStateCallback != null) {
213             sTelephonyManager.unregisterTelephonyCallback(sCallStateCallback);
214             sCallStateCallback = null;
215         }
216 
217         // Rebind all interfaces which is binding to MockModemService to default.
218         assertNotNull(sMockModemManager);
219         // Reset the modified error response of RIL_REQUEST_RADIO_POWER to the original behavior
220         // and -1 means to disable the modifed mechanism in mock modem
221         sMockModemManager.forceErrorResponse(0, RIL_REQUEST_RADIO_POWER, -1);
222         assertTrue(sMockModemManager.disconnectMockModemService());
223         sMockModemManager = null;
224         mShaId = null;
225     }
226 
227     @Before
beforeTest()228     public void beforeTest() {
229         assumeTrue(hasTelephonyFeature());
230         try {
231             sTelephonyManager.getHalVersion(TelephonyManager.HAL_SERVICE_RADIO);
232         } catch (IllegalStateException e) {
233             assumeNoException("Skipping tests because Telephony service is null", e);
234         }
235     }
236 
237     @After
afterTest()238     public void afterTest() {
239         if (mResetCarrierStatusInfo) {
240             try {
241                 TelephonyUtils.resetCarrierRestrictionStatusAllowList(
242                         androidx.test.platform.app.InstrumentationRegistry.getInstrumentation());
243             } catch (Exception e) {
244                 e.printStackTrace();
245             } finally {
246                 mResetCarrierStatusInfo = false;
247             }
248         }
249     }
250 
getContext()251     private static Context getContext() {
252         return InstrumentationRegistry.getInstrumentation().getContext();
253     }
254 
getShaId(String packageName)255     private static String getShaId(String packageName) {
256         try {
257             final PackageManager packageManager = getContext().getPackageManager();
258             MessageDigest sha1MDigest = MessageDigest.getInstance("SHA-256");
259             final PackageInfo packageInfo = packageManager.getPackageInfo(packageName,
260                     PackageManager.GET_SIGNATURES);
261             for (Signature signature : packageInfo.signatures) {
262                 final byte[] signatureSha1 = sha1MDigest.digest(signature.toByteArray());
263                 return IccUtils.bytesToHexString(signatureSha1);
264             }
265         } catch (NoSuchAlgorithmException | PackageManager.NameNotFoundException ex) {
266             ex.printStackTrace();
267         }
268         return null;
269     }
270 
hasTelephonyFeature()271     private static boolean hasTelephonyFeature() {
272         final PackageManager pm = getContext().getPackageManager();
273         if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
274             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
275             return false;
276         }
277         return true;
278     }
279 
280     @RequiresFlagsEnabled(Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS)
hasTelephonyFeature(String featureName)281     private static boolean hasTelephonyFeature(String featureName) {
282         final PackageManager pm = getContext().getPackageManager();
283         if (!pm.hasSystemFeature(featureName)) {
284             Log.d(TAG, "Skipping test that requires " + featureName);
285             return false;
286         }
287         return true;
288     }
289 
isMultiSim(TelephonyManager tm)290     private static boolean isMultiSim(TelephonyManager tm) {
291         return tm != null && tm.getPhoneCount() > 1;
292     }
293 
isSimHotSwapCapable()294     private static boolean isSimHotSwapCapable() {
295         boolean isSimHotSwapCapable = false;
296         int resourceId =
297                 getContext()
298                         .getResources()
299                         .getIdentifier("config_hotswapCapable", "bool", RESOURCE_PACKAGE_NAME);
300 
301         if (resourceId > 0) {
302             isSimHotSwapCapable = getContext().getResources().getBoolean(resourceId);
303         } else {
304             Log.d(TAG, "Fail to get the resource Id, using default.");
305         }
306 
307         Log.d(TAG, "isSimHotSwapCapable = " + (isSimHotSwapCapable ? "true" : "false"));
308 
309         return isSimHotSwapCapable;
310     }
311 
enforceMockModemDeveloperSetting()312     private static void enforceMockModemDeveloperSetting() throws Exception {
313         boolean isAllowed = SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false);
314         boolean isAllowedForBoot =
315                 SystemProperties.getBoolean(BOOT_ALLOW_MOCK_MODEM_PROPERTY, false);
316         // Check for developer settings for user build. Always allow for debug builds
317         if (!(isAllowed || isAllowedForBoot) && !DEBUG) {
318             throw new IllegalStateException(
319                     "!! Enable Mock Modem before running this test !! "
320                             + "Developer options => Allow Mock Modem");
321         }
322     }
323 
getActiveSubId(int phoneId)324     private int getActiveSubId(int phoneId) {
325         InstrumentationRegistry.getInstrumentation()
326                 .getUiAutomation()
327                 .adoptShellPermissionIdentity("android.permission.READ_PRIVILEGED_PHONE_STATE");
328 
329         int[] allSubs =
330                 getContext()
331                         .getSystemService(SubscriptionManager.class)
332                         .getActiveSubscriptionIdList();
333         int subsLength = allSubs.length;
334         Log.d(TAG, " Active Sub length is " + subsLength);
335 
336         return (phoneId < subsLength) ? allSubs[phoneId] : -1;
337     }
338 
getNri(int domain, int subId)339     private NetworkRegistrationInfo getNri(int domain, int subId) {
340         InstrumentationRegistry.getInstrumentation()
341                 .getUiAutomation()
342                 .adoptShellPermissionIdentity("android.permission.READ_PHONE_STATE");
343 
344         ServiceState ss = sTelephonyManager.createForSubscriptionId(subId).getServiceState();
345         assertNotNull(ss);
346 
347         NetworkRegistrationInfo nri =
348                 ss.getNetworkRegistrationInfo(domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
349         assertNotNull(nri);
350         return nri;
351     }
352 
getRegState(int domain, int subId)353     private int getRegState(int domain, int subId) {
354         int reg;
355 
356         NetworkRegistrationInfo nri = getNri(domain, subId);
357 
358         reg = nri.getRegistrationState();
359         Log.d(TAG, "SS: " + nri.registrationStateToString(reg));
360 
361         return reg;
362     }
363 
getRegFailCause(int domain, int subId)364     private int getRegFailCause(int domain, int subId) {
365         return getNri(domain, subId).getRejectCause();
366     }
367 
waitForCondition(BooleanSupplier condition, Object lock, long maxWaitMillis)368     private void waitForCondition(BooleanSupplier condition, Object lock, long maxWaitMillis)
369             throws Exception {
370         long now = System.currentTimeMillis();
371         long deadlineTime = now + maxWaitMillis;
372         while (!condition.getAsBoolean() && now < deadlineTime) {
373             lock.wait(deadlineTime - now);
374             now = System.currentTimeMillis();
375         }
376     }
377 
378     @Test
testSimStateChange()379     public void testSimStateChange() throws Throwable {
380         Log.d(TAG, "TelephonyManagerTestOnMockModem#testSimStateChange");
381 
382         assumeTrue(isSimHotSwapCapable());
383 
384         int slotId = 0;
385 
386         // Remove the SIM for initial state
387         sMockModemManager.removeSimCard(slotId);
388 
389         int simCardState = sTelephonyManager.getSimCardState();
390         Log.d(TAG, "Current SIM card state: " + simCardState);
391 
392         assertTrue(
393                 Arrays.asList(TelephonyManager.SIM_STATE_UNKNOWN, TelephonyManager.SIM_STATE_ABSENT)
394                         .contains(simCardState));
395 
396         // Insert a SIM
397         assertTrue(sMockModemManager.insertSimCard(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT));
398         simCardState = sTelephonyManager.getSimCardState();
399         assertEquals(TelephonyManager.SIM_STATE_PRESENT, simCardState);
400 
401         // Check SIM state ready
402         simCardState = sTelephonyManager.getSimState();
403         assertEquals(TelephonyManager.SIM_STATE_READY, simCardState);
404 
405         // Remove the SIM
406         assertTrue(sMockModemManager.removeSimCard(slotId));
407         simCardState = sTelephonyManager.getSimCardState();
408         assertEquals(TelephonyManager.SIM_STATE_ABSENT, simCardState);
409     }
410 
411     @Test
testServiceStateChange()412     public void testServiceStateChange() throws Throwable {
413         Log.d(TAG, "TelephonyManagerTestOnMockModem#testServiceStateChange");
414 
415         assumeTrue(isSimHotSwapCapable());
416 
417         int slotId = 0;
418         int subId;
419 
420         // Insert a SIM
421         sMockModemManager.insertSimCard(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT);
422 
423         TimeUnit.SECONDS.sleep(2);
424         subId = getActiveSubId(slotId);
425         assertTrue(subId > 0);
426 
427         // Register service state change callback
428         synchronized (mServiceStateChangeLock) {
429             mServiceState = ServiceState.STATE_OUT_OF_SERVICE;
430             mExpectedRegState = ServiceState.STATE_IN_SERVICE;
431         }
432 
433         sServiceStateChangeCallbackHandler.post(
434                 () -> {
435                     sServiceStateCallback = new ServiceStateListener();
436                     ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
437                             sTelephonyManager,
438                             (tm) ->
439                                     tm.registerTelephonyCallback(
440                                             mServiceStateChangeExecutor, sServiceStateCallback));
441                 });
442 
443         // Enter Service
444         Log.d(TAG, "testServiceStateChange: Enter Service");
445         sMockModemManager.changeNetworkService(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT, true);
446 
447         // Expect: Home State
448         synchronized (mServiceStateChangeLock) {
449             if (mServiceState != ServiceState.STATE_IN_SERVICE) {
450                 Log.d(TAG, "Wait for service state change to in service");
451                 waitForCondition(
452                         () -> (ServiceState.STATE_IN_SERVICE == mServiceState),
453                         mServiceStateChangeLock,
454                         WAIT_TIME_MS);
455             }
456         }
457         assertEquals(
458                 getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId),
459                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
460 
461         // Leave Service
462         synchronized (mServiceStateChangeLock) {
463             mExpectedRegState = ServiceState.STATE_OUT_OF_SERVICE;
464         }
465 
466         Log.d(TAG, "testServiceStateChange: Leave Service");
467         sMockModemManager.changeNetworkService(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT, false);
468 
469         // Expect: Seaching State
470         synchronized (mServiceStateChangeLock) {
471             if (mServiceState != ServiceState.STATE_OUT_OF_SERVICE) {
472                 Log.d(TAG, "Wait for service state change to out of service");
473                 waitForCondition(
474                         () -> (ServiceState.STATE_OUT_OF_SERVICE == mServiceState),
475                         mServiceStateChangeLock,
476                         WAIT_TIME_MS);
477             }
478         }
479         assertEquals(
480                 getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId),
481                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING);
482 
483         // Unregister service state change callback
484         sTelephonyManager.unregisterTelephonyCallback(sServiceStateCallback);
485         sServiceStateCallback = null;
486 
487         // Remove the SIM
488         sMockModemManager.removeSimCard(slotId);
489     }
490 
491     private class ServiceStateListener extends TelephonyCallback
492             implements TelephonyCallback.ServiceStateListener {
493         @Override
onServiceStateChanged(ServiceState serviceState)494         public void onServiceStateChanged(ServiceState serviceState) {
495             Log.d(TAG, "Callback: service state = " + serviceState.getVoiceRegState());
496             synchronized (mServiceStateChangeLock) {
497                 mServiceState = serviceState.getVoiceRegState();
498                 if (serviceState.getVoiceRegState() == mExpectedRegState) {
499                     mServiceStateChangeLock.notify();
500                 }
501             }
502         }
503     }
504 
505     @Test
testRegistrationFailed()506     public void testRegistrationFailed() throws Throwable {
507         Log.d(TAG, "TelephonyManagerTestOnMockModem#testRegistrationFailed");
508 
509         assumeTrue(isSimHotSwapCapable());
510 
511         int slotId = 0;
512         int subId;
513 
514         // Insert a SIM
515         sMockModemManager.insertSimCard(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT);
516 
517         TimeUnit.SECONDS.sleep(2);
518         subId = getActiveSubId(slotId);
519         assertTrue(subId > 0);
520 
521         // Register service state change callback
522         synchronized (mServiceStateChangeLock) {
523             mServiceState = ServiceState.STATE_IN_SERVICE;
524             mExpectedRegState = ServiceState.STATE_OUT_OF_SERVICE;
525             mExpectedRegFailCause = (int) (Math.random() * (double) 256);
526         }
527 
528         sServiceStateChangeCallbackHandler.post(
529                 () -> {
530                     sServiceStateCallback = new ServiceStateListener();
531                     ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
532                             sTelephonyManager,
533                             (tm) ->
534                                     tm.registerTelephonyCallback(
535                                             mServiceStateChangeExecutor, sServiceStateCallback));
536                 });
537 
538         sMockModemManager.changeNetworkService(
539                 slotId, MOCK_SIM_PROFILE_ID_TWN_CHT, false);
540 
541         // Expect: Searching
542         synchronized (mServiceStateChangeLock) {
543             if (mServiceState != ServiceState.STATE_OUT_OF_SERVICE) {
544                 Log.d(TAG, "Wait for service state change to searching");
545                 waitForCondition(
546                         () -> (ServiceState.STATE_OUT_OF_SERVICE == mServiceState),
547                         mServiceStateChangeLock,
548                         WAIT_TIME_MS);
549             }
550         }
551         assertEquals(
552                 getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId),
553                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING);
554 
555 
556         // Expect: Registration Failed
557         synchronized (mServiceStateChangeLock) {
558             Log.d(TAG, "Wait for service state change to denied");
559             sMockModemManager.changeNetworkService(
560                     slotId, MOCK_SIM_PROFILE_ID_TWN_CHT, false, Domain.CS, mExpectedRegFailCause);
561             mServiceStateChangeLock.wait(WAIT_TIME_MS);
562         }
563 
564         assertEquals(
565                 getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId),
566                 NetworkRegistrationInfo.REGISTRATION_STATE_DENIED);
567         assertEquals(
568                 getRegFailCause(NetworkRegistrationInfo.DOMAIN_CS, subId),
569                 mExpectedRegFailCause);
570 
571         // Unregister service state change callback
572         sTelephonyManager.unregisterTelephonyCallback(sServiceStateCallback);
573         sServiceStateCallback = null;
574 
575         // Remove the SIM
576         sMockModemManager.removeSimCard(slotId);
577     }
578 
579     private class CallDisconnectCauseListener extends TelephonyCallback
580             implements TelephonyCallback.CallDisconnectCauseListener {
581         @Override
onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause)582         public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) {
583             synchronized (mCallDisconnectCauseLock) {
584                 mPreciseCallDisconnectCause = preciseDisconnectCause;
585                 Log.d(TAG, "Callback: call disconnect cause = " + mPreciseCallDisconnectCause);
586                 mCallDisconnectCauseLock.notify();
587             }
588         }
589     }
590 
591     private class CallStateListener extends TelephonyCallback
592             implements TelephonyCallback.CallStateListener {
593         @Override
onCallStateChanged(int state)594         public void onCallStateChanged(int state) {
595             synchronized (mCallStateChangeLock) {
596                 mCallState = state;
597                 mCallStateChangeLock.notify();
598             }
599         }
600     }
601 
602     @Test
testVoiceCallState()603     public void testVoiceCallState() throws Throwable {
604         Log.d(TAG, "TelephonyManagerTestOnMockModem#testVoiceCallState");
605 
606         // Skip the test if it is a data-only device
607         final PackageManager pm = getContext().getPackageManager();
608         if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING)) {
609             Log.d(TAG, "Skipping test: Not test on data-only device");
610             return;
611         }
612 
613         assumeTrue(isSimHotSwapCapable());
614 
615         int slotId = 0;
616         int subId;
617         TelecomManager telecomManager =
618                 (TelecomManager) getContext().getSystemService(Context.TELECOM_SERVICE);
619 
620         // Insert a SIM
621         Log.d(TAG, "Start to insert a SIM");
622         sMockModemManager.insertSimCard(slotId, MOCK_SIM_PROFILE_ID_TWN_FET);
623         TimeUnit.SECONDS.sleep(1);
624 
625         // Register service state change callback
626         synchronized (mServiceStateChangeLock) {
627             mServiceState = ServiceState.STATE_OUT_OF_SERVICE;
628             mExpectedRegState = ServiceState.STATE_IN_SERVICE;
629         }
630 
631         sServiceStateChangeCallbackHandler.post(
632                 () -> {
633                     sServiceStateCallback = new ServiceStateListener();
634                     ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
635                             sTelephonyManager,
636                             (tm) ->
637                                     tm.registerTelephonyCallback(
638                                             mServiceStateChangeExecutor, sServiceStateCallback));
639                 });
640 
641         // In service
642         Log.d(TAG, "Start to register CS only network");
643         sMockModemManager.changeNetworkService(
644                 slotId, MOCK_SIM_PROFILE_ID_TWN_FET, true, Domain.CS);
645 
646         // Verify service state
647         synchronized (mServiceStateChangeLock) {
648             if (mServiceState != ServiceState.STATE_IN_SERVICE) {
649                 Log.d(TAG, "Wait for service state change to in service");
650                 waitForCondition(() -> (
651                         ServiceState.STATE_IN_SERVICE == mServiceState),
652                         mServiceStateChangeLock,
653                         WAIT_TIME_MS);
654             }
655         }
656 
657         subId = getActiveSubId(slotId);
658         assertTrue(subId > 0);
659         assertEquals(
660                 getRegState(NetworkRegistrationInfo.DOMAIN_PS, subId),
661                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING);
662 
663         assertEquals(
664                 getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId),
665                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
666 
667         // Register call state change callback
668         mCallState = TelephonyManager.CALL_STATE_IDLE;
669         sCallStateChangeCallbackHandler.post(
670                 () -> {
671                     sCallStateCallback = new CallStateListener();
672                     ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
673                             sTelephonyManager,
674                             (tm) ->
675                                     tm.registerTelephonyCallback(
676                                             mCallStateChangeExecutor, sCallStateCallback));
677                 });
678 
679         //Disable Ims to make sure the call would go thorugh with a CS call
680         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
681                 sTelephonyManager,  (tm) -> tm.disableIms(slotId));
682         // Sleep 3s to make sure ims is disabled
683         TimeUnit.SECONDS.sleep(3);
684 
685         // Dial a CS voice call
686         Log.d(TAG, "Start dialing call");
687         String phoneNumber = "+886987654321";
688         final Uri address = Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null);
689 
690         // Place outgoing call
691         telecomManager.placeCall(address, null);
692         TimeUnit.SECONDS.sleep(1);
693 
694         // Verify call state
695         synchronized (mCallStateChangeLock) {
696             if (mCallState == TelephonyManager.CALL_STATE_IDLE) {
697                 Log.d(TAG, "Wait for call state change to offhook");
698                 mCallStateChangeLock.wait(WAIT_TIME_MS);
699             }
700             assertEquals(TelephonyManager.CALL_STATE_OFFHOOK, mCallState);
701         }
702 
703         // Verify the call is a CS call
704         assertTrue(sMockModemManager.getNumberOfOngoingCSCalls(slotId) > 0);
705 
706         // Hang up the call
707         Log.d(TAG, "Hangup call");
708         telecomManager.endCall();
709         TimeUnit.SECONDS.sleep(1);
710 
711         // Verify call state
712         synchronized (mCallStateChangeLock) {
713             if (mCallState == TelephonyManager.CALL_STATE_OFFHOOK) {
714                 Log.d(TAG, "Wait for call state change to idle");
715                 mCallStateChangeLock.wait(WAIT_TIME_MS);
716             }
717             assertEquals(TelephonyManager.CALL_STATE_IDLE, mCallState);
718         }
719 
720         // Register call disconnect cause callback
721         mPreciseCallDisconnectCause = NO_DISCONNECT_CAUSE_AVAILABLE;
722 
723         sCallDisconnectCauseCallbackHandler.post(
724                 () -> {
725                     sCallDisconnectCauseCallback = new CallDisconnectCauseListener();
726                     ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
727                             sTelephonyManager,
728                             (tm) ->
729                                     tm.registerTelephonyCallback(
730                                             mCallDisconnectCauseExecutor,
731                                             sCallDisconnectCauseCallback));
732                 });
733 
734         // Trigger an incoming call
735         Log.d(TAG, "Trigger an incoming call.");
736         UusInfo[] uusInfo = new UusInfo[0];
737         MockCallControlInfo callControlInfo = new MockCallControlInfo();
738         callControlInfo.setActiveDurationInMs(1000);
739         callControlInfo.setCallEndInfo(
740                 LastCallFailCause.TEMPORARY_FAILURE, "cts-test-call-failure");
741         sMockModemManager.triggerIncomingVoiceCall(
742                 slotId, phoneNumber, uusInfo, null, callControlInfo);
743 
744         // Verify call state
745         synchronized (mCallStateChangeLock) {
746             if (mCallState == TelephonyManager.CALL_STATE_IDLE) {
747                 Log.d(TAG, "Wait for call state change to ringing");
748                 mCallStateChangeLock.wait(WAIT_TIME_MS);
749             }
750             assertEquals(TelephonyManager.CALL_STATE_RINGING, mCallState);
751         }
752 
753         Log.d(TAG, "Answer the call");
754         telecomManager.acceptRingingCall();
755 
756         // Verify call state
757         synchronized (mCallStateChangeLock) {
758             if (mCallState == TelephonyManager.CALL_STATE_RINGING) {
759                 Log.d(TAG, "Wait for call state change to offhook");
760                 mCallStateChangeLock.wait(WAIT_TIME_MS);
761             }
762             assertEquals(TelephonyManager.CALL_STATE_OFFHOOK, mCallState);
763         }
764 
765         synchronized (mCallDisconnectCauseLock) {
766             if (mPreciseCallDisconnectCause == NO_DISCONNECT_CAUSE_AVAILABLE) {
767                 Log.d(TAG, "Wait for disconnect cause to TEMPORARY_FAILURE");
768                 mCallDisconnectCauseLock.wait(WAIT_TIME_MS);
769             }
770             assertEquals(TEMPORARY_FAILURE, mPreciseCallDisconnectCause);
771         }
772 
773         // Unregister service state change callback
774         sTelephonyManager.unregisterTelephonyCallback(sServiceStateCallback);
775         sServiceStateCallback = null;
776 
777         // Unregister call disconnect cause callback
778         sTelephonyManager.unregisterTelephonyCallback(sCallDisconnectCauseCallback);
779         sCallDisconnectCauseCallback = null;
780 
781         // Unregister call state change callback
782         sTelephonyManager.unregisterTelephonyCallback(sCallStateCallback);
783         sCallStateCallback = null;
784 
785         // Out of service
786         sMockModemManager.changeNetworkService(
787                 slotId, MOCK_SIM_PROFILE_ID_TWN_FET, false, Domain.CS);
788 
789         // Remove the SIM
790         sMockModemManager.removeSimCard(slotId);
791     }
792 
793     @Test
testDsdsServiceStateChange()794     public void testDsdsServiceStateChange() throws Throwable {
795         Log.d(TAG, "TelephonyManagerTestOnMockModem#testDsdsServiceStateChange");
796         assumeTrue("Skip test: Not test on single SIM device", sIsMultiSimDevice);
797 
798         int slotId_0 = 0;
799         int slotId_1 = 1;
800         int subId_0;
801         int subId_1;
802 
803         // Insert a SIM
804         sMockModemManager.insertSimCard(slotId_0, MOCK_SIM_PROFILE_ID_TWN_CHT);
805         sMockModemManager.insertSimCard(slotId_1, MOCK_SIM_PROFILE_ID_TWN_FET);
806 
807         TimeUnit.SECONDS.sleep(2);
808         subId_0 = getActiveSubId(slotId_0);
809         subId_1 = getActiveSubId(slotId_1);
810 
811         // Register service state change callback
812         synchronized (mServiceStateChangeLock) {
813             mServiceState = ServiceState.STATE_OUT_OF_SERVICE;
814             mExpectedRegState = ServiceState.STATE_IN_SERVICE;
815         }
816 
817         sServiceStateChangeCallbackHandler.post(
818                 () -> {
819                     sServiceStateCallback = new ServiceStateListener();
820                     ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
821                             sTelephonyManager,
822                             (tm) ->
823                                     tm.registerTelephonyCallback(
824                                             mServiceStateChangeExecutor, sServiceStateCallback));
825                 });
826 
827         // Enter Service
828         Log.d(TAG, "testDsdsServiceStateChange: Enter Service");
829         sMockModemManager.changeNetworkService(slotId_0, MOCK_SIM_PROFILE_ID_TWN_CHT, true);
830         sMockModemManager.changeNetworkService(slotId_1, MOCK_SIM_PROFILE_ID_TWN_FET, true);
831 
832         // Expect: Home State
833         synchronized (mServiceStateChangeLock) {
834             if (mServiceState != ServiceState.STATE_IN_SERVICE) {
835                 Log.d(TAG, "Wait for service state change to in service");
836                 waitForCondition(
837                         () -> (ServiceState.STATE_IN_SERVICE == mServiceState),
838                         mServiceStateChangeLock,
839                         WAIT_TIME_MS);
840             }
841         }
842         if (subId_0 > 0) {
843             assertEquals(
844                     getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId_0),
845                     NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
846         }
847         if (subId_1 > 0) {
848             TimeUnit.SECONDS.sleep(2);
849             assertEquals(
850                     getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId_1),
851                     NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
852         }
853 
854         assertTrue(subId_0 > 0 || subId_1 > 0);
855 
856         // Leave Service
857         synchronized (mServiceStateChangeLock) {
858             mExpectedRegState = ServiceState.STATE_OUT_OF_SERVICE;
859         }
860 
861         Log.d(TAG, "testDsdsServiceStateChange: Leave Service");
862         sMockModemManager.changeNetworkService(slotId_0, MOCK_SIM_PROFILE_ID_TWN_CHT, false);
863         sMockModemManager.changeNetworkService(slotId_1, MOCK_SIM_PROFILE_ID_TWN_FET, false);
864 
865         // Expect: Seaching State
866         synchronized (mServiceStateChangeLock) {
867             if (mServiceState != ServiceState.STATE_OUT_OF_SERVICE) {
868                 Log.d(TAG, "Wait for service state change to out of service");
869                 waitForCondition(
870                         () -> (ServiceState.STATE_OUT_OF_SERVICE == mServiceState),
871                         mServiceStateChangeLock,
872                         WAIT_TIME_MS);
873             }
874         }
875         if (subId_0 > 0) {
876             assertEquals(
877                     getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId_0),
878                     NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING);
879         }
880         if (subId_1 > 0) {
881             assertEquals(
882                     getRegState(NetworkRegistrationInfo.DOMAIN_CS, subId_1),
883                     NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING);
884         }
885 
886         // Unregister service state change callback
887         sTelephonyManager.unregisterTelephonyCallback(sServiceStateCallback);
888         sServiceStateCallback = null;
889 
890         // Remove the SIM
891         sMockModemManager.removeSimCard(slotId_0);
892         sMockModemManager.removeSimCard(slotId_1);
893     }
894 
895     /**
896      * Verify the NotRestricted status of the device with READ_PHONE_STATE permission granted.
897      */
898     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
899     @Test
getCarrierRestrictionStatus_ReadPhoneState_NotRestricted()900     public void getCarrierRestrictionStatus_ReadPhoneState_NotRestricted() throws Exception {
901         LinkedBlockingQueue<Integer> carrierRestrictionStatusResult = new LinkedBlockingQueue<>(1);
902         try {
903             sMockModemManager.updateCarrierRestrictionInfo(null,
904                     CarrierRestrictions.CarrierRestrictionStatus.NOT_RESTRICTED);
905             TelephonyUtils.addCarrierRestrictionStatusAllowList(
906                     androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(),
907                     TelephonyUtils.CTS_APP_PACKAGE, 10110, mShaId);
908             mResetCarrierStatusInfo = true;
909             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTelephonyManager,
910                     tm -> tm.getCarrierRestrictionStatus(getContext().getMainExecutor(),
911                             carrierRestrictionStatusResult::offer),
912                     Manifest.permission.READ_PHONE_STATE);
913         } catch (SecurityException ex) {
914             fail(ex.getMessage());
915         }
916         Integer value = carrierRestrictionStatusResult.poll(TIMEOUT_IN_SEC_FOR_MODEM_CB,
917                 TimeUnit.SECONDS);
918         assertNotNull(value);
919         assertEquals(TelephonyManager.CARRIER_RESTRICTION_STATUS_NOT_RESTRICTED, value.intValue());
920     }
921 
922     /**
923      * Verify the Restricted status of the device with READ_PHONE_STATE permission granted.
924      */
925     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
926     @Test
getCarrierRestrictionStatus_ReadPhoneState_Restricted()927     public void getCarrierRestrictionStatus_ReadPhoneState_Restricted() throws Exception {
928         LinkedBlockingQueue<Integer> carrierRestrictionStatusResult = new LinkedBlockingQueue<>(1);
929         try {
930             sMockModemManager.updateCarrierRestrictionInfo(getCarrierList(false),
931                     CarrierRestrictions.CarrierRestrictionStatus.RESTRICTED);
932             TelephonyUtils.addCarrierRestrictionStatusAllowList(
933                     androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(),
934                     TelephonyUtils.CTS_APP_PACKAGE, 10110, mShaId);
935             mResetCarrierStatusInfo = true;
936             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTelephonyManager,
937                     tm -> tm.getCarrierRestrictionStatus(getContext().getMainExecutor(),
938                             carrierRestrictionStatusResult::offer),
939                     Manifest.permission.READ_PHONE_STATE);
940         } catch (SecurityException ex) {
941             fail(ex.getMessage());
942         }
943         Integer value = carrierRestrictionStatusResult.poll(TIMEOUT_IN_SEC_FOR_MODEM_CB,
944                 TimeUnit.SECONDS);
945         assertNotNull(value);
946         assertEquals(CARRIER_RESTRICTION_STATUS_RESTRICTED, value.intValue());
947     }
948 
949     /**
950      * Verify the Restricted To Caller status of the device with READ_PHONE_STATE permission
951      * granted.
952      */
953     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
954     @Test
getCarrierRestrictionStatus_ReadPhoneState_RestrictedToCaller_MNO()955     public void getCarrierRestrictionStatus_ReadPhoneState_RestrictedToCaller_MNO() throws Exception {
956         LinkedBlockingQueue<Integer> carrierRestrictionStatusResult = new LinkedBlockingQueue<>(1);
957         try {
958             sMockModemManager.updateCarrierRestrictionInfo(getCarrierList(false),
959                     CarrierRestrictions.CarrierRestrictionStatus.RESTRICTED);
960             TelephonyUtils.addCarrierRestrictionStatusAllowList(
961                     androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(),
962                     TelephonyUtils.CTS_APP_PACKAGE, 1839, mShaId);
963             mResetCarrierStatusInfo = true;
964             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTelephonyManager,
965                     tm -> tm.getCarrierRestrictionStatus(getContext().getMainExecutor(),
966                             carrierRestrictionStatusResult::offer),
967                     Manifest.permission.READ_PHONE_STATE);
968         } catch (SecurityException ex) {
969             fail(ex.getMessage());
970         }
971         Integer value = carrierRestrictionStatusResult.poll(TIMEOUT_IN_SEC_FOR_MODEM_CB,
972                 TimeUnit.SECONDS);
973         assertNotNull(value);
974         assertEquals(TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER,
975                 value.intValue());
976     }
977 
978     /**
979      * Verify the Restricted status of the device with READ_PHONE_STATE permission granted.
980      * MVNO operator reference without GID
981      */
982     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
983     @Test
getCarrierRestrictionStatus_ReadPhoneState_RestrictedToCaller_MNO1()984     public void getCarrierRestrictionStatus_ReadPhoneState_RestrictedToCaller_MNO1() throws Exception {
985         LinkedBlockingQueue<Integer> carrierRestrictionStatusResult = new LinkedBlockingQueue<>(1);
986         try {
987             sMockModemManager.updateCarrierRestrictionInfo(getCarrierList(false),
988                     CarrierRestrictions.CarrierRestrictionStatus.RESTRICTED);
989             TelephonyUtils.addCarrierRestrictionStatusAllowList(
990                     androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(),
991                     TelephonyUtils.CTS_APP_PACKAGE, 2032, mShaId);
992             mResetCarrierStatusInfo = true;
993             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTelephonyManager,
994                     tm -> tm.getCarrierRestrictionStatus(getContext().getMainExecutor(),
995                             carrierRestrictionStatusResult::offer),
996                     Manifest.permission.READ_PHONE_STATE);
997         } catch (SecurityException ex) {
998             fail(ex.getMessage());
999         }
1000         Integer value = carrierRestrictionStatusResult.poll(TIMEOUT_IN_SEC_FOR_MODEM_CB,
1001                 TimeUnit.SECONDS);
1002         assertNotNull(value);
1003         assertEquals(CARRIER_RESTRICTION_STATUS_RESTRICTED,
1004                 value.intValue());
1005     }
1006 
1007     /**
1008      * Verify the Restricted To Caller status of the device with READ_PHONE_STATE permission
1009      * granted.
1010      */
1011     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
1012     @Test
getCarrierRestrictionStatus_ReadPhoneState_RestrictedToCaller_MVNO()1013     public void getCarrierRestrictionStatus_ReadPhoneState_RestrictedToCaller_MVNO() throws Exception {
1014         LinkedBlockingQueue<Integer> carrierRestrictionStatusResult = new LinkedBlockingQueue<>(1);
1015         try {
1016             sMockModemManager.updateCarrierRestrictionInfo(getCarrierList(true),
1017                     CarrierRestrictions.CarrierRestrictionStatus.RESTRICTED);
1018             TelephonyUtils.addCarrierRestrictionStatusAllowList(
1019                     androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(),
1020                     TelephonyUtils.CTS_APP_PACKAGE, 2032, mShaId);
1021             mResetCarrierStatusInfo = true;
1022             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTelephonyManager,
1023                     tm -> tm.getCarrierRestrictionStatus(getContext().getMainExecutor(),
1024                             carrierRestrictionStatusResult::offer),
1025                     Manifest.permission.READ_PHONE_STATE);
1026         } catch (SecurityException ex) {
1027             fail(ex.getMessage());
1028         }
1029         Integer value = carrierRestrictionStatusResult.poll(TIMEOUT_IN_SEC_FOR_MODEM_CB,
1030                 TimeUnit.SECONDS);
1031         assertNotNull(value);
1032         assertEquals(TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER,
1033                 value.intValue());
1034     }
1035 
1036     /**
1037      * Verify the Unknown status of the device with READ_PHONE_STATE permission granted.
1038      */
1039     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
1040     @Test
getCarrierRestrictionStatus_ReadPhoneState_Unknown()1041     public void getCarrierRestrictionStatus_ReadPhoneState_Unknown() throws Exception {
1042         LinkedBlockingQueue<Integer> carrierRestrictionStatusResult = new LinkedBlockingQueue<>(1);
1043         try {
1044             sMockModemManager.updateCarrierRestrictionInfo(null,
1045                     CarrierRestrictions.CarrierRestrictionStatus.UNKNOWN);
1046             TelephonyUtils.addCarrierRestrictionStatusAllowList(
1047                     androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(),
1048                     TelephonyUtils.CTS_APP_PACKAGE, 10110, mShaId);
1049             mResetCarrierStatusInfo = true;
1050             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTelephonyManager,
1051                     tm -> tm.getCarrierRestrictionStatus(getContext().getMainExecutor(),
1052                             carrierRestrictionStatusResult::offer),
1053                     Manifest.permission.READ_PHONE_STATE);
1054         } catch (SecurityException ex) {
1055             fail(ex.getMessage());
1056         }
1057         Integer value = carrierRestrictionStatusResult.poll(TIMEOUT_IN_SEC_FOR_MODEM_CB,
1058                 TimeUnit.SECONDS);
1059         assertNotNull(value);
1060         assertEquals(TelephonyManager.CARRIER_RESTRICTION_STATUS_UNKNOWN, value.intValue());
1061     }
1062 
getCarrierList(boolean isGidRequired)1063     private Carrier[] getCarrierList(boolean isGidRequired) {
1064         android.hardware.radio.sim.Carrier carrier
1065                 = new android.hardware.radio.sim.Carrier();
1066         carrier.mcc = "310";
1067         carrier.mnc = "599";
1068         if (isGidRequired) {
1069             carrier.matchType = Carrier.MATCH_TYPE_GID1;
1070             carrier.matchData = "BA01450000000000";
1071         }
1072         Carrier[] carrierList = new Carrier[1];
1073         carrierList[0] = carrier;
1074         return carrierList;
1075     }
1076 
1077     /**
1078      * Test for primaryImei will return the IMEI that is set through mockModem
1079      */
1080     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
1081     @Test
testGetPrimaryImei()1082     public void testGetPrimaryImei() {
1083         if (Flags.enforceTelephonyFeatureMappingForPublicApis()) {
1084             assumeTrue(hasTelephonyFeature(PackageManager.FEATURE_TELEPHONY_GSM)
1085                     && sTelephonyManager.getActiveModemCount() > 0);
1086         } else {
1087             assumeTrue(sTelephonyManager.getActiveModemCount() > 0);
1088         }
1089 
1090         String primaryImei = ShellIdentityUtils.invokeMethodWithShellPermissions(sTelephonyManager,
1091                 (tm) -> tm.getPrimaryImei());
1092         assertNotNull(primaryImei);
1093         assertEquals(MockModemConfigInterface.DEFAULT_PHONE1_IMEI, primaryImei);
1094     }
1095 
1096     /**
1097      * Verify the change of PrimaryImei with respect to sim slot.
1098      */
1099     @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
1100     @Test
onImeiMappingChanged()1101     public void onImeiMappingChanged() {
1102         // As first step verify the primary Imei against the default allocation
1103         assumeTrue(sTelephonyManager.getActiveModemCount() > 1);
1104         String primaryImei = ShellIdentityUtils.invokeMethodWithShellPermissions(sTelephonyManager,
1105                 (tm) -> tm.getPrimaryImei());
1106         assertNotNull(primaryImei);
1107         assertEquals(MockModemConfigInterface.DEFAULT_PHONE1_IMEI, primaryImei);
1108         String slot0Imei = ShellIdentityUtils.invokeMethodWithShellPermissions(sTelephonyManager,
1109                 (tm) -> tm.getImei(0));
1110         assertEquals(slot0Imei, primaryImei);
1111 
1112         // Second step is change the PrimaryImei to slot2 and verify the same.
1113         if (sMockModemManager.changeImeiMapping()) {
1114             Log.d(TAG, "Verifying primary IMEI after change in IMEI mapping");
1115             primaryImei = ShellIdentityUtils.invokeMethodWithShellPermissions(sTelephonyManager,
1116                     (tm) -> tm.getPrimaryImei());
1117             assertNotNull(primaryImei);
1118             assertEquals(MockModemConfigInterface.DEFAULT_PHONE1_IMEI, primaryImei);
1119             String slot1Imei = ShellIdentityUtils.invokeMethodWithShellPermissions(
1120                     sTelephonyManager,
1121                     (tm) -> tm.getImei(1));
1122             assertEquals(slot1Imei, primaryImei);
1123         }
1124     }
1125 
1126     @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
1127     @Test
getAllowedCarriers_ReadPhoneState_Restricted()1128     public void getAllowedCarriers_ReadPhoneState_Restricted() throws Exception {
1129         assumeTrue(isCarrierLockEnabled());
1130         sMockModemManager.updateCarrierRestrictionInfo(getCarrierList(false),
1131                 CarrierRestrictions.CarrierRestrictionStatus.RESTRICTED);
1132         CarrierRestrictionRules rules =runWithShellPermissionIdentity(() -> {
1133             return sTelephonyManager.getCarrierRestrictionRules();
1134         }, android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
1135         assertEquals(CARRIER_RESTRICTION_STATUS_RESTRICTED,
1136                 rules.getCarrierRestrictionStatus());
1137     }
1138 
1139     /**
1140      * Verifies the API CarrierRestrictionRules#setCarrierRestrictionStatus
1141      */
1142     @RequiresFlagsEnabled(Flags.FLAG_SET_CARRIER_RESTRICTION_STATUS)
1143     @Test
setCarrierRestrictionStatus()1144     public void setCarrierRestrictionStatus() {
1145         CarrierRestrictionRules crr = new CarrierRestrictionRules.Builder()
1146                 .setMultiSimPolicy(MULTISIM_POLICY_NONE)
1147                 .setDefaultCarrierRestriction(CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED)
1148                 .setAllowedCarriers(Collections.EMPTY_LIST)
1149                 .setExcludedCarriers(Collections.EMPTY_LIST)
1150                 .setCarrierRestrictionStatus(CARRIER_RESTRICTION_STATUS_RESTRICTED)
1151                 .build();
1152 
1153         assertEquals(MULTISIM_POLICY_NONE, crr.getMultiSimPolicy());
1154         assertEquals(CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED, crr.getDefaultCarrierRestriction());
1155         assertEquals(Collections.EMPTY_LIST, crr.getAllowedCarriers());
1156         assertEquals(Collections.EMPTY_LIST, crr.getExcludedCarriers());
1157         assertEquals(CARRIER_RESTRICTION_STATUS_RESTRICTED, crr.getCarrierRestrictionStatus());
1158     }
1159 
1160     @RequiresFlagsEnabled(Flags.FLAG_CARRIER_RESTRICTION_RULES_ENHANCEMENT)
1161     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
1162             codeName = "VanillaIceCream")
1163     @Test
getCarrierRestrictionRules()1164     public void getCarrierRestrictionRules() {
1165         assumeTrue(isCarrierLockEnabled());
1166         assumeTrue(Flags.carrierRestrictionRulesEnhancement());
1167         // settings the data in MockModem
1168         android.hardware.radio.sim.CarrierRestrictions carrierRestrictions =
1169                 new android.hardware.radio.sim.CarrierRestrictions();
1170         android.hardware.radio.sim.CarrierInfo carrierInfo = getCarrierInfo("321", "654", "Airtel",
1171                 null, null, null, null, null, null);
1172         carrierRestrictions.allowedCarrierInfoList = new android.hardware.radio.sim.CarrierInfo[1];
1173         carrierRestrictions.allowedCarrierInfoList[0] = carrierInfo;
1174         sMockModemManager.setCarrierRestrictionRules(carrierRestrictions,
1175                 android.hardware.radio.sim.SimLockMultiSimPolicy.NO_MULTISIM_POLICY);
1176 
1177         // calling TM API with shell permissions.
1178         CarrierRestrictionRules carrierRules = ShellIdentityUtils.invokeMethodWithShellPermissions(
1179                 sTelephonyManager, tm -> tm.getCarrierRestrictionRules());
1180 
1181         // Verify the received CarrierRestrictionRules
1182         assertTrue(carrierRules != null);
1183         assertTrue(carrierRules.getAllowedCarriersInfoList() != null);
1184         assertEquals(1, carrierRules.getAllowedCarriersInfoList().size());
1185         CarrierInfo carrierInfo1 = carrierRules.getAllowedCarriersInfoList().get(0);
1186         assertTrue(carrierInfo1 != null);
1187         assertEquals(carrierInfo1.getMcc(), "321");
1188         assertEquals(carrierInfo1.getMnc(), "654");
1189         assertEquals(carrierInfo1.getSpn(), "Airtel");
1190         assertEquals(carrierRules.getMultiSimPolicy(),
1191                 MULTISIM_POLICY_NONE);
1192     }
1193 
1194     @RequiresFlagsEnabled(Flags.FLAG_CARRIER_RESTRICTION_RULES_ENHANCEMENT)
1195     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
1196             codeName = "VanillaIceCream")
1197     @Test
getCarrierRestrictionRules_WithEphlmnList()1198     public void getCarrierRestrictionRules_WithEphlmnList() {
1199         assumeTrue(isCarrierLockEnabled());
1200         assumeTrue(Flags.carrierRestrictionRulesEnhancement());
1201         // settings the data in MockModem
1202         android.hardware.radio.sim.CarrierRestrictions carrierRestrictions =
1203                 new android.hardware.radio.sim.CarrierRestrictions();
1204         List<android.hardware.radio.sim.Plmn> plmnList = new ArrayList<>();
1205         android.hardware.radio.sim.Plmn plmn1 = new android.hardware.radio.sim.Plmn();
1206         plmn1.mcc = "*";
1207         plmn1.mnc = "546";
1208 
1209         android.hardware.radio.sim.Plmn plmn2 = new android.hardware.radio.sim.Plmn();
1210         plmn2.mcc = "132";
1211         plmn2.mnc = "***";
1212 
1213         plmnList.add(plmn1);
1214         plmnList.add(plmn2);
1215 
1216         android.hardware.radio.sim.CarrierInfo carrierInfo = getCarrierInfo("*21", "**1", "Jio",
1217                 null, null, null, plmnList, null, null);
1218         carrierRestrictions.allowedCarrierInfoList = new android.hardware.radio.sim.CarrierInfo[1];
1219         carrierRestrictions.allowedCarrierInfoList[0] = carrierInfo;
1220         sMockModemManager.setCarrierRestrictionRules(carrierRestrictions,
1221                 SimLockMultiSimPolicy.ACTIVE_SERVICE_ON_ANY_SLOT_TO_UNBLOCK_OTHER_SLOTS);
1222 
1223         // calling TM API with shell permissions.
1224         CarrierRestrictionRules carrierRules = ShellIdentityUtils.invokeMethodWithShellPermissions(
1225                 sTelephonyManager, tm -> tm.getCarrierRestrictionRules());
1226 
1227         // Verify the received CarrierRestrictionRules
1228         assertTrue(carrierRules != null);
1229         Log.d("TestonMockModem", "CTS carrierRules = " +carrierRules);
1230         assertTrue(carrierRules.getAllowedCarriersInfoList() != null);
1231         assertEquals(1, carrierRules.getAllowedCarriersInfoList().size());
1232         CarrierInfo carrierInfo1 = carrierRules.getAllowedCarriersInfoList().get(0);
1233         assertTrue(carrierInfo1 != null);
1234         assertEquals(carrierInfo1.getMcc(), "*21");
1235         assertEquals(carrierInfo1.getMnc(), "**1");
1236         assertEquals(carrierInfo1.getSpn(), "Jio");
1237         assertTrue(carrierInfo1.getEhplmn() != null);
1238         assertTrue(carrierInfo1.getEhplmn().size() == 2);
1239         String ehplmn1 = carrierInfo1.getEhplmn().get(0);
1240         String ehplmn2 = carrierInfo1.getEhplmn().get(1);
1241         String[] ehplmn1Tokens = ehplmn1.split(",");
1242         String[] ehplmn2Tokens = ehplmn2.split(",");
1243         assertEquals(ehplmn1Tokens[0], "*");
1244         assertEquals(ehplmn1Tokens[1], "546");
1245         assertEquals(ehplmn2Tokens[0], "132");
1246         assertEquals(ehplmn2Tokens[1], "***");
1247         assertEquals(carrierRules.getMultiSimPolicy(),
1248                 CarrierRestrictionRules.
1249                         MULTISIM_POLICY_ACTIVE_SERVICE_ON_ANY_SLOT_TO_UNBLOCK_OTHER_SLOTS);
1250     }
1251 
getCarrierInfo(String mcc, String mnc, String spn, String gid1, String gid2, String imsi, List<android.hardware.radio.sim.Plmn> ehplmn, String iccid, String impi)1252     private android.hardware.radio.sim.CarrierInfo getCarrierInfo(String mcc, String mnc,
1253             String spn, String gid1, String gid2, String imsi,
1254             List<android.hardware.radio.sim.Plmn> ehplmn, String iccid, String impi) {
1255         android.hardware.radio.sim.CarrierInfo carrierInfo =
1256                 new android.hardware.radio.sim.CarrierInfo();
1257         carrierInfo.mcc = mcc;
1258         carrierInfo.mnc = mnc;
1259         carrierInfo.spn = spn;
1260         carrierInfo.gid1 = gid1;
1261         carrierInfo.gid2 = gid2;
1262         carrierInfo.imsiPrefix = imsi;
1263         carrierInfo.ehplmn = ehplmn;
1264         carrierInfo.iccid = iccid;
1265         carrierInfo.impi = impi;
1266         return carrierInfo;
1267     }
1268 
isCarrierLockEnabled()1269     private boolean isCarrierLockEnabled() {
1270         return InstrumentationRegistry.getInstrumentation().getContext()
1271                 .getPackageManager().hasSystemFeature(
1272                         PackageManager.FEATURE_TELEPHONY_CARRIERLOCK);
1273     }
1274 }
1275