1 /*
2  * Copyright (C) 2009 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 com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27 
28 import android.Manifest.permission;
29 import android.app.UiAutomation;
30 import android.bluetooth.BluetoothAdapter;
31 import android.content.BroadcastReceiver;
32 import android.content.ComponentName;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.content.IntentFilter;
36 import android.content.pm.PackageInfo;
37 import android.content.pm.PackageManager;
38 import android.database.ContentObserver;
39 import android.net.ConnectivityManager;
40 import android.net.Uri;
41 import android.net.wifi.WifiInfo;
42 import android.net.wifi.WifiManager;
43 import android.os.AsyncTask;
44 import android.os.Build;
45 import android.os.Handler;
46 import android.os.Looper;
47 import android.os.PersistableBundle;
48 import android.os.Process;
49 import android.os.UserManager;
50 import android.provider.Settings;
51 import android.telecom.PhoneAccount;
52 import android.telecom.PhoneAccountHandle;
53 import android.telecom.TelecomManager;
54 import android.telephony.AccessNetworkConstants;
55 import android.telephony.Annotation.RadioPowerState;
56 import android.telephony.AvailableNetworkInfo;
57 import android.telephony.CallAttributes;
58 import android.telephony.CallQuality;
59 import android.telephony.CarrierConfigManager;
60 import android.telephony.CellLocation;
61 import android.telephony.NetworkRegistrationInfo;
62 import android.telephony.PhoneStateListener;
63 import android.telephony.PreciseCallState;
64 import android.telephony.RadioAccessFamily;
65 import android.telephony.ServiceState;
66 import android.telephony.SubscriptionInfo;
67 import android.telephony.SubscriptionManager;
68 import android.telephony.TelephonyManager;
69 import android.telephony.UiccCardInfo;
70 import android.telephony.UiccSlotInfo;
71 import android.telephony.data.ApnSetting;
72 import android.telephony.emergency.EmergencyNumber;
73 import android.text.TextUtils;
74 import android.util.Log;
75 import android.util.Pair;
76 
77 import androidx.test.InstrumentationRegistry;
78 
79 import com.android.compatibility.common.util.ShellIdentityUtils;
80 import com.android.compatibility.common.util.TestThread;
81 import com.android.internal.telephony.uicc.IccUtils;
82 
83 import org.junit.After;
84 import org.junit.Before;
85 import org.junit.Ignore;
86 import org.junit.Test;
87 
88 import java.security.MessageDigest;
89 import java.security.NoSuchAlgorithmException;
90 import java.util.ArrayList;
91 import java.util.Arrays;
92 import java.util.Collections;
93 import java.util.HashMap;
94 import java.util.HashSet;
95 import java.util.List;
96 import java.util.Locale;
97 import java.util.Map;
98 import java.util.Objects;
99 import java.util.Set;
100 import java.util.concurrent.CountDownLatch;
101 import java.util.concurrent.LinkedBlockingQueue;
102 import java.util.concurrent.TimeUnit;
103 import java.util.function.Consumer;
104 import java.util.regex.Pattern;
105 import java.util.stream.Collectors;
106 
107 
108 /**
109  * Build, install and run the tests by running the commands below:
110  *  make cts -j64
111  *  cts-tradefed run cts -m CtsTelephonyTestCases --test android.telephony.cts.TelephonyManagerTest
112  */
113 public class TelephonyManagerTest {
114     private TelephonyManager mTelephonyManager;
115     private SubscriptionManager mSubscriptionManager;
116     private PackageManager mPackageManager;
117     private boolean mOnCellLocationChangedCalled = false;
118     private boolean mServiceStateChangedCalled = false;
119     private boolean mRadioRebootTriggered = false;
120     private boolean mHasRadioPowerOff = false;
121     private ServiceState mServiceState;
122     private final Object mLock = new Object();
123 
124     private CarrierConfigManager mCarrierConfigManager;
125     private String mSelfPackageName;
126     private String mSelfCertHash;
127 
128     private static final int TOLERANCE = 1000;
129     private PhoneStateListener mListener;
130     private static ConnectivityManager mCm;
131     private static final String TAG = "TelephonyManagerTest";
132     private static final List<Integer> ROAMING_TYPES = Arrays.asList(
133             ServiceState.ROAMING_TYPE_DOMESTIC,
134             ServiceState.ROAMING_TYPE_INTERNATIONAL,
135             ServiceState.ROAMING_TYPE_NOT_ROAMING,
136             ServiceState.ROAMING_TYPE_UNKNOWN);
137     private static final List<Integer> NETWORK_TYPES = Arrays.asList(
138             TelephonyManager.NETWORK_TYPE_UNKNOWN,
139             TelephonyManager.NETWORK_TYPE_GPRS,
140             TelephonyManager.NETWORK_TYPE_EDGE,
141             TelephonyManager.NETWORK_TYPE_UMTS,
142             TelephonyManager.NETWORK_TYPE_CDMA,
143             TelephonyManager.NETWORK_TYPE_EVDO_0,
144             TelephonyManager.NETWORK_TYPE_EVDO_A,
145             TelephonyManager.NETWORK_TYPE_1xRTT,
146             TelephonyManager.NETWORK_TYPE_HSDPA,
147             TelephonyManager.NETWORK_TYPE_HSUPA,
148             TelephonyManager.NETWORK_TYPE_HSPA,
149             TelephonyManager.NETWORK_TYPE_IDEN,
150             TelephonyManager.NETWORK_TYPE_EVDO_B,
151             TelephonyManager.NETWORK_TYPE_LTE,
152             TelephonyManager.NETWORK_TYPE_EHRPD,
153             TelephonyManager.NETWORK_TYPE_HSPAP,
154             TelephonyManager.NETWORK_TYPE_GSM,
155             TelephonyManager.NETWORK_TYPE_TD_SCDMA,
156             TelephonyManager.NETWORK_TYPE_IWLAN,
157             TelephonyManager.NETWORK_TYPE_LTE_CA,
158             TelephonyManager.NETWORK_TYPE_NR);
159 
160     private static final int EMERGENCY_NUMBER_SOURCE_RIL_ECCLIST = 0;
161     private static final Set<Integer> EMERGENCY_NUMBER_SOURCE_SET;
162 
163     private static final String PLMN_A = "123456";
164     private static final String PLMN_B = "78901";
165     private static final List<String> FPLMN_TEST = Arrays.asList(PLMN_A, PLMN_B);
166     private static final int MAX_FPLMN_NUM = 100;
167     private static final int MIN_FPLMN_NUM = 3;
168 
169     private static final String TEST_FORWARD_NUMBER = "54321";
170 
171     private static final int RADIO_HAL_VERSION_1_3 = makeRadioVersion(1, 3);
172 
173     static {
174         EMERGENCY_NUMBER_SOURCE_SET = new HashSet<Integer>();
175         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
176         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM);
177         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE);
178         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
179         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT);
180     }
181 
182     private static final Set<Integer> EMERGENCY_SERVICE_CATEGORY_SET;
183     static {
184         EMERGENCY_SERVICE_CATEGORY_SET = new HashSet<Integer>();
185         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
186         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
187         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE);
188         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD);
189         EMERGENCY_SERVICE_CATEGORY_SET.add(
190                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE);
191         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC);
192         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC);
193     }
194 
195     private int mTestSub;
196     private TelephonyManagerTest.CarrierConfigReceiver mReceiver;
197     private int mRadioVersion;
198 
199     private static class CarrierConfigReceiver extends BroadcastReceiver {
200         private CountDownLatch mLatch = new CountDownLatch(1);
201         private final int mSubId;
202 
CarrierConfigReceiver(int subId)203         CarrierConfigReceiver(int subId) {
204             mSubId = subId;
205         }
206 
207         @Override
onReceive(Context context, Intent intent)208         public void onReceive(Context context, Intent intent) {
209             if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
210                 int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
211                         SubscriptionManager.INVALID_SUBSCRIPTION_ID);
212                 if (mSubId == subId) {
213                     mLatch.countDown();
214                 }
215             }
216         }
217 
clearQueue()218         void clearQueue() {
219             mLatch = new CountDownLatch(1);
220         }
221 
waitForCarrierConfigChanged()222         void waitForCarrierConfigChanged() throws Exception {
223             mLatch.await(5000, TimeUnit.MILLISECONDS);
224         }
225     }
226 
227     @Before
setUp()228     public void setUp() throws Exception {
229         mCm = getContext().getSystemService(ConnectivityManager.class);
230         mSubscriptionManager = getContext().getSystemService(SubscriptionManager.class);
231         mPackageManager = getContext().getPackageManager();
232         mCarrierConfigManager = getContext().getSystemService(CarrierConfigManager.class);
233         mSelfPackageName = getContext().getPackageName();
234         mSelfCertHash = getCertHash(mSelfPackageName);
235         mTestSub = SubscriptionManager.getDefaultSubscriptionId();
236         mTelephonyManager = getContext().getSystemService(TelephonyManager.class)
237                 .createForSubscriptionId(mTestSub);
238         mReceiver = new CarrierConfigReceiver(mTestSub);
239         Pair<Integer, Integer> radioVersion = mTelephonyManager.getRadioHalVersion();
240         mRadioVersion = makeRadioVersion(radioVersion.first, radioVersion.second);
241         IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
242         // ACTION_CARRIER_CONFIG_CHANGED is sticky, so we will get a callback right away.
243         getContext().registerReceiver(mReceiver, filter);
244     }
245 
246     @After
tearDown()247     public void tearDown() throws Exception {
248         if (mListener != null) {
249             // unregister the listener
250             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
251         }
252         if (mReceiver != null) {
253             getContext().unregisterReceiver(mReceiver);
254             mReceiver = null;
255         }
256     }
257 
getCertHash(String pkgName)258     private String getCertHash(String pkgName) throws Exception {
259         try {
260             PackageInfo pInfo = mPackageManager.getPackageInfo(pkgName,
261                     PackageManager.GET_SIGNATURES
262                             | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
263             MessageDigest md = MessageDigest.getInstance("SHA-1");
264             return IccUtils.bytesToHexString(md.digest(pInfo.signatures[0].toByteArray()));
265         } catch (PackageManager.NameNotFoundException ex) {
266             Log.e(TAG, pkgName + " not found", ex);
267             throw ex;
268         } catch (NoSuchAlgorithmException ex) {
269             Log.e(TAG, "Algorithm SHA1 is not found.");
270             throw ex;
271         }
272     }
273 
274     /** Checks whether the cellular stack should be running on this device. */
hasCellular()275     private boolean hasCellular() {
276         return mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
277                 && mTelephonyManager.getPhoneCount() > 0;
278     }
279 
280     @Test
testHasCarrierPrivilegesViaCarrierConfigs()281     public void testHasCarrierPrivilegesViaCarrierConfigs() throws Exception {
282         if (!hasCellular()) return;
283         PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mTestSub);
284 
285         try {
286             assertNotNull("CarrierConfigManager#getConfigForSubId() returned null",
287                     carrierConfig);
288             assertFalse("CarrierConfigManager#getConfigForSubId() returned empty bundle",
289                     carrierConfig.isEmpty());
290 
291             // purge the certs in carrierConfigs first
292             carrierConfig.putStringArray(
293                     CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY, new String[]{});
294             overrideCarrierConfig(carrierConfig);
295             // verify we don't have privilege through carrierConfigs or Uicc
296             assertFalse(mTelephonyManager.hasCarrierPrivileges());
297 
298             carrierConfig.putStringArray(
299                     CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
300                     new String[]{mSelfCertHash});
301 
302             // verify we now have privilege after adding certificate to carrierConfigs
303             overrideCarrierConfig(carrierConfig);
304             assertTrue(mTelephonyManager.hasCarrierPrivileges());
305         } finally {
306             // purge the newly added certificate
307             carrierConfig.putStringArray(
308                     CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY, new String[]{});
309             // carrierConfig.remove(CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
310             overrideCarrierConfig(carrierConfig);
311 
312             // verify we no longer have privilege after removing certificate
313             assertFalse(mTelephonyManager.hasCarrierPrivileges());
314         }
315     }
316 
overrideCarrierConfig(PersistableBundle bundle)317     private void overrideCarrierConfig(PersistableBundle bundle) throws Exception {
318         mReceiver.clearQueue();
319         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mCarrierConfigManager,
320                 (cm) -> cm.overrideConfig(mTestSub, bundle));
321         mReceiver.waitForCarrierConfigChanged();
322     }
323 
grantLocationPermissions()324     public static void grantLocationPermissions() {
325         UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
326         String packageName = getContext().getPackageName();
327         uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_COARSE_LOCATION);
328         uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_FINE_LOCATION);
329         uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_BACKGROUND_LOCATION);
330     }
331 
332     @Test
testDevicePolicyApn()333     public void testDevicePolicyApn() {
334         // These methods aren't accessible to anything except system and phone by design, so we just
335         // look for security exceptions here.
336         try {
337             List<ApnSetting> apns = mTelephonyManager.getDevicePolicyOverrideApns(getContext());
338             fail("SecurityException expected");
339         } catch (SecurityException e) {
340             // expected
341         }
342 
343         try {
344             ApnSetting.Builder builder = new ApnSetting.Builder();
345 
346             ApnSetting setting = builder
347                     .setEntryName("asdf")
348                     .setApnName("asdf")
349                     .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
350                     .build();
351             int id = mTelephonyManager.addDevicePolicyOverrideApn(getContext(), setting);
352             fail("SecurityException expected");
353         } catch (SecurityException e) {
354             // expected
355         }
356 
357         try {
358             ApnSetting.Builder builder = new ApnSetting.Builder();
359 
360             ApnSetting setting = builder
361                     .setEntryName("asdf")
362                     .setApnName("asdf")
363                     .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
364                     .build();
365             boolean success = mTelephonyManager.modifyDevicePolicyOverrideApn(
366                     getContext(), 0, setting);
367             fail("SecurityException expected");
368         } catch (SecurityException e) {
369             // expected
370         }
371     }
372     @Test
testListen()373     public void testListen() throws Throwable {
374         if (!InstrumentationRegistry.getContext().getPackageManager()
375                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
376             Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
377             return;
378         }
379 
380         if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
381             // TODO: temp workaround, need to adjust test to for CDMA
382             return;
383         }
384 
385         grantLocationPermissions();
386 
387         TestThread t = new TestThread(new Runnable() {
388             public void run() {
389                 Looper.prepare();
390                 mListener = new PhoneStateListener() {
391                     @Override
392                     public void onCellLocationChanged(CellLocation location) {
393                         if(!mOnCellLocationChangedCalled) {
394                             synchronized (mLock) {
395                                 mOnCellLocationChangedCalled = true;
396                                 mLock.notify();
397                             }
398                         }
399                     }
400                 };
401 
402                 synchronized (mLock) {
403                     mLock.notify(); // mListener is ready
404                 }
405 
406                 Looper.loop();
407             }
408         });
409 
410         synchronized (mLock) {
411             t.start();
412             mLock.wait(TOLERANCE); // wait for mListener
413         }
414 
415         // Test register
416         synchronized (mLock) {
417             // .listen generates an onCellLocationChanged event
418             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
419             mLock.wait(TOLERANCE);
420 
421             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
422                     mOnCellLocationChangedCalled);
423         }
424 
425         synchronized (mLock) {
426             mOnCellLocationChangedCalled = false;
427             CellLocation.requestLocationUpdate();
428             mLock.wait(TOLERANCE);
429 
430             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
431                     mOnCellLocationChangedCalled);
432         }
433 
434         // unregister the listener
435         mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
436         Thread.sleep(TOLERANCE);
437 
438         // Test unregister
439         synchronized (mLock) {
440             mOnCellLocationChangedCalled = false;
441             // unregister again, to make sure doing so does not call the listener
442             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
443             CellLocation.requestLocationUpdate();
444             mLock.wait(TOLERANCE);
445 
446             assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.",
447                     mOnCellLocationChangedCalled);
448         }
449     }
450 
451     /**
452      * The getter methods here are all related to the information about the telephony.
453      * These getters are related to concrete location, phone, service provider company, so
454      * it's no need to get details of these information, just make sure they are in right
455      * condition(>0 or not null).
456      */
457     @Test
testTelephonyManager()458     public void testTelephonyManager() {
459         assertTrue(mTelephonyManager.getNetworkType() >= TelephonyManager.NETWORK_TYPE_UNKNOWN);
460         assertTrue(mTelephonyManager.getPhoneType() >= TelephonyManager.PHONE_TYPE_NONE);
461         assertTrue(mTelephonyManager.getSimState() >= TelephonyManager.SIM_STATE_UNKNOWN);
462         assertTrue(mTelephonyManager.getDataActivity() >= TelephonyManager.DATA_ACTIVITY_NONE);
463         assertTrue(mTelephonyManager.getDataState() >= TelephonyManager.DATA_DISCONNECTED);
464         assertTrue(mTelephonyManager.getCallState() >= TelephonyManager.CALL_STATE_IDLE);
465 
466         for (int i = 0; i < mTelephonyManager.getPhoneCount(); ++i) {
467             assertTrue(mTelephonyManager.getSimState(i) >= TelephonyManager.SIM_STATE_UNKNOWN);
468         }
469 
470         // Make sure devices without MMS service won't fail on this
471         if (InstrumentationRegistry.getContext().getPackageManager()
472                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
473                 && (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE)) {
474             assertFalse(mTelephonyManager.getMmsUserAgent().isEmpty());
475             assertFalse(mTelephonyManager.getMmsUAProfUrl().isEmpty());
476         }
477 
478         // The following methods may return any value depending on the state of the device. Simply
479         // call them to make sure they do not throw any exceptions.
480         mTelephonyManager.getVoiceMailNumber();
481         mTelephonyManager.getSimOperatorName();
482         mTelephonyManager.getNetworkCountryIso();
483         mTelephonyManager.getCellLocation();
484         mTelephonyManager.getSimCarrierId();
485         mTelephonyManager.getSimCarrierIdName();
486         mTelephonyManager.getSimSpecificCarrierId();
487         mTelephonyManager.getSimSpecificCarrierIdName();
488         mTelephonyManager.getCarrierIdFromSimMccMnc();
489         mTelephonyManager.isDataRoamingEnabled();
490         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
491                 (tm) -> tm.getSimSerialNumber());
492         mTelephonyManager.getSimOperator();
493         mTelephonyManager.getSignalStrength();
494         mTelephonyManager.getNetworkOperatorName();
495         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
496                 (tm) -> tm.getSubscriberId());
497         mTelephonyManager.getLine1Number();
498         mTelephonyManager.getNetworkOperator();
499         mTelephonyManager.getSimCountryIso();
500         mTelephonyManager.getVoiceMailAlphaTag();
501         mTelephonyManager.isNetworkRoaming();
502         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
503                 (tm) -> tm.getDeviceId());
504         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
505                 (tm) -> tm.getDeviceId(mTelephonyManager.getSlotIndex()));
506         mTelephonyManager.getDeviceSoftwareVersion();
507         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
508                 (tm) -> tm.getDeviceSoftwareVersion(mTelephonyManager.getSlotIndex()));
509         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
510                 (tm) -> tm.getImei());
511         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
512                 (tm) -> tm.getImei(mTelephonyManager.getSlotIndex()));
513         mTelephonyManager.getPhoneCount();
514         mTelephonyManager.getDataEnabled();
515         mTelephonyManager.getNetworkSpecifier();
516         mTelephonyManager.getNai();
517         TelecomManager telecomManager = getContext().getSystemService(TelecomManager.class);
518         PhoneAccountHandle defaultAccount = telecomManager
519                 .getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
520         mTelephonyManager.getVoicemailRingtoneUri(defaultAccount);
521         mTelephonyManager.isVoicemailVibrationEnabled(defaultAccount);
522         mTelephonyManager.getSubscriptionId(defaultAccount);
523         mTelephonyManager.getCarrierConfig();
524         mTelephonyManager.isVoiceCapable();
525         mTelephonyManager.isSmsCapable();
526         mTelephonyManager.isLteCdmaEvdoGsmWcdmaEnabled();
527         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
528                 (tm) -> tm.isDataConnectionAllowed());
529         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
530                 (tm) -> tm.isAnyRadioPoweredOn());
531         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
532                 (tm) -> tm.resetIms(tm.getSlotIndex()));
533 
534         // Verify TelephonyManager.getCarrierPrivilegeStatus
535         List<Integer> validCarrierPrivilegeStatus = new ArrayList<>();
536         validCarrierPrivilegeStatus.add(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
537         validCarrierPrivilegeStatus.add(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
538         validCarrierPrivilegeStatus.add(
539                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED);
540         validCarrierPrivilegeStatus.add(
541                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES);
542         int carrierPrivilegeStatusResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
543                 mTelephonyManager, (tm) -> tm.getCarrierPrivilegeStatus(Process.myUid()));
544         assertTrue(validCarrierPrivilegeStatus.contains(carrierPrivilegeStatusResult));
545 
546         // Verify TelephonyManager.getCarrierPrivilegedPackagesForAllActiveSubscriptions
547         List<String> resultForGetCarrierPrivilegedApis =
548                 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
549                         (tm) -> tm.getCarrierPrivilegedPackagesForAllActiveSubscriptions());
550         assertNotNull(resultForGetCarrierPrivilegedApis);
551         for (String result : resultForGetCarrierPrivilegedApis) {
552             assertFalse(TextUtils.isEmpty(result));
553         }
554 
555         TelephonyManager.getDefaultRespondViaMessageApplication(getContext(), false);
556     }
557 
558     /**
559      * Due to the corresponding API is hidden in R and will be public in S, this test
560      * is commented and will be un-commented in Android S.
561      *
562     @Test
563     public void testGetCallForwarding() {
564         List<Integer> callForwardingReasons = new ArrayList<>();
565         callForwardingReasons.add(CallForwardingInfo.REASON_UNCONDITIONAL);
566         callForwardingReasons.add(CallForwardingInfo.REASON_BUSY);
567         callForwardingReasons.add(CallForwardingInfo.REASON_NO_REPLY);
568         callForwardingReasons.add(CallForwardingInfo.REASON_NOT_REACHABLE);
569         callForwardingReasons.add(CallForwardingInfo.REASON_ALL);
570         callForwardingReasons.add(CallForwardingInfo.REASON_ALL_CONDITIONAL);
571 
572         Set<Integer> callForwardingStatus = new HashSet<Integer>();
573         callForwardingStatus.add(CallForwardingInfo.STATUS_INACTIVE);
574         callForwardingStatus.add(CallForwardingInfo.STATUS_ACTIVE);
575         callForwardingStatus.add(CallForwardingInfo.STATUS_FDN_CHECK_FAILURE);
576         callForwardingStatus.add(CallForwardingInfo.STATUS_UNKNOWN_ERROR);
577         callForwardingStatus.add(CallForwardingInfo.STATUS_NOT_SUPPORTED);
578 
579         for (int callForwardingReasonToGet : callForwardingReasons) {
580             Log.d(TAG, "[testGetCallForwarding] callForwardingReasonToGet: "
581                     + callForwardingReasonToGet);
582             CallForwardingInfo callForwardingInfo =
583                     ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
584                             (tm) -> tm.getCallForwarding(callForwardingReasonToGet));
585 
586             assertNotNull(callForwardingInfo);
587             assertTrue(callForwardingStatus.contains(callForwardingInfo.getStatus()));
588             assertTrue(callForwardingReasons.contains(callForwardingInfo.getReason()));
589             callForwardingInfo.getNumber();
590             assertTrue(callForwardingInfo.getTimeoutSeconds() >= 0);
591         }
592     }
593      */
594 
595     /**
596      * Due to the corresponding API is hidden in R and will be public in S, this test
597      * is commented and will be un-commented in Android S.
598      *
599     @Test
600     public void testSetCallForwarding() {
601         List<Integer> callForwardingReasons = new ArrayList<>();
602         callForwardingReasons.add(CallForwardingInfo.REASON_UNCONDITIONAL);
603         callForwardingReasons.add(CallForwardingInfo.REASON_BUSY);
604         callForwardingReasons.add(CallForwardingInfo.REASON_NO_REPLY);
605         callForwardingReasons.add(CallForwardingInfo.REASON_NOT_REACHABLE);
606         callForwardingReasons.add(CallForwardingInfo.REASON_ALL);
607         callForwardingReasons.add(CallForwardingInfo.REASON_ALL_CONDITIONAL);
608 
609         // Enable Call Forwarding
610         for (int callForwardingReasonToEnable : callForwardingReasons) {
611             final CallForwardingInfo callForwardingInfoToEnable = new CallForwardingInfo(
612                     CallForwardingInfo.STATUS_ACTIVE,
613                     callForwardingReasonToEnable,
614                     TEST_FORWARD_NUMBER,
615                     // time seconds
616                     1);
617             Log.d(TAG, "[testSetCallForwarding] Enable Call Forwarding. Status: "
618                     + CallForwardingInfo.STATUS_ACTIVE + " Reason: "
619                     + callForwardingReasonToEnable + " Number: " + TEST_FORWARD_NUMBER
620                     + " Time Seconds: 1");
621             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
622                     (tm) -> tm.setCallForwarding(callForwardingInfoToEnable));
623         }
624 
625         // Disable Call Forwarding
626         for (int callForwardingReasonToDisable : callForwardingReasons) {
627             final CallForwardingInfo callForwardingInfoToDisable = new CallForwardingInfo(
628                     CallForwardingInfo.STATUS_INACTIVE,
629                     callForwardingReasonToDisable,
630                     TEST_FORWARD_NUMBER,
631                     // time seconds
632                     1);
633             Log.d(TAG, "[testSetCallForwarding] Disable Call Forwarding. Status: "
634                     + CallForwardingInfo.STATUS_INACTIVE + " Reason: "
635                     + callForwardingReasonToDisable + " Number: " + TEST_FORWARD_NUMBER
636                     + " Time Seconds: 1");
637             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
638                     (tm) -> tm.setCallForwarding(callForwardingInfoToDisable));
639         }
640     }
641     */
642 
643     /**
644      * Due to the corresponding API is hidden in R and will be public in S, this test
645      * is commented and will be un-commented in Android S.
646      *
647     @Test
648     public void testGetCallWaitingStatus() {
649         Set<Integer> callWaitingStatus = new HashSet<Integer>();
650         callWaitingStatus.add(TelephonyManager.CALL_WAITING_STATUS_ACTIVE);
651         callWaitingStatus.add(TelephonyManager.CALL_WAITING_STATUS_INACTIVE);
652         callWaitingStatus.add(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
653         callWaitingStatus.add(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
654 
655         int status = ShellIdentityUtils.invokeMethodWithShellPermissions(
656                 mTelephonyManager, (tm) -> tm.getCallWaitingStatus());
657         assertTrue(callWaitingStatus.contains(status));
658     }
659      */
660 
661     /**
662      * Due to the corresponding API is hidden in R and will be public in S, this test
663      * is commented and will be un-commented in Android S.
664      *
665     @Test
666     public void testSetCallWaitingStatus() {
667         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
668                 (tm) -> tm.setCallWaitingStatus(true));
669         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
670                 (tm) -> tm.setCallWaitingStatus(false));
671     }
672      */
673 
674     @Test
testGetRadioHalVersion()675     public void testGetRadioHalVersion() {
676         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
677             Log.d(TAG,"skipping test on device without FEATURE_TELEPHONY present");
678             return;
679         }
680 
681         Pair<Integer, Integer> version = mTelephonyManager.getRadioHalVersion();
682 
683         // The version must be valid, and the versions start with 1.0
684         assertFalse("Invalid Radio HAL Version: " + version,
685                 version.first < 1 || version.second < 0);
686     }
687 
688     @Test
testCreateForPhoneAccountHandle()689     public void testCreateForPhoneAccountHandle() {
690         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
691             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
692             return;
693         }
694         if (!mTelephonyManager.isVoiceCapable()) {
695             Log.d(TAG, "Skipping test that requires config_voice_capable is true");
696             return;
697         }
698         int subId = SubscriptionManager.getDefaultDataSubscriptionId();
699         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
700             Log.d(TAG, "Skipping test that requires DefaultDataSubscriptionId setting");
701             return;
702         }
703 
704         TelecomManager telecomManager = getContext().getSystemService(TelecomManager.class);
705         PhoneAccountHandle handle =
706                 telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
707         TelephonyManager telephonyManager = mTelephonyManager.createForPhoneAccountHandle(handle);
708         String globalSubscriberId = ShellIdentityUtils.invokeMethodWithShellPermissions(
709                 mTelephonyManager, (tm) -> tm.getSubscriberId());
710         String localSubscriberId = ShellIdentityUtils.invokeMethodWithShellPermissions(
711                 telephonyManager, (tm) -> tm.getSubscriberId());
712         assertEquals(globalSubscriberId, localSubscriberId);
713     }
714 
715     @Test
testCreateForPhoneAccountHandle_InvalidHandle()716     public void testCreateForPhoneAccountHandle_InvalidHandle(){
717         PhoneAccountHandle handle =
718                 new PhoneAccountHandle(new ComponentName("com.example.foo", "bar"), "baz");
719         assertNull(mTelephonyManager.createForPhoneAccountHandle(handle));
720     }
721 
722     /**
723      * Tests that the phone count returned is valid.
724      */
725     @Test
testGetPhoneCount()726     public void testGetPhoneCount() {
727         int phoneCount = mTelephonyManager.getPhoneCount();
728         int phoneType = mTelephonyManager.getPhoneType();
729         switch (phoneType) {
730             case TelephonyManager.PHONE_TYPE_GSM:
731             case TelephonyManager.PHONE_TYPE_CDMA:
732                 assertTrue("Phone count should be > 0", phoneCount > 0);
733                 break;
734             case TelephonyManager.PHONE_TYPE_NONE:
735                 assertTrue("Phone count should be 0", phoneCount == 0 || phoneCount == 1);
736                 break;
737             default:
738                 throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
739         }
740     }
741 
742     /**
743      * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address
744      * if only a WiFi device. At least one of them must be valid.
745      */
746     @Test
testGetDeviceId()747     public void testGetDeviceId() {
748         String deviceId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
749                 (tm) -> tm.getDeviceId());
750         verifyDeviceId(deviceId);
751     }
752 
753     /**
754      * Tests the max number of active SIMs method
755      */
756     @Test
testGetMaxNumberOfSimultaneouslyActiveSims()757     public void testGetMaxNumberOfSimultaneouslyActiveSims() {
758         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
759             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
760             return;
761         }
762 
763         int maxNum = mTelephonyManager.getMaxNumberOfSimultaneouslyActiveSims();
764         assertTrue(maxNum >= 1);
765     }
766 
767     /**
768      * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address
769      * if only a WiFi device. At least one of them must be valid.
770      */
771     @Test
testGetDeviceIdForSlot()772     public void testGetDeviceIdForSlot() {
773         String deviceId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
774                 (tm) -> tm.getDeviceId(mTelephonyManager.getSlotIndex()));
775         verifyDeviceId(deviceId);
776         // Also verify that no exception is thrown for any slot index (including invalid ones)
777         for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) {
778             // The compiler error 'local variables referenced from a lambda expression must be final
779             // or effectively final' is reported when using i, so assign it to a final variable.
780             final int currI = i;
781             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
782                     (tm) -> tm.getDeviceId(currI));
783         }
784     }
785 
verifyDeviceId(String deviceId)786     private void verifyDeviceId(String deviceId) {
787         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
788             // Either IMEI or MEID need to be valid.
789             try {
790                 assertImei(deviceId);
791             } catch (AssertionError e) {
792                 assertMeidEsn(deviceId);
793             }
794         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
795             assertSerialNumber();
796             assertMacAddress(getWifiMacAddress());
797         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
798             assertSerialNumber();
799             assertMacAddress(getBluetoothMacAddress());
800         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {
801             assertTrue(mCm.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET) != null);
802         }
803     }
804 
assertImei(String id)805     private static void assertImei(String id) {
806         assertFalse("Imei should not be empty or null", TextUtils.isEmpty(id));
807         // IMEI may include the check digit
808         String imeiPattern = "[0-9]{14,15}";
809         String invalidPattern = "[0]{14,15}";
810         assertTrue("IMEI " + id + " does not match pattern " + imeiPattern,
811                 Pattern.matches(imeiPattern, id));
812         assertFalse("IMEI " + id + " must not be a zero sequence" + invalidPattern,
813                 Pattern.matches(invalidPattern, id));
814         if (id.length() == 15) {
815             // if the ID is 15 digits, the 15th must be a check digit.
816             assertImeiCheckDigit(id);
817         }
818     }
819 
assertImeiCheckDigit(String deviceId)820     private static void assertImeiCheckDigit(String deviceId) {
821         int expectedCheckDigit = getLuhnCheckDigit(deviceId.substring(0, 14));
822         int actualCheckDigit = Character.digit(deviceId.charAt(14), 10);
823         assertEquals("Incorrect check digit for " + deviceId, expectedCheckDigit, actualCheckDigit);
824     }
825 
826     /**
827      * Use decimal value (0-9) to index into array to get sum of its digits
828      * needed by Lunh check.
829      *
830      * Example: DOUBLE_DIGIT_SUM[6] = 3 because 6 * 2 = 12 => 1 + 2 = 3
831      */
832     private static final int[] DOUBLE_DIGIT_SUM = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
833 
834     /**
835      * Calculate the check digit by starting from the right, doubling every
836      * each digit, summing all the digits including the doubled ones, and
837      * finding a number to make the sum divisible by 10.
838      *
839      * @param deviceId not including the check digit
840      * @return the check digit
841      */
getLuhnCheckDigit(String deviceId)842     private static int getLuhnCheckDigit(String deviceId) {
843         int sum = 0;
844         int dontDoubleModulus = deviceId.length() % 2;
845         for (int i = deviceId.length() - 1; i >= 0; --i) {
846             int digit = Character.digit(deviceId.charAt(i), 10);
847             if (i % 2 == dontDoubleModulus) {
848                 sum += digit;
849             } else {
850                 sum += DOUBLE_DIGIT_SUM[digit];
851             }
852         }
853         sum %= 10;
854         return sum == 0 ? 0 : 10 - sum;
855     }
856 
assertMeidEsn(String id)857     private static void assertMeidEsn(String id) {
858         // CDMA device IDs may either be a 14-hex-digit MEID or an
859         // 8-hex-digit ESN.  If it's an ESN, it may not be a
860         // pseudo-ESN.
861         assertFalse("Meid ESN should not be empty or null", TextUtils.isEmpty(id));
862         if (id.length() == 14) {
863             assertMeidFormat(id);
864         } else if (id.length() == 8) {
865             assertHexadecimalEsnFormat(id);
866         } else {
867             fail("device id on CDMA must be 14-digit hex MEID or 8-digit hex ESN.");
868         }
869     }
870 
assertHexadecimalEsnFormat(String deviceId)871     private static void assertHexadecimalEsnFormat(String deviceId) {
872         String esnPattern = "[0-9a-fA-F]{8}";
873         String invalidPattern = "[0]{8}";
874         assertTrue("ESN hex device id " + deviceId + " does not match pattern " + esnPattern,
875                 Pattern.matches(esnPattern, deviceId));
876         assertFalse("ESN hex device id " + deviceId + " must not be a pseudo-ESN",
877                 "80".equals(deviceId.substring(0, 2)));
878         assertFalse("ESN hex device id " + deviceId + "must not be a zero sequence",
879                 Pattern.matches(invalidPattern, deviceId));
880     }
881 
assertMeidFormat(String deviceId)882     private static void assertMeidFormat(String deviceId) {
883         // MEID must NOT include the check digit.
884         String meidPattern = "[0-9a-fA-F]{14}";
885         String invalidPattern = "[0]{14}";
886         assertTrue("MEID device id " + deviceId + " does not match pattern "
887                 + meidPattern, Pattern.matches(meidPattern, deviceId));
888         assertFalse("MEID device id " + deviceId + "must not be a zero sequence",
889                 Pattern.matches(invalidPattern, deviceId));
890     }
891 
assertSerialNumber()892     private void assertSerialNumber() {
893         String serial = ShellIdentityUtils.invokeStaticMethodWithShellPermissions(
894                 Build::getSerial);
895         assertNotNull("Non-telephony devices must have a Build.getSerial() number.",
896                 serial);
897         assertTrue("Hardware id must be no longer than 20 characters.",
898                 serial.length() <= 20);
899         assertTrue("Hardware id must be alphanumeric.",
900                 Pattern.matches("[0-9A-Za-z]+", serial));
901     }
902 
assertMacAddress(String macAddress)903     private void assertMacAddress(String macAddress) {
904         String macPattern = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}";
905         assertTrue("MAC Address " + macAddress + " does not match pattern " + macPattern,
906                 Pattern.matches(macPattern, macAddress));
907     }
908 
909     /** @return mac address which requires the WiFi system to be enabled */
getWifiMacAddress()910     private String getWifiMacAddress() {
911         WifiManager wifiManager = getContext().getSystemService(WifiManager.class);
912 
913         boolean enabled = wifiManager.isWifiEnabled();
914 
915         try {
916             if (!enabled) {
917                 wifiManager.setWifiEnabled(true);
918             }
919 
920             WifiInfo wifiInfo = wifiManager.getConnectionInfo();
921             return wifiInfo.getMacAddress();
922 
923         } finally {
924             if (!enabled) {
925                 wifiManager.setWifiEnabled(false);
926             }
927         }
928     }
929 
getBluetoothMacAddress()930     private String getBluetoothMacAddress() {
931         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
932         if (adapter == null) {
933             return "";
934         }
935 
936         return adapter.getAddress();
937     }
938 
939     private static final String ISO_COUNTRY_CODE_PATTERN = "[a-z]{2}";
940 
941     @Test
testGetNetworkCountryIso()942     public void testGetNetworkCountryIso() {
943         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
944             String countryCode = mTelephonyManager.getNetworkCountryIso();
945             assertTrue("Country code '" + countryCode + "' did not match "
946                             + ISO_COUNTRY_CODE_PATTERN,
947                     Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
948 
949             for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) {
950                 countryCode = mTelephonyManager.getNetworkCountryIso(i);
951 
952                 assertTrue("Country code '" + countryCode + "' did not match "
953                                 + ISO_COUNTRY_CODE_PATTERN + " for slot " + i,
954                         Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
955             }
956         } else {
957             // Non-telephony may still have the property defined if it has a SIM.
958         }
959     }
960 
961     @Test
testSetSystemSelectionChannels()962     public void testSetSystemSelectionChannels() {
963         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(1);
964         final UiAutomation uiAutomation =
965                 InstrumentationRegistry.getInstrumentation().getUiAutomation();
966         try {
967             uiAutomation.adoptShellPermissionIdentity();
968             // This is a oneway binder call, meaning we may return before the permission check
969             // happens. Hold shell permissions until we get a response.
970             mTelephonyManager.setSystemSelectionChannels(Collections.emptyList(),
971                     getContext().getMainExecutor(), queue::offer);
972             Boolean result = queue.poll(1000, TimeUnit.MILLISECONDS);
973             // Ensure we get a result
974             assertNotNull(result);
975             // Only verify the result for supported devices on IRadio 1.3+
976             if (mRadioVersion >= RADIO_HAL_VERSION_1_3) {
977                 assertTrue(result);
978             }
979         } catch (InterruptedException e) {
980             fail("interrupted");
981         } finally {
982             uiAutomation.dropShellPermissionIdentity();
983         }
984 
985         // Try calling the API that doesn't provide feedback. We have no way of knowing if it
986         // succeeds, so just make sure nothing crashes.
987         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
988                 tp -> tp.setSystemSelectionChannels(Collections.emptyList()));
989     }
990 
991     @Test
testGetSimCountryIso()992     public void testGetSimCountryIso() {
993         String countryCode = mTelephonyManager.getSimCountryIso();
994         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
995             assertTrue("Country code '" + countryCode + "' did not match "
996                             + ISO_COUNTRY_CODE_PATTERN,
997                     Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
998         } else {
999             // Non-telephony may still have the property defined if it has a SIM.
1000         }
1001     }
1002 
1003     @Test
testResetSettings()1004     public void testResetSettings() throws Exception {
1005         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1006             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
1007             return;
1008         }
1009 
1010         UserManager userManager = getContext().getSystemService(UserManager.class);
1011 
1012         boolean canChangeMobileNetworkSettings = userManager != null
1013                 && !userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
1014         assertTrue("Primary user must be able to configure mobile networks to pass this test",
1015                 canChangeMobileNetworkSettings);
1016 
1017         //First check permissions are correct
1018         try {
1019             mTelephonyManager.resetSettings();
1020             fail("TelephonyManager#resetSettings requires the"
1021                     + " android.Manifest.permission.NETWORK_SETTINGS permission");
1022         } catch (SecurityException e) {
1023             //expected
1024         }
1025         // and then do a reset to move data to default.
1026         try {
1027             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1028                     TelephonyManager::resetSettings, "android.permission.NETWORK_SETTINGS");
1029         } catch (SecurityException e) {
1030             fail("TelephonyManager#resetSettings requires the"
1031                     + " android.Manifest.permission.NETWORK_SETTINGS permission");
1032         }
1033 
1034         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(2);
1035         final ContentObserver mobileDataChangeObserver = new ContentObserver(
1036                 new Handler(Looper.getMainLooper())) {
1037             @Override
1038             public void onChange(boolean selfChange) {
1039                 queue.offer(isDataEnabled());
1040             }
1041         };
1042 
1043         getContext().getContentResolver().registerContentObserver(
1044                 getObservableDataEnabledUri(mTestSub), /* notifyForDescendants= */ false,
1045                 mobileDataChangeObserver);
1046         boolean defaultDataSetting = isDataEnabled();
1047 
1048         // set data to not the default!
1049         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1050                 tm -> tm.setDataEnabled(!defaultDataSetting));
1051         Boolean dataChangedResult = queue.poll(TOLERANCE, TimeUnit.MILLISECONDS);
1052         assertNotNull("Data setting was not changed", dataChangedResult);
1053         assertEquals("Data enable change didn't work", !defaultDataSetting,
1054                 dataChangedResult);
1055 
1056         // and then do a reset to move data to default again.
1057         try {
1058             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1059                     TelephonyManager::resetSettings, "android.permission.NETWORK_SETTINGS");
1060         } catch (SecurityException e) {
1061             fail("TelephonyManager#resetSettings requires the"
1062                     + " android.Manifest.permission.NETWORK_SETTINGS permission");
1063         }
1064         dataChangedResult = queue.poll(TOLERANCE, TimeUnit.MILLISECONDS);
1065         assertNotNull("Data setting was not changed", dataChangedResult);
1066         assertEquals("resetSettings did not reset default data", defaultDataSetting,
1067                 dataChangedResult);
1068     }
1069 
1070     @Test
testGetServiceState()1071     public void testGetServiceState() throws InterruptedException {
1072         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
1073             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
1074             return;
1075         }
1076 
1077         TestThread t = new TestThread(new Runnable() {
1078             public void run() {
1079                 Looper.prepare();
1080 
1081                 mListener = new PhoneStateListener() {
1082                     @Override
1083                     public void onServiceStateChanged(ServiceState serviceState) {
1084                         synchronized (mLock) {
1085                             mServiceState = serviceState;
1086                             mLock.notify();
1087                         }
1088                     }
1089                 };
1090                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
1091                 Looper.loop();
1092             }
1093         });
1094 
1095         synchronized (mLock) {
1096             t.start();
1097             mLock.wait(TOLERANCE);
1098         }
1099 
1100         assertEquals(mServiceState, mTelephonyManager.getServiceState());
1101     }
1102 
1103     @Test
testGetSimLocale()1104     public void testGetSimLocale() throws InterruptedException {
1105         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1106             Log.d(TAG,"skipping test that requires Telephony");
1107             return;
1108         }
1109         if (SubscriptionManager.getDefaultSubscriptionId()
1110                 == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1111             fail("Expected SIM inserted");
1112         }
1113         Locale locale = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1114                 (tm) -> tm.getSimLocale());
1115         Log.d(TAG, "testGetSimLocale: " + locale);
1116         assertNotNull(locale);
1117     }
1118 
1119     /**
1120      * Tests that a GSM device properly reports either the correct TAC (type allocation code) or
1121      * null.
1122      * The TAC should match the first 8 digits of the IMEI.
1123      */
1124     @Test
testGetTac()1125     public void testGetTac() {
1126         String tac = mTelephonyManager.getTypeAllocationCode();
1127         String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1128                 (tm) -> tm.getImei());
1129 
1130         if (tac == null || imei == null) {
1131             return;
1132         }
1133 
1134         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1135             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
1136                 assertEquals(imei.substring(0, 8), tac);
1137             }
1138         }
1139     }
1140 
1141     /**
1142      * Tests that a CDMA device properly reports either the correct MC (manufacturer code) or null.
1143      * The MC should match the first 8 digits of the MEID.
1144      */
1145     @Test
testGetMc()1146     public void testGetMc() {
1147         String mc = mTelephonyManager.getManufacturerCode();
1148         String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1149                 (tm) -> tm.getMeid());
1150 
1151         if (mc == null || meid == null) {
1152             return;
1153         }
1154 
1155         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1156             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
1157                 assertEquals(meid.substring(0, 8), mc);
1158             }
1159         }
1160     }
1161 
1162     /**
1163      * Tests that the device properly reports either a valid IMEI or null.
1164      */
1165     @Test
testGetImei()1166     public void testGetImei() {
1167         String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1168                 (tm) -> tm.getImei());
1169 
1170         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1171             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
1172                 assertImei(imei);
1173             }
1174         }
1175     }
1176 
1177     /**
1178      * Tests that the device properly reports either a valid IMEI or null.
1179      */
1180     @Test
testGetImeiForSlot()1181     public void testGetImeiForSlot() {
1182         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1183             return;
1184         }
1185 
1186         for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) {
1187             // The compiler error 'local variables referenced from a lambda expression must be final
1188             // or effectively final' is reported when using i, so assign it to a final variable.
1189             final int currI = i;
1190             String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1191                     (tm) -> tm.getImei(currI));
1192             if (!TextUtils.isEmpty(imei)) {
1193                 assertImei(imei);
1194             }
1195         }
1196 
1197         // Also verify that no exception is thrown for any slot index (including invalid ones)
1198         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1199                 (tm) -> tm.getImei(-1));
1200         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1201                 (tm) -> tm.getImei(mTelephonyManager.getPhoneCount()));
1202     }
1203 
1204     /**
1205      * Verifies that {@link TelephonyManager#getRadioPowerState()} does not throw any exception
1206      * and returns radio on.
1207      */
1208     @Test
testGetRadioPowerState()1209     public void testGetRadioPowerState() {
1210         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1211             return;
1212         }
1213 
1214         // Also verify that no exception is thrown.
1215         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
1216                 TelephonyManager.RADIO_POWER_ON);
1217     }
1218 
1219     /**
1220      * Verifies that {@link TelephonyManager#setCarrierDataEnabled(boolean)} does not throw any
1221      * exception. TODO enhance later if we have an API to get data enabled state.
1222      */
1223     @Test
testSetCarrierDataEnabled()1224     public void testSetCarrierDataEnabled() {
1225         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1226             return;
1227         }
1228         // Also verify that no exception is thrown.
1229         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1230                 (tm) -> tm.setCarrierDataEnabled(false));
1231         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1232                 (tm) -> tm.setCarrierDataEnabled(true));
1233     }
1234 
1235     /**
1236      * Verifies that {@link TelephonyManager#rebootRadio()} does not throw any exception
1237      * and final radio state is radio power on.
1238      */
1239     @Test
testRebootRadio()1240     public void testRebootRadio() throws Throwable {
1241         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1242             return;
1243         }
1244         assertEquals(mTelephonyManager.getServiceState().getState(), ServiceState.STATE_IN_SERVICE);
1245 
1246         TestThread t = new TestThread(new Runnable() {
1247             public void run() {
1248                 Looper.prepare();
1249 
1250                 mListener = new PhoneStateListener() {
1251                     @Override
1252                     public void onRadioPowerStateChanged(
1253                             @RadioPowerState int state) {
1254                         synchronized (mLock) {
1255                             if (state == TelephonyManager.RADIO_POWER_ON && mHasRadioPowerOff) {
1256                                 mRadioRebootTriggered = true;
1257                                 mLock.notify();
1258                             } else if (state == TelephonyManager.RADIO_POWER_OFF) {
1259                                 // reboot must go to power off
1260                                 mHasRadioPowerOff = true;
1261                             }
1262                         }
1263                     }
1264                 };
1265                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1266                         (tm) -> tm.listen(mListener,
1267                                 PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
1268                 Looper.loop();
1269             }
1270         });
1271 
1272         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
1273                 TelephonyManager.RADIO_POWER_ON);
1274         assertThat(mRadioRebootTriggered).isFalse();
1275         assertThat(mHasRadioPowerOff).isFalse();
1276         boolean success = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1277                 (tm) -> tm.rebootRadio());
1278         //skip this test if not supported or unsuccessful (success=false)
1279         if(!success) {
1280             return;
1281         }
1282 
1283         t.start();
1284         synchronized (mLock) {
1285             // reboot takes longer time
1286             if (!mRadioRebootTriggered) {
1287                 mLock.wait(10000);
1288             }
1289         }
1290         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
1291                 TelephonyManager.RADIO_POWER_ON);
1292         assertThat(mRadioRebootTriggered).isTrue();
1293 
1294         // note, other telephony states might not resumes properly at this point. e.g, service state
1295         // might still in the transition from OOS to In service. Thus we need to wait for in
1296         // service state before running next tests.
1297         t = new TestThread(new Runnable() {
1298             public void run() {
1299                 Looper.prepare();
1300 
1301                 mListener = new PhoneStateListener() {
1302                     @Override
1303                     public void onServiceStateChanged(ServiceState serviceState) {
1304                         synchronized (mLock) {
1305                             if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
1306                                 mServiceStateChangedCalled = true;
1307                                 mLock.notify();
1308                             }
1309                         }
1310                     }
1311                 };
1312                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1313                         (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE));
1314                 Looper.loop();
1315             }
1316         });
1317 
1318         synchronized (mLock) {
1319             t.start();
1320             if (!mServiceStateChangedCalled) {
1321                 mLock.wait(60000);
1322             }
1323         }
1324         assertThat(mTelephonyManager.getServiceState().getState()).isEqualTo(
1325                 ServiceState.STATE_IN_SERVICE);
1326     }
1327 
1328     /**
1329      * Verifies that {@link TelephonyManager#getAidForAppType(int)} does not throw any exception
1330      * for all supported subscription app type.
1331      */
1332     @Test
testGetAidForAppType()1333     public void testGetAidForAppType() {
1334         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1335             return;
1336         }
1337         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1338                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_SIM));
1339         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1340                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_CSIM));
1341         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1342                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_RUIM));
1343         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1344                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_ISIM));
1345         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1346                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_USIM));
1347     }
1348 
1349     /**
1350      * Verifies that {@link TelephonyManager#getIsimDomain()} does not throw any exception
1351      */
1352     @Test
testGetIsimDomain()1353     public void testGetIsimDomain() {
1354         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1355             return;
1356         }
1357         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1358                 (tm) -> tm.getIsimDomain());
1359     }
1360 
1361     /**
1362      * Verifies that {@link TelephonyManager#getIsimImpu()} does not throw any exception when called
1363      * and has the correct permissions.
1364      */
1365     @Ignore("API moved back to @hide for Android R.")
1366     @Test
testGetIsimImpu()1367     public void testGetIsimImpu() {
1368         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1369             return;
1370         }
1371         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1372                 TelephonyManager::getIsimImpu);
1373         // Try without the correct permissions and ensure it fails.
1374         try {
1375             mTelephonyManager.getIsimImpu();
1376             fail();
1377         } catch (SecurityException e) {
1378             // expected
1379         }
1380     }
1381 
1382     /**
1383      * Basic test to ensure {@link NetworkRegistrationInfo#getRegisteredPlmn()} provides valid
1384      * information.
1385      */
1386     @Test
testNetworkRegistrationInfoRegisteredPlmn()1387     public void testNetworkRegistrationInfoRegisteredPlmn() {
1388         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1389             return;
1390         }
1391         // get NetworkRegistration object
1392         ServiceState ss = mTelephonyManager.getServiceState();
1393         assertNotNull(ss);
1394 
1395         boolean hasRegistered = false;
1396         for (NetworkRegistrationInfo nwReg : ss.getNetworkRegistrationInfoList()) {
1397             if (nwReg.isRegistered()
1398                         && nwReg.getTransportType() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
1399                 hasRegistered = true;
1400                 String plmnId = nwReg.getRegisteredPlmn();
1401                 // CDMA doesn't have PLMN IDs. Rather than put CID|NID here, instead it will be
1402                 // empty. It's a case that's becoming less important over time, but for now a
1403                 // device that's only registered on CDMA needs to pass this test.
1404                 if (nwReg.getCellIdentity() instanceof android.telephony.CellIdentityCdma) {
1405                     assertTrue(TextUtils.isEmpty(plmnId));
1406                 } else {
1407                     assertFalse(TextUtils.isEmpty(plmnId));
1408                     assertTrue("PlmnId() out of range [00000 - 999999], PLMN ID=" + plmnId,
1409                             plmnId.matches("^[0-9]{5,6}$"));
1410                 }
1411             }
1412         }
1413         assertTrue(hasRegistered);
1414     }
1415 
1416     /**
1417      * Basic test to ensure {@link NetworkRegistrationInfo#isRoaming()} does not throw any
1418      * exception.
1419      */
1420     @Test
testNetworkRegistrationInfoIsRoaming()1421     public void testNetworkRegistrationInfoIsRoaming() {
1422         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1423             return;
1424         }
1425         // get NetworkRegistration object
1426         NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
1427                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
1428                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1429         assertThat(nwReg).isNotNull();
1430         nwReg.isRoaming();
1431     }
1432 
1433     /**
1434      * Basic test to ensure {@link NetworkRegistrationInfo#getRoamingType()} ()} does not throw any
1435      * exception and returns valid result
1436      * @see ServiceState.RoamingType
1437      */
1438     @Test
testNetworkRegistrationInfoGetRoamingType()1439     public void testNetworkRegistrationInfoGetRoamingType() {
1440         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1441             return;
1442         }
1443         // get NetworkRegistration object for voice
1444         NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
1445                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
1446                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1447         assertNotNull(nwReg);
1448         assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
1449 
1450         // getNetworkRegistration object for data
1451         // get NetworkRegistration object for voice
1452         nwReg = mTelephonyManager.getServiceState()
1453                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
1454                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1455         assertThat(nwReg).isNotNull();
1456         assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
1457     }
1458 
1459     /**
1460      * Basic test to ensure {@link NetworkRegistrationInfo#getAccessNetworkTechnology()} not
1461      * throw any exception and returns valid result
1462      * @see android.telephony.Annotation.NetworkType
1463      */
1464     @Test
testNetworkRegistationStateGetAccessNetworkTechnology()1465     public void testNetworkRegistationStateGetAccessNetworkTechnology() {
1466         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1467             return;
1468         }
1469         // get NetworkRegistration object for voice
1470         NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
1471                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
1472                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1473         assertThat(nwReg).isNotNull();
1474         assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
1475 
1476         // get NetworkRegistation object for data
1477         nwReg = mTelephonyManager.getServiceState()
1478                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
1479                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1480         assertThat(nwReg).isNotNull();
1481         assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
1482     }
1483 
1484 
1485     /**
1486      * Tests that the device properly reports either a valid MEID or null.
1487      */
1488     @Test
testGetMeid()1489     public void testGetMeid() {
1490         String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1491                 (tm) -> tm.getMeid());
1492 
1493         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1494             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
1495                 assertMeidEsn(meid);
1496             }
1497         }
1498     }
1499 
1500     /**
1501      * Tests that the device properly reports either a valid MEID or null.
1502      */
1503     @Test
testGetMeidForSlot()1504     public void testGetMeidForSlot() {
1505         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1506             return;
1507         }
1508 
1509         SubscriptionManager sm = getContext().getSystemService(SubscriptionManager.class);
1510         List<SubscriptionInfo> subInfos = sm.getActiveSubscriptionInfoList();
1511 
1512         if (subInfos != null) {
1513             for (SubscriptionInfo subInfo : subInfos) {
1514                 int slotIndex = subInfo.getSimSlotIndex();
1515                 int subId = subInfo.getSubscriptionId();
1516                 TelephonyManager tm = mTelephonyManager.createForSubscriptionId(subId);
1517                 if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
1518                     String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(
1519                             mTelephonyManager,
1520                             (telephonyManager) -> telephonyManager.getMeid(slotIndex));
1521 
1522                     if (!TextUtils.isEmpty(meid)) {
1523                         assertMeidEsn(meid);
1524                     }
1525                 }
1526             }
1527         }
1528 
1529         // Also verify that no exception is thrown for any slot index (including invalid ones)
1530         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1531                 (tm) -> tm.getMeid(-1));
1532         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1533                 (tm) -> tm.getMeid(mTelephonyManager.getPhoneCount()));
1534     }
1535 
1536     /**
1537      * Tests sendDialerSpecialCode API.
1538      * Expects a security exception since the caller does not have carrier privileges or is not the
1539      * current default dialer app.
1540      */
1541     @Test
testSendDialerSpecialCode()1542     public void testSendDialerSpecialCode() {
1543         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1544             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
1545             return;
1546         }
1547         try {
1548             mTelephonyManager.sendDialerSpecialCode("4636");
1549             fail("Expected SecurityException. App does not have carrier privileges or is not the "
1550                     + "default dialer app");
1551         } catch (SecurityException expected) {
1552         }
1553     }
1554 
1555     /**
1556      * Tests that the device properly reports the contents of EF_FPLMN or null
1557      */
1558     @Test
testGetForbiddenPlmns()1559     public void testGetForbiddenPlmns() {
1560         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1561             return;
1562         }
1563         String[] plmns = mTelephonyManager.getForbiddenPlmns();
1564 
1565         int phoneType = mTelephonyManager.getPhoneType();
1566         switch (phoneType) {
1567             case TelephonyManager.PHONE_TYPE_GSM:
1568                 assertNotNull("Forbidden PLMNs must be valid or an empty list!", plmns);
1569             case TelephonyManager.PHONE_TYPE_CDMA:
1570             case TelephonyManager.PHONE_TYPE_NONE:
1571                 if (plmns == null) {
1572                     return;
1573                 }
1574         }
1575 
1576         for(String plmn : plmns) {
1577             assertTrue(
1578                     "Invalid Length for PLMN-ID, must be 5 or 6! plmn=" + plmn,
1579                     plmn.length() >= 5 && plmn.length() <= 6);
1580             assertTrue(
1581                     "PLMNs must be strings of digits 0-9! plmn=" + plmn,
1582                     android.text.TextUtils.isDigitsOnly(plmn));
1583         }
1584     }
1585 
1586     /**
1587      * Tests that the device properly sets and pads the contents of EF_FPLMN
1588      */
1589     @Test
testSetForbiddenPlmns()1590     public void testSetForbiddenPlmns() {
1591         if (!supportSetFplmn()) {
1592             return;
1593         }
1594         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
1595         try {
1596             int numFplmnsSet = mTelephonyManager.setForbiddenPlmns(FPLMN_TEST);
1597             String[] writtenFplmns = mTelephonyManager.getForbiddenPlmns();
1598             assertEquals("Wrong return value for setFplmns with less than required fplmns: "
1599                     + numFplmnsSet, FPLMN_TEST.size(), numFplmnsSet);
1600             assertEquals("Wrong Fplmns content written", FPLMN_TEST, Arrays.asList(writtenFplmns));
1601         } finally {
1602             // Restore
1603             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
1604         }
1605     }
1606 
1607     /**
1608      * Tests that the device properly truncates the contents of EF_FPLMN when provided size
1609      * is too big.
1610      */
1611     @Test
testSetForbiddenPlmnsTruncate()1612     public void testSetForbiddenPlmnsTruncate() {
1613         if (!supportSetFplmn()) {
1614             return;
1615         }
1616         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
1617         try {
1618             List<String> targetFplmns = new ArrayList<>();
1619             for (int i = 0; i < MIN_FPLMN_NUM; i++) {
1620                 targetFplmns.add(PLMN_A);
1621             }
1622             for (int i = MIN_FPLMN_NUM; i < MAX_FPLMN_NUM; i++) {
1623                 targetFplmns.add(PLMN_B);
1624             }
1625             int numFplmnsSet = mTelephonyManager.setForbiddenPlmns(targetFplmns);
1626             String[] writtenFplmns = mTelephonyManager.getForbiddenPlmns();
1627             assertTrue("Wrong return value for setFplmns with overflowing fplmns: " + numFplmnsSet,
1628                     numFplmnsSet < MAX_FPLMN_NUM);
1629             assertEquals("Number of Fplmns set does not equal number of Fplmns available",
1630                     numFplmnsSet, writtenFplmns.length);
1631             assertEquals("Wrong Fplmns content written", targetFplmns.subList(0, numFplmnsSet),
1632                     Arrays.asList(writtenFplmns));
1633         } finally {
1634             // Restore
1635             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
1636         }
1637     }
1638 
1639     /**
1640      * Tests that the device properly deletes the contents of EF_FPLMN
1641      */
1642     @Test
testSetForbiddenPlmnsDelete()1643     public void testSetForbiddenPlmnsDelete() {
1644         if (!supportSetFplmn()) {
1645             return;
1646         }
1647         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
1648         try {
1649             // Support test for empty SIM
1650             List<String> targetDummyFplmns = new ArrayList<>();
1651             for (int i = 0; i < MIN_FPLMN_NUM; i++) {
1652                 targetDummyFplmns.add(PLMN_A);
1653             }
1654             mTelephonyManager.setForbiddenPlmns(targetDummyFplmns);
1655             String[] writtenDummyFplmns = mTelephonyManager.getForbiddenPlmns();
1656             assertEquals(targetDummyFplmns, Arrays.asList(writtenDummyFplmns));
1657 
1658             List<String> targetFplmns = new ArrayList<>();
1659             int numFplmnsSet = mTelephonyManager.setForbiddenPlmns(targetFplmns);
1660             String[] writtenFplmns = mTelephonyManager.getForbiddenPlmns();
1661             assertEquals("Wrong return value for setFplmns with empty list", 0, numFplmnsSet);
1662             assertEquals("Wrong number of Fplmns written", 0, writtenFplmns.length);
1663             // TODO wait for 10 minutes or so for the FPLMNS list to grow back
1664         } finally {
1665             // Restore
1666             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
1667         }
1668     }
1669 
1670 
1671     /**
1672      * Tests that setForbiddenPlmns properly handles null input
1673      */
1674     @Test
testSetForbiddenPlmnsVoid()1675     public void testSetForbiddenPlmnsVoid() {
1676         if (!supportSetFplmn()) {
1677             return;
1678         }
1679         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
1680         try {
1681             mTelephonyManager.setForbiddenPlmns(null);
1682             fail("Expected IllegalArgumentException. Null input is not allowed");
1683         } catch (IllegalArgumentException expected) {
1684         } finally {
1685             // Restore
1686             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
1687         }
1688     }
1689 
1690     /**
1691      * Verify that TelephonyManager.getCardIdForDefaultEuicc returns a positive value or either
1692      * UNINITIALIZED_CARD_ID or UNSUPPORTED_CARD_ID.
1693      */
1694     @Test
testGetCardIdForDefaultEuicc()1695     public void testGetCardIdForDefaultEuicc() {
1696         int cardId = mTelephonyManager.getCardIdForDefaultEuicc();
1697         assertTrue("Card ID for default EUICC is not a valid value",
1698                 cardId == TelephonyManager.UNSUPPORTED_CARD_ID
1699                         || cardId == TelephonyManager.UNINITIALIZED_CARD_ID
1700                         || cardId >= 0);
1701     }
1702 
1703     /**
1704      * Tests that a SecurityException is thrown when trying to access UiccCardsInfo.
1705      */
1706     @Test
testGetUiccCardsInfoException()1707     public void testGetUiccCardsInfoException() {
1708         try {
1709             // Requires READ_PRIVILEGED_PHONE_STATE or carrier privileges
1710             List<UiccCardInfo> infos = mTelephonyManager.getUiccCardsInfo();
1711             fail("Expected SecurityException. App does not have carrier privileges");
1712         } catch (SecurityException e) {
1713         }
1714     }
1715 
1716     /**
1717      * Tests that UiccCardsInfo methods don't crash.
1718      */
1719     @Test
testGetUiccCardsInfo()1720     public void testGetUiccCardsInfo() {
1721         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1722             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
1723             return;
1724         }
1725         // Requires READ_PRIVILEGED_PHONE_STATE or carrier privileges
1726         List<UiccCardInfo> infos =
1727                 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1728                 (tm) -> tm.getUiccCardsInfo());
1729         // test that these methods don't crash
1730         if (infos.size() > 0) {
1731             UiccCardInfo info = infos.get(0);
1732             info.getIccId();
1733             info.getEid();
1734             info.isRemovable();
1735             info.isEuicc();
1736             info.getCardId();
1737             info.getSlotIndex();
1738         }
1739     }
1740 
getContext()1741     private static Context getContext() {
1742         return InstrumentationRegistry.getContext();
1743     }
1744 
1745     /**
1746      * Tests that the device properly sets the network selection mode to automatic.
1747      * Expects a security exception since the caller does not have carrier privileges.
1748      */
1749     @Test
testSetNetworkSelectionModeAutomatic()1750     public void testSetNetworkSelectionModeAutomatic() {
1751         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1752             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
1753             return;
1754         }
1755         try {
1756             mTelephonyManager.setNetworkSelectionModeAutomatic();
1757             fail("Expected SecurityException. App does not have carrier privileges.");
1758         } catch (SecurityException expected) {
1759         }
1760     }
1761 
1762     /**
1763      * Tests that the device properly asks the radio to connect to the input network and change
1764      * selection mode to manual.
1765      * Expects a security exception since the caller does not have carrier privileges.
1766      */
1767     @Test
testSetNetworkSelectionModeManual()1768     public void testSetNetworkSelectionModeManual() {
1769         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1770             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
1771             return;
1772         }
1773         try {
1774             mTelephonyManager.setNetworkSelectionModeManual(
1775                     "" /* operatorNumeric */, false /* persistSelection */);
1776             fail("Expected SecurityException. App does not have carrier privileges.");
1777         } catch (SecurityException expected) {
1778         }
1779     }
1780 
1781     /**
1782      * Construct a CallAttributes object and test getters.
1783      */
1784     @Test
testCallAttributes()1785     public void testCallAttributes() {
1786         CallQuality cq = new CallQuality();
1787         PreciseCallState pcs = new PreciseCallState();
1788         CallAttributes ca = new CallAttributes(pcs, TelephonyManager.NETWORK_TYPE_UNKNOWN, cq);
1789         assertEquals(pcs, ca.getPreciseCallState());
1790         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, ca.getNetworkType());
1791         assertEquals(cq, ca.getCallQuality());
1792     }
1793 
1794     /**
1795      * Checks that a zeroed-out default CallQuality object can be created
1796      */
1797     @Test
testCallQuality()1798     public void testCallQuality() {
1799         CallQuality cq = new CallQuality();
1800         assertEquals(0, cq.getDownlinkCallQualityLevel());
1801         assertEquals(0, cq.getUplinkCallQualityLevel());
1802         assertEquals(0, cq.getCallDuration());
1803         assertEquals(0, cq.getNumRtpPacketsTransmitted());
1804         assertEquals(0, cq.getNumRtpPacketsReceived());
1805         assertEquals(0, cq.getNumRtpPacketsTransmittedLost());
1806         assertEquals(0, cq.getNumRtpPacketsNotReceived());
1807         assertEquals(0, cq.getAverageRelativeJitter());
1808         assertEquals(0, cq.getMaxRelativeJitter());
1809         assertEquals(0, cq.getAverageRoundTripTime());
1810         assertEquals(0, cq.getCodecType());
1811     }
1812 
1813 
1814     // Reference: packages/services/Telephony/ecc/input/eccdata.txt
1815     private static final Map<String, String> EMERGENCY_NUMBERS_FOR_COUNTRIES =
1816             new HashMap<String, String>() {{
1817                 put("au", "000");
1818                 put("ca", "911");
1819                 put("de", "112");
1820                 put("gb", "999");
1821                 put("in", "112");
1822                 put("jp", "110");
1823                 put("sg", "999");
1824                 put("tw", "110");
1825                 put("us", "911");
1826             }};
1827 
1828     /**
1829      * Tests TelephonyManager.getEmergencyNumberList.
1830      *
1831      * Also enforce country-specific emergency number in CTS.
1832      */
1833     @Test
testGetEmergencyNumberList()1834     public void testGetEmergencyNumberList() {
1835         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1836             return;
1837         }
1838         Map<Integer, List<EmergencyNumber>> emergencyNumberList =
1839                 mTelephonyManager.getEmergencyNumberList();
1840 
1841         assertFalse(emergencyNumberList == null);
1842 
1843         checkEmergencyNumberFormat(emergencyNumberList);
1844 
1845         int defaultSubId = mSubscriptionManager.getDefaultSubscriptionId();
1846         for (Map.Entry<String, String> entry : EMERGENCY_NUMBERS_FOR_COUNTRIES.entrySet()) {
1847             if (mTelephonyManager.getNetworkCountryIso().equals(entry.getKey())) {
1848                 assertTrue(checkIfEmergencyNumberListHasSpecificAddress(
1849                         emergencyNumberList.get(defaultSubId), entry.getValue()));
1850             }
1851         }
1852     }
1853 
1854     /**
1855      * Tests TelephonyManager.isEmergencyNumber.
1856      *
1857      * Also enforce country-specific emergency number in CTS.
1858      */
1859     @Test
testIsEmergencyNumber()1860     public void testIsEmergencyNumber() {
1861         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1862             return;
1863         }
1864 
1865         for (Map.Entry<String, String> entry : EMERGENCY_NUMBERS_FOR_COUNTRIES.entrySet()) {
1866             if (mTelephonyManager.getNetworkCountryIso().equals(entry.getKey())) {
1867                 assertTrue(mTelephonyManager.isEmergencyNumber(entry.getValue()));
1868             }
1869         }
1870     }
1871 
1872     /**
1873      * Tests TelephonyManager.isPotentialEmergencyNumber.
1874      */
1875     @Test
testIsPotentialEmergencyNumber()1876     public void testIsPotentialEmergencyNumber() {
1877         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1878             return;
1879         }
1880 
1881         String countryIso = mTelephonyManager.getNetworkCountryIso();
1882         String potentialEmergencyAddress = "91112345";
1883         // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
1884         // these countries, if extra digits are added to an emergency number,
1885         // it no longer connects to the emergency service.
1886         if (countryIso.equals("br") || countryIso.equals("cl") || countryIso.equals("ni")) {
1887             assertFalse(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1888                     (tm) -> tm.isPotentialEmergencyNumber(potentialEmergencyAddress)));
1889         } else {
1890             assertTrue(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1891                     (tm) -> tm.isPotentialEmergencyNumber(potentialEmergencyAddress)));
1892         }
1893     }
1894 
1895     /**
1896      * Tests {@link TelephonyManager#getSupportedRadioAccessFamily()}
1897      */
1898     @Test
testGetRadioAccessFamily()1899     public void testGetRadioAccessFamily() {
1900         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1901             return;
1902         }
1903         long raf = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1904                 (tm) -> tm.getSupportedRadioAccessFamily());
1905         assertThat(raf).isNotEqualTo(TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN);
1906     }
1907 
assertSetOpportunisticSubSuccess(int value)1908     private static void assertSetOpportunisticSubSuccess(int value) {
1909         assertThat(value).isEqualTo(TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS);
1910     }
1911 
assertSetOpportunisticNoOpportunisticSub(int value)1912     private static void assertSetOpportunisticNoOpportunisticSub(int value) {
1913         assertThat(value).isEqualTo(
1914                 TelephonyManager.SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE);
1915     }
1916 
1917     /**
1918      * Tests {@link TelephonyManager#setPreferredOpportunisticDataSubscription} and
1919      * {@link TelephonyManager#getPreferredOpportunisticDataSubscription}
1920      */
1921     @Test
testPreferredOpportunisticDataSubscription()1922     public void testPreferredOpportunisticDataSubscription() {
1923         int randomSubId = 1;
1924         int activeSubscriptionInfoCount = ShellIdentityUtils.invokeMethodWithShellPermissions(
1925                 mSubscriptionManager, (tm) -> tm.getActiveSubscriptionInfoCount());
1926         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1927             return;
1928         }
1929         if (mTelephonyManager.getPhoneCount() == 1) {
1930             return;
1931         }
1932         if (mTelephonyManager.getPhoneCount() == 2 && activeSubscriptionInfoCount != 2) {
1933             return;
1934         }
1935         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1936                 (tm) -> tm.setPreferredOpportunisticDataSubscription(
1937                         SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false,
1938                         null, null));
1939         // wait for the data change to take effect
1940         waitForMs(500);
1941         int subId =
1942                 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1943                         (tm) -> tm.getPreferredOpportunisticDataSubscription());
1944         assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
1945         List<SubscriptionInfo> subscriptionInfoList =
1946                 ShellIdentityUtils.invokeMethodWithShellPermissions(mSubscriptionManager,
1947                         (tm) -> tm.getOpportunisticSubscriptions());
1948         Consumer<Integer> callbackSuccess = TelephonyManagerTest::assertSetOpportunisticSubSuccess;
1949         Consumer<Integer> callbackNoOpSub =
1950                 TelephonyManagerTest::assertSetOpportunisticNoOpportunisticSub;
1951         if (subscriptionInfoList == null || subscriptionInfoList.size() == 0) {
1952             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1953                     (tm) -> tm.setPreferredOpportunisticDataSubscription(randomSubId, false,
1954                             AsyncTask.SERIAL_EXECUTOR, callbackNoOpSub));
1955             // wait for the data change to take effect
1956             waitForMs(500);
1957             subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1958                     (tm) -> tm.getPreferredOpportunisticDataSubscription());
1959             assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
1960         } else {
1961             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1962                     (tm) -> tm.setPreferredOpportunisticDataSubscription(
1963                             subscriptionInfoList.get(0).getSubscriptionId(), false,
1964                             AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
1965             // wait for the data change to take effect
1966             waitForMs(500);
1967             subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1968                     (tm) -> tm.getPreferredOpportunisticDataSubscription());
1969             assertThat(subId).isEqualTo(subscriptionInfoList.get(0).getSubscriptionId());
1970         }
1971 
1972         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1973                 (tm) -> tm.setPreferredOpportunisticDataSubscription(
1974                         SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false,
1975                         AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
1976         // wait for the data change to take effect
1977         waitForMs(500);
1978         subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1979                 (tm) -> tm.getPreferredOpportunisticDataSubscription());
1980         assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
1981     }
1982 
assertUpdateAvailableNetworkSuccess(int value)1983     private static void assertUpdateAvailableNetworkSuccess(int value) {
1984         assertThat(value).isEqualTo(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS);
1985     }
1986 
assertUpdateAvailableNetworkNoOpportunisticSub(int value)1987     private static void assertUpdateAvailableNetworkNoOpportunisticSub(int value) {
1988         assertThat(value).isEqualTo(
1989                 TelephonyManager.UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE);
1990     }
1991 
checkIfEmergencyNumberListHasSpecificAddress( List<EmergencyNumber> emergencyNumberList, String address)1992     private static boolean checkIfEmergencyNumberListHasSpecificAddress(
1993             List<EmergencyNumber> emergencyNumberList, String address) {
1994         for (EmergencyNumber emergencyNumber : emergencyNumberList) {
1995             if (address.equals(emergencyNumber.getNumber())) {
1996                 return true;
1997             }
1998         }
1999         return false;
2000     }
2001 
checkEmergencyNumberFormat( Map<Integer, List<EmergencyNumber>> emergencyNumberLists)2002     private static void checkEmergencyNumberFormat(
2003             Map<Integer, List<EmergencyNumber>> emergencyNumberLists) {
2004         for (List<EmergencyNumber> emergencyNumberList : emergencyNumberLists.values()) {
2005             for (EmergencyNumber emergencyNumber : emergencyNumberList) {
2006 
2007                 // Validate Emergency number address
2008                 assertTrue(validateEmergencyNumberAddress(emergencyNumber.getNumber()));
2009 
2010                 // Validate Emergency number country Iso
2011                 assertTrue(validateEmergencyNumberCountryIso(emergencyNumber.getCountryIso()));
2012 
2013                 // Validate Emergency number mnc
2014                 assertTrue(validateEmergencyNumberMnc(emergencyNumber.getMnc()));
2015 
2016                 // Validate Emergency service category list
2017                 assertTrue(validateEmergencyServiceCategoryList(
2018                         emergencyNumber.getEmergencyServiceCategories()));
2019 
2020                 // Validate Emergency number source list
2021                 assertTrue(validateEmergencyNumberSourceList(
2022                         emergencyNumber.getEmergencyNumberSources()));
2023 
2024                 // Validate Emergency URN list
2025                 // (just verify it is not null, because the support of this field is optional)
2026                 assertTrue(emergencyNumber.getEmergencyUrns() != null);
2027 
2028                 // Validat Emergency call routing
2029                 assertTrue(validateEmergencyCallRouting(
2030                         emergencyNumber.getEmergencyCallRouting()));
2031 
2032                 // Valid the emergency number should be at least in a valid source.
2033                 assertTrue(validateEmergencyNumberFromAnySource(emergencyNumber));
2034 
2035                 // Valid the emergency number should be at least in a valid category.
2036                 assertTrue(validateEmergencyNumberInAnyCategory(emergencyNumber));
2037             }
2038 
2039             // Validate compareTo
2040             assertTrue(validateEmergencyNumberCompareTo(emergencyNumberList));
2041         }
2042     }
2043 
2044     /**
2045      * Tests {@link TelephonyManager#updateAvailableNetworks}
2046      */
2047     @Test
testUpdateAvailableNetworks()2048     public void testUpdateAvailableNetworks() {
2049         int randomSubId = 1;
2050         int activeSubscriptionInfoCount = ShellIdentityUtils.invokeMethodWithShellPermissions(
2051                 mSubscriptionManager, (tm) -> tm.getActiveSubscriptionInfoCount());
2052         boolean isOpportunisticNetworkEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(
2053                 mTelephonyManager, (tm) -> tm.isOpportunisticNetworkEnabled());
2054 
2055         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2056             return;
2057         }
2058         if (!isOpportunisticNetworkEnabled) {
2059             return;
2060         }
2061         if (mTelephonyManager.getPhoneCount() == 1) {
2062             return;
2063         }
2064         if (mTelephonyManager.getPhoneCount() == 2 && activeSubscriptionInfoCount != 2) {
2065             return;
2066         }
2067 
2068         List<SubscriptionInfo> subscriptionInfoList =
2069                 ShellIdentityUtils.invokeMethodWithShellPermissions(mSubscriptionManager,
2070                         (tm) -> tm.getOpportunisticSubscriptions());
2071         List<String> mccMncs = new ArrayList<String>();
2072         List<Integer> bands = new ArrayList<Integer>();
2073         List<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<AvailableNetworkInfo>();
2074         Consumer<Integer> callbackSuccess =
2075                 TelephonyManagerTest::assertUpdateAvailableNetworkSuccess;
2076         Consumer<Integer> callbackNoOpSub =
2077                 TelephonyManagerTest::assertUpdateAvailableNetworkNoOpportunisticSub;
2078         if (subscriptionInfoList == null || subscriptionInfoList.size() == 0
2079                 || !mSubscriptionManager.isActiveSubscriptionId(
2080                 subscriptionInfoList.get(0).getSubscriptionId())) {
2081             AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(randomSubId,
2082                     AvailableNetworkInfo.PRIORITY_HIGH, mccMncs, bands);
2083             availableNetworkInfos.add(availableNetworkInfo);
2084             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2085                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2086                             AsyncTask.SERIAL_EXECUTOR, callbackNoOpSub));
2087             // wait for the data change to take effect
2088             waitForMs(500);
2089             // clear all the operations at the end of test.
2090             availableNetworkInfos.clear();
2091             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2092                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2093                             AsyncTask.SERIAL_EXECUTOR, callbackNoOpSub));
2094         } else {
2095             AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(
2096                     subscriptionInfoList.get(0).getSubscriptionId(),
2097                     AvailableNetworkInfo.PRIORITY_HIGH, mccMncs, bands);
2098             availableNetworkInfos.add(availableNetworkInfo);
2099             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2100                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2101                             AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
2102             // wait for the data change to take effect
2103             waitForMs(500);
2104             // clear all the operations at the end of test.
2105             availableNetworkInfos.clear();
2106             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2107                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2108                             AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
2109         }
2110     }
2111 
2112     @Test
testSwitchMultiSimConfig()2113     public void testSwitchMultiSimConfig() {
2114         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2115             return;
2116         }
2117         try {
2118             mTelephonyManager.switchMultiSimConfig(mTelephonyManager.getActiveModemCount());
2119             fail("TelephonyManager#switchMultiSimConfig should require the MODIFY_PHONE_STATE"
2120                     + " permission to access.");
2121         } catch (SecurityException e) {
2122             // expected
2123         }
2124         try {
2125             // This should result in no-op.
2126             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mTelephonyManager,
2127                     (tm) -> tm.switchMultiSimConfig(mTelephonyManager.getActiveModemCount()),
2128                     SecurityException.class, "android.permission.MODIFY_PHONE_STATE");
2129         } catch (SecurityException e) {
2130             fail("TelephonyManager#switchMultiSimConfig should require MODIFY_PHONE_STATE"
2131                     + "permission to access.");
2132         }
2133     }
2134 
2135     @Test
testIccOpenLogicalChannelBySlot()2136     public void testIccOpenLogicalChannelBySlot() {
2137         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2138             return;
2139         }
2140         // just verify no crash
2141         try {
2142             ShellIdentityUtils.invokeMethodWithShellPermissions(
2143                     mTelephonyManager, (tm) -> tm.iccOpenLogicalChannelBySlot(0, null, 0));
2144         } catch (IllegalArgumentException e) {
2145             // IllegalArgumentException is okay, just not SecurityException
2146         }
2147     }
2148 
2149     @Test
testIccCloseLogicalChannelBySlot()2150     public void testIccCloseLogicalChannelBySlot() {
2151         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2152             return;
2153         }
2154         // just verify no crash
2155         try {
2156             ShellIdentityUtils.invokeMethodWithShellPermissions(
2157                     mTelephonyManager, (tm) -> tm.iccCloseLogicalChannelBySlot(0, 0));
2158         } catch (IllegalArgumentException e) {
2159             // IllegalArgumentException is okay, just not SecurityException
2160         }
2161     }
2162 
2163     @Test
testIccTransmitApduLogicalChannelBySlot()2164     public void testIccTransmitApduLogicalChannelBySlot() {
2165         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2166             return;
2167         }
2168         int slotIndex = getValidSlotIndex();
2169         String result = ShellIdentityUtils.invokeMethodWithShellPermissions(
2170                 mTelephonyManager, (tm) -> tm.iccTransmitApduLogicalChannelBySlot(
2171                         slotIndex,
2172                         0 /* channel */,
2173                         0 /* cla */,
2174                         0 /* instruction */,
2175                         0 /* p1 */,
2176                         0 /* p2 */,
2177                         0 /* p3 */,
2178                         null /* data */));
2179         assertTrue(TextUtils.isEmpty(result));
2180     }
2181 
2182     @Test
testIccTransmitApduBasicChannelBySlot()2183     public void testIccTransmitApduBasicChannelBySlot() {
2184         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2185             return;
2186         }
2187         // just verify no crash
2188         int slotIndex = getValidSlotIndex();
2189         try {
2190             ShellIdentityUtils.invokeMethodWithShellPermissions(
2191                     mTelephonyManager, (tm) -> tm.iccTransmitApduBasicChannelBySlot(
2192                             slotIndex,
2193                             0 /* cla */,
2194                             0 /* instruction */,
2195                             0 /* p1 */,
2196                             0 /* p2 */,
2197                             0 /* p3 */,
2198                             null /* data */));
2199         } catch (IllegalArgumentException e ) {
2200             // IllegalArgumentException is okay, just not SecurityException
2201         }
2202     }
2203 
2204     @Test
testIsIccLockEnabled()2205     public void testIsIccLockEnabled() {
2206         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2207             return;
2208         }
2209         // verify SecurityException
2210         try {
2211             mTelephonyManager.isIccLockEnabled();
2212             fail("testIsIccLockEnabled: Expected SecurityException on isIccLockEnabled");
2213         } catch (SecurityException se) {
2214             // expected
2215         }
2216 
2217         // test with permission
2218         try {
2219             ShellIdentityUtils.invokeMethodWithShellPermissions(
2220                     mTelephonyManager, (tm) -> tm.isIccLockEnabled());
2221         } catch (SecurityException se) {
2222             fail("testIsIccLockEnabled: SecurityException not expected");
2223         }
2224     }
2225 
2226     @Test
testIsDataEnabledForApn()2227     public void testIsDataEnabledForApn() {
2228         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2229             return;
2230         }
2231         // verify SecurityException
2232         try {
2233             mTelephonyManager.isDataEnabledForApn(ApnSetting.TYPE_MMS);
2234             fail("testIsDataEnabledForApn: Expected SecurityException on isDataEnabledForApn");
2235         } catch (SecurityException se) {
2236             // expected
2237         }
2238 
2239         // test with permission
2240         try {
2241             ShellIdentityUtils.invokeMethodWithShellPermissions(
2242                     mTelephonyManager, (tm) -> tm.isDataEnabledForApn(ApnSetting.TYPE_MMS));
2243         } catch (SecurityException se) {
2244             fail("testIsDataEnabledForApn: SecurityException not expected");
2245         }
2246     }
2247 
2248     @Test
testIsTetheringApnRequired()2249     public void testIsTetheringApnRequired() {
2250         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2251             return;
2252         }
2253         // verify SecurityException
2254         try {
2255             mTelephonyManager.isTetheringApnRequired();
2256             fail("testIsTetheringApnRequired: Expected SecurityException on "
2257                     + "isTetheringApnRequired");
2258         } catch (SecurityException se) {
2259             // expected
2260         }
2261 
2262         // test with permission
2263         try {
2264             ShellIdentityUtils.invokeMethodWithShellPermissions(
2265                     mTelephonyManager, (tm) -> tm.isTetheringApnRequired());
2266         } catch (SecurityException se) {
2267             fail("testIsIccLockEnabled: SecurityException not expected");
2268         }
2269     }
2270 
2271     @Test
testGetCarrierInfoForImsiEncryption()2272     public void testGetCarrierInfoForImsiEncryption() {
2273         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2274             return;
2275         }
2276         // test without permission: verify SecurityException
2277         try {
2278             mTelephonyManager.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_EPDG);
2279             fail("testGetCarrierInfoForImsiEncryption: "
2280                     + "SecurityException expected on getCarrierInfoForImsiEncryption");
2281         } catch (SecurityException se) {
2282             // expected
2283         }
2284         try {
2285             mTelephonyManager.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_WLAN);
2286             fail("testGetCarrierInfoForImsiEncryption: "
2287                     + "SecurityException expected on getCarrierInfoForImsiEncryption");
2288         } catch (SecurityException se) {
2289             // expected
2290         }
2291         // test with permission
2292         try {
2293             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2294                     (tm) -> tm.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_EPDG));
2295         } catch (SecurityException se) {
2296             fail("testGetCarrierInfoForImsiEncryption: SecurityException not expected");
2297         } catch (IllegalArgumentException iae) {
2298             // IllegalArgumentException is okay, just not SecurityException
2299         }
2300         try {
2301             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2302                     (tm) -> tm.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_WLAN));
2303         } catch (SecurityException se) {
2304             fail("testGetCarrierInfoForImsiEncryption: SecurityException not expected");
2305         } catch (IllegalArgumentException iae) {
2306             // IllegalArgumentException is okay, just not SecurityException
2307         }
2308     }
2309 
2310     @Test
testResetCarrierKeysForImsiEncryption()2311     public void testResetCarrierKeysForImsiEncryption() {
2312         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2313             return;
2314         }
2315         // test without permission: verify SecurityException
2316         try {
2317             mTelephonyManager.resetCarrierKeysForImsiEncryption();
2318             fail("testResetCarrierKeysForImsiEncryption: SecurityException expected");
2319         } catch (SecurityException se) {
2320             // expected
2321         }
2322         // test with permission
2323         try {
2324             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2325                     mTelephonyManager,
2326                     (tm) -> tm.resetCarrierKeysForImsiEncryption());
2327         } catch (SecurityException se) {
2328             fail("testResetCarrierKeysForImsiEncryption: SecurityException not expected");
2329         }
2330     }
2331 
2332     @Test
testIsInEmergencySmsMode()2333     public void testIsInEmergencySmsMode() {
2334         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2335             return;
2336         }
2337         // test without permission: verify SecurityException
2338         try {
2339             mTelephonyManager.isInEmergencySmsMode();
2340             fail("testIsInEmergencySmsMode: SecurityException expected");
2341         } catch (SecurityException se) {
2342             // expected
2343         }
2344         // test with permission
2345         try {
2346             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2347                     mTelephonyManager,
2348                     (tm) -> tm.isInEmergencySmsMode());
2349         } catch (SecurityException se) {
2350             fail("testIsInEmergencySmsMode: SecurityException not expected");
2351         }
2352     }
2353 
2354     @Test
testSetAllowedNetworkTypes()2355     public void testSetAllowedNetworkTypes() {
2356         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2357             return;
2358         }
2359 
2360         // test without permission: verify SecurityException
2361         long allowedNetworkTypes = TelephonyManager.NETWORK_TYPE_BITMASK_NR;
2362         try {
2363             mTelephonyManager.setAllowedNetworkTypes(allowedNetworkTypes);
2364             fail("testSetPolicyDataEnabled: SecurityException expected");
2365         } catch (SecurityException se) {
2366             // expected
2367         }
2368 
2369         // test with permission
2370         try {
2371             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2372                     mTelephonyManager,
2373                     (tm) -> tm.setAllowedNetworkTypes(allowedNetworkTypes));
2374 
2375             long deviceAllowedNetworkTypes = ShellIdentityUtils.invokeMethodWithShellPermissions(
2376                     mTelephonyManager, (tm) -> {
2377                         return tm.getAllowedNetworkTypes();
2378                     }
2379             );
2380             assertEquals(allowedNetworkTypes, deviceAllowedNetworkTypes);
2381         } catch (SecurityException se) {
2382             fail("testSetAllowedNetworkTypes: SecurityException not expected");
2383         }
2384     }
2385 
2386     @Test
testDisAllowedNetworkTypes()2387     public void testDisAllowedNetworkTypes() {
2388         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2389             return;
2390         }
2391 
2392         long allowedNetworkTypes = -1 & (~TelephonyManager.NETWORK_TYPE_BITMASK_NR);
2393         long networkTypeBitmask = TelephonyManager.NETWORK_TYPE_BITMASK_NR
2394                 | TelephonyManager.NETWORK_TYPE_BITMASK_LTE
2395                 | TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
2396 
2397         try {
2398             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2399                     mTelephonyManager,
2400                     (tm) -> tm.setAllowedNetworkTypes(allowedNetworkTypes));
2401 
2402             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2403                     mTelephonyManager,
2404                     (tm) -> tm.setPreferredNetworkTypeBitmask(networkTypeBitmask));
2405 
2406             long modemNetworkTypeBitmask = ShellIdentityUtils.invokeMethodWithShellPermissions(
2407                     mTelephonyManager, (tm) -> {
2408                         return tm.getPreferredNetworkTypeBitmask();
2409                     }
2410             );
2411             long radioAccessFamily = ShellIdentityUtils.invokeMethodWithShellPermissions(
2412                     mTelephonyManager, (tm) -> {
2413                         return tm.getSupportedRadioAccessFamily();
2414                     }
2415             );
2416 
2417             // RadioAccessFamily won't include all bits of RAFs group, so transfer to preferred
2418             // network type instead of using bitmask directly
2419             int modemPreferredNetworkType = RadioAccessFamily.getNetworkTypeFromRaf(
2420                     (int) modemNetworkTypeBitmask);
2421             int preferredNetworkType = RadioAccessFamily.getNetworkTypeFromRaf(
2422                     (int) (networkTypeBitmask & allowedNetworkTypes & radioAccessFamily));
2423             assertEquals(preferredNetworkType, modemPreferredNetworkType);
2424         } catch (SecurityException se) {
2425             fail("testDisAllowedNetworkTypes: SecurityException not expected");
2426         }
2427     }
2428 
2429     @Test
testGetSupportedModemCount()2430     public void testGetSupportedModemCount() {
2431         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2432             return;
2433         }
2434 
2435         int supportedModemCount = mTelephonyManager.getSupportedModemCount();
2436         int activeModemCount = mTelephonyManager.getActiveModemCount();
2437         assertTrue(activeModemCount >= 0);
2438         assertTrue(supportedModemCount >= activeModemCount);
2439     }
2440 
2441     @Test
testIsModemEnabledForSlot()2442     public void testIsModemEnabledForSlot() {
2443         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2444             return;
2445         }
2446 
2447         int activeModemCount = mTelephonyManager.getActiveModemCount();
2448         for (int i = 0; i < activeModemCount; i++) {
2449             // Call isModemEnabledForSlot for each slot and verify no crash.
2450             mTelephonyManager.isModemEnabledForSlot(i);
2451         }
2452     }
2453 
2454     @Test
testOpportunisticNetworkState()2455     public void testOpportunisticNetworkState() {
2456         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2457             return;
2458         }
2459 
2460         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2461                 tm -> tm.isOpportunisticNetworkEnabled());
2462         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2463                 tm -> tm.setOpportunisticNetworkState(true));
2464         assertTrue(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2465                 tm -> tm.isOpportunisticNetworkEnabled()));
2466         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2467                 tm -> tm.setOpportunisticNetworkState(false));
2468         assertFalse(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2469                 tm -> tm.isOpportunisticNetworkEnabled()));
2470         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2471                 tm -> tm.setOpportunisticNetworkState(isEnabled));
2472     }
2473 
2474     @Test
testGetSimApplicationState()2475     public void testGetSimApplicationState() {
2476         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2477             return;
2478         }
2479         int simApplicationState = mTelephonyManager.getSimApplicationState();
2480         assertTrue(Arrays.asList(TelephonyManager.SIM_STATE_UNKNOWN,
2481                 TelephonyManager.SIM_STATE_PIN_REQUIRED,
2482                 TelephonyManager.SIM_STATE_PUK_REQUIRED,
2483                 TelephonyManager.SIM_STATE_NETWORK_LOCKED,
2484                 TelephonyManager.SIM_STATE_NOT_READY,
2485                 TelephonyManager.SIM_STATE_PERM_DISABLED,
2486                 TelephonyManager.SIM_STATE_LOADED).contains(simApplicationState));
2487     }
2488 
2489     @Test
testGetSimCardState()2490     public void testGetSimCardState() {
2491         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2492             return;
2493         }
2494         int simCardState = mTelephonyManager.getSimCardState();
2495         assertTrue(Arrays.asList(TelephonyManager.SIM_STATE_UNKNOWN,
2496                 TelephonyManager.SIM_STATE_ABSENT,
2497                 TelephonyManager.SIM_STATE_CARD_IO_ERROR,
2498                 TelephonyManager.SIM_STATE_CARD_RESTRICTED,
2499                 TelephonyManager.SIM_STATE_PRESENT).contains(simCardState));
2500     }
2501 
2502 
isDataEnabled()2503     private boolean isDataEnabled() {
2504         return ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2505                 TelephonyManager::isDataEnabled);
2506     }
2507 
getObservableDataEnabledUri(int subId)2508     private Uri getObservableDataEnabledUri(int subId) {
2509         Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
2510         if (mTelephonyManager.getActiveModemCount() != 1) {
2511             uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
2512         }
2513         return uri;
2514     }
2515 
2516     /**
2517      * Validate Emergency Number address that only contains the dialable character.
2518      *
2519      * @param address Emergency number address to validate
2520      * @return {@code true} if the address is valid; {@code false} otherwise.
2521      */
validateEmergencyNumberAddress(String address)2522     private static boolean validateEmergencyNumberAddress(String address) {
2523         if (address == null) {
2524             return false;
2525         }
2526         for (char c : address.toCharArray()) {
2527             if (!isDialable(c)) {
2528                 return false;
2529             }
2530         }
2531         return true;
2532     }
2533 
2534     /**
2535      * Validate Emergency Number country Iso
2536      *
2537      * @param countryIso Emergency number country iso to validate
2538      * @return {@code true} if the country iso is valid; {@code false} otherwise.
2539      */
validateEmergencyNumberCountryIso(String countryIso)2540     private static boolean validateEmergencyNumberCountryIso(String countryIso) {
2541         if (countryIso == null) {
2542             return false;
2543         }
2544         int length = countryIso.length();
2545         return length >= 0 && length <= 2;
2546     }
2547 
2548     /**
2549      * Validate Emergency Number MNC
2550      *
2551      * @param mnc Emergency number MNC to validate
2552      * @return {@code true} if the MNC is valid; {@code false} otherwise.
2553      */
validateEmergencyNumberMnc(String mnc)2554     private static boolean validateEmergencyNumberMnc(String mnc) {
2555         if (mnc == null) {
2556             return false;
2557         }
2558         int length = mnc.length();
2559         return length >= 0 && length <= 3;
2560     }
2561 
2562     /**
2563      * Validate Emergency service category list
2564      *
2565      * @param categories Emergency service category list to validate
2566      * @return {@code true} if the category list is valid; {@code false} otherwise.
2567      */
validateEmergencyServiceCategoryList(List<Integer> categories)2568     private static boolean validateEmergencyServiceCategoryList(List<Integer> categories) {
2569         if (categories == null) {
2570             return false;
2571         }
2572         if (categories.contains(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED)) {
2573             return categories.size() == 1;
2574         }
2575         for (int category : categories) {
2576             if (!EMERGENCY_SERVICE_CATEGORY_SET.contains(category)) {
2577                 return false;
2578             }
2579         }
2580         return true;
2581     }
2582 
2583     /**
2584      * Validate Emergency number source list
2585      *
2586      * @param categories Emergency number source list to validate
2587      * @return {@code true} if the source list is valid; {@code false} otherwise.
2588      */
validateEmergencyNumberSourceList(List<Integer> sources)2589     private static boolean validateEmergencyNumberSourceList(List<Integer> sources) {
2590         if (sources == null) {
2591             return false;
2592         }
2593         for (int source : sources) {
2594             if (!EMERGENCY_NUMBER_SOURCE_SET.contains(source)) {
2595                 return false;
2596             }
2597         }
2598         return true;
2599     }
2600 
2601     /**
2602      * Validate Emergency call routing.
2603      *
2604      * @param routing Emergency call routing to validate
2605      * @return {@code true} if the emergency call routing is valid; {@code false} otherwise.
2606      */
validateEmergencyCallRouting(int routing)2607     private static boolean validateEmergencyCallRouting(int routing) {
2608         return routing >= EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN
2609                 && routing <= (EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY
2610                 | EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
2611     }
2612 
2613     /**
2614      * Valid the emergency number should be at least from a valid source.
2615      *
2616      * @param emergencyNumber Emergency number to verify
2617      * @return {@code true} if the emergency number is from any source; {@code false} otherwise.
2618      */
validateEmergencyNumberFromAnySource(EmergencyNumber emergencyNumber)2619     private static boolean validateEmergencyNumberFromAnySource(EmergencyNumber emergencyNumber) {
2620         boolean isFromAnySource = false;
2621         for (int possibleSourceValue = EMERGENCY_NUMBER_SOURCE_RIL_ECCLIST;
2622                 possibleSourceValue <= (EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
2623                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM
2624                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE
2625                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
2626                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT);
2627                 possibleSourceValue++) {
2628             if (emergencyNumber.isFromSources(possibleSourceValue)) {
2629                 isFromAnySource = true;
2630                 break;
2631             }
2632         }
2633         return isFromAnySource;
2634     }
2635 
2636     /**
2637      * Valid the emergency number should be at least in a valid category.
2638      *
2639      * @param emergencyNumber Emergency number to verify
2640      * @return {@code true} if it is in any category; {@code false} otherwise.
2641      */
validateEmergencyNumberInAnyCategory(EmergencyNumber emergencyNumber)2642     private static boolean validateEmergencyNumberInAnyCategory(EmergencyNumber emergencyNumber) {
2643         boolean isInAnyCategory = false;
2644         for (int possibleCategoryValue = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
2645                 possibleCategoryValue <= (EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
2646                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
2647                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE
2648                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD
2649                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE
2650                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC
2651                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC);
2652                 possibleCategoryValue++) {
2653             if (emergencyNumber.isInEmergencyServiceCategories(possibleCategoryValue)) {
2654                 isInAnyCategory = true;
2655                 break;
2656             }
2657         }
2658         return isInAnyCategory;
2659     }
2660 
validateEmergencyNumberCompareTo( List<EmergencyNumber> emergencyNumberList)2661     private static boolean validateEmergencyNumberCompareTo(
2662             List<EmergencyNumber> emergencyNumberList) {
2663         if (emergencyNumberList == null) {
2664             return false;
2665         }
2666         if (emergencyNumberList.size() > 0) {
2667             EmergencyNumber emergencyNumber = emergencyNumberList.get(0);
2668             if (emergencyNumber.compareTo(emergencyNumber) != 0) {
2669                 return false;
2670             }
2671         }
2672         return true;
2673     }
2674 
isDialable(char c)2675     private static boolean isDialable(char c) {
2676         return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N';
2677     }
2678 
getValidSlotIndex()2679     private int getValidSlotIndex() {
2680         return ShellIdentityUtils.invokeMethodWithShellPermissions(
2681                 mTelephonyManager, (tm) -> {
2682                     List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
2683                     Set<String> presentCards = Arrays.stream(mTelephonyManager.getUiccSlotsInfo())
2684                             .filter(UiccSlotInfo::getIsActive)
2685                             .map(UiccSlotInfo::getCardId)
2686                             .filter(Objects::nonNull)
2687                             // hack around getUiccSlotsInfo not stripping trailing F
2688                             .map(s -> s.endsWith("F") ? s.substring(0, s.length() - 1) : s)
2689                             .collect(Collectors.toSet());
2690                     int slotIndex = -1;
2691                     for (UiccCardInfo cardInfo : cardInfos) {
2692                         if (presentCards.contains(cardInfo.getIccId())
2693                                 || presentCards.contains(cardInfo.getEid())) {
2694                             slotIndex = cardInfo.getSlotIndex();
2695                             break;
2696                         }
2697                     }
2698                     if (slotIndex < 0) {
2699                         fail("Test must be run with SIM card inserted, presentCards = "
2700                                 + presentCards + "cardinfos = " + cardInfos);
2701                     }
2702                     return slotIndex;
2703                 });
2704     }
2705 
waitForMs(long ms)2706     public static void waitForMs(long ms) {
2707         try {
2708             Thread.sleep(ms);
2709         } catch (InterruptedException e) {
2710             Log.d(TAG, "InterruptedException while waiting: " + e);
2711         }
2712     }
2713 
2714     /**
2715      * Verify that the phone is supporting the action of setForbiddenPlmn.
2716      *
2717      * @return whether to proceed the test
2718      */
supportSetFplmn()2719     private boolean supportSetFplmn() {
2720         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2721             return false;
2722         }
2723         return mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM;
2724     }
2725 
makeRadioVersion(int major, int minor)2726     private static int makeRadioVersion(int major, int minor) {
2727         if (major < 0 || minor < 0) return 0;
2728         return major * 100 + minor;
2729     }
2730 }
2731 
2732 
2733