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 android.app.AppOpsManager.OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER;
20 import static android.telephony.PhoneCapability.DEVICE_NR_CAPABILITY_NSA;
21 import static android.telephony.PhoneCapability.DEVICE_NR_CAPABILITY_SA;
22 
23 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import static org.junit.Assert.assertArrayEquals;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertNotEquals;
31 import static org.junit.Assert.assertNotNull;
32 import static org.junit.Assert.assertNull;
33 import static org.junit.Assert.assertTrue;
34 import static org.junit.Assert.fail;
35 
36 import android.Manifest.permission;
37 import android.annotation.NonNull;
38 import android.app.AppOpsManager;
39 import android.app.UiAutomation;
40 import android.bluetooth.BluetoothAdapter;
41 import android.content.BroadcastReceiver;
42 import android.content.ComponentName;
43 import android.content.Context;
44 import android.content.Intent;
45 import android.content.IntentFilter;
46 import android.content.pm.PackageInfo;
47 import android.content.pm.PackageManager;
48 import android.net.ConnectivityManager;
49 import android.net.wifi.WifiManager;
50 import android.os.AsyncTask;
51 import android.os.Build;
52 import android.os.Looper;
53 import android.os.PersistableBundle;
54 import android.os.Process;
55 import android.os.UserManager;
56 import android.telecom.PhoneAccount;
57 import android.telecom.PhoneAccountHandle;
58 import android.telecom.TelecomManager;
59 import android.telephony.AccessNetworkConstants;
60 import android.telephony.Annotation.RadioPowerState;
61 import android.telephony.AvailableNetworkInfo;
62 import android.telephony.CallAttributes;
63 import android.telephony.CallForwardingInfo;
64 import android.telephony.CallQuality;
65 import android.telephony.CarrierConfigManager;
66 import android.telephony.CellIdentity;
67 import android.telephony.CellIdentityLte;
68 import android.telephony.CellIdentityNr;
69 import android.telephony.CellInfo;
70 import android.telephony.CellLocation;
71 import android.telephony.DataThrottlingRequest;
72 import android.telephony.ImsiEncryptionInfo;
73 import android.telephony.ModemActivityInfo;
74 import android.telephony.NetworkRegistrationInfo;
75 import android.telephony.PhoneCapability;
76 import android.telephony.PhoneStateListener;
77 import android.telephony.PinResult;
78 import android.telephony.PreciseCallState;
79 import android.telephony.RadioAccessFamily;
80 import android.telephony.ServiceState;
81 import android.telephony.SignalStrength;
82 import android.telephony.SignalStrengthUpdateRequest;
83 import android.telephony.SignalThresholdInfo;
84 import android.telephony.SubscriptionInfo;
85 import android.telephony.SubscriptionManager;
86 import android.telephony.TelephonyCallback;
87 import android.telephony.TelephonyManager;
88 import android.telephony.ThermalMitigationRequest;
89 import android.telephony.UiccCardInfo;
90 import android.telephony.UiccSlotInfo;
91 import android.telephony.data.ApnSetting;
92 import android.telephony.data.NetworkSlicingConfig;
93 import android.telephony.emergency.EmergencyNumber;
94 import android.text.TextUtils;
95 import android.util.Log;
96 import android.util.Pair;
97 
98 import androidx.test.InstrumentationRegistry;
99 
100 import com.android.compatibility.common.util.ShellIdentityUtils;
101 import com.android.compatibility.common.util.TestThread;
102 import com.android.internal.telephony.uicc.IccUtils;
103 
104 import org.junit.After;
105 import org.junit.Before;
106 import org.junit.Ignore;
107 import org.junit.Test;
108 
109 import java.io.ByteArrayInputStream;
110 import java.io.InputStream;
111 import java.security.MessageDigest;
112 import java.security.NoSuchAlgorithmException;
113 import java.security.PublicKey;
114 import java.security.cert.CertificateException;
115 import java.security.cert.CertificateFactory;
116 import java.security.cert.X509Certificate;
117 import java.util.ArrayList;
118 import java.util.Arrays;
119 import java.util.Collections;
120 import java.util.HashMap;
121 import java.util.HashSet;
122 import java.util.List;
123 import java.util.Locale;
124 import java.util.Map;
125 import java.util.Objects;
126 import java.util.Set;
127 import java.util.concurrent.CompletableFuture;
128 import java.util.concurrent.CountDownLatch;
129 import java.util.concurrent.Executor;
130 import java.util.concurrent.LinkedBlockingQueue;
131 import java.util.concurrent.TimeUnit;
132 import java.util.concurrent.atomic.AtomicReference;
133 import java.util.function.Consumer;
134 import java.util.regex.Pattern;
135 import java.util.stream.Collectors;
136 import java.util.stream.IntStream;
137 
138 
139 /**
140  * Build, install and run the tests by running the commands below:
141  *  make cts -j64
142  *  cts-tradefed run cts -m CtsTelephonyTestCases --test android.telephony.cts.TelephonyManagerTest
143  */
144 public class TelephonyManagerTest {
145     private TelephonyManager mTelephonyManager;
146     private SubscriptionManager mSubscriptionManager;
147     private PackageManager mPackageManager;
148     private boolean mOnCellLocationChangedCalled = false;
149     private boolean mOnCellInfoChanged = false;
150     private boolean mOnSignalStrengthsChanged = false;
151     private boolean mServiceStateChangedCalled = false;
152     private boolean mRadioRebootTriggered = false;
153     private boolean mHasRadioPowerOff = false;
154     private ServiceState mServiceState;
155     private PhoneCapability mPhoneCapability;
156     private boolean mOnPhoneCapabilityChanged = false;
157     private final Object mLock = new Object();
158 
159     private CarrierConfigManager mCarrierConfigManager;
160     private String mSelfPackageName;
161     private String mSelfCertHash;
162 
163     private static final int TOLERANCE = 1000;
164     private static final int TIMEOUT_FOR_NETWORK_OPS = TOLERANCE * 180;
165     private PhoneStateListener mListener;
166     private static ConnectivityManager mCm;
167     private static final String TAG = "TelephonyManagerTest";
168     private static final List<Integer> ROAMING_TYPES = Arrays.asList(
169             ServiceState.ROAMING_TYPE_DOMESTIC,
170             ServiceState.ROAMING_TYPE_INTERNATIONAL,
171             ServiceState.ROAMING_TYPE_NOT_ROAMING,
172             ServiceState.ROAMING_TYPE_UNKNOWN);
173     private static final List<Integer> NETWORK_TYPES = Arrays.asList(
174             TelephonyManager.NETWORK_TYPE_UNKNOWN,
175             TelephonyManager.NETWORK_TYPE_GPRS,
176             TelephonyManager.NETWORK_TYPE_EDGE,
177             TelephonyManager.NETWORK_TYPE_UMTS,
178             TelephonyManager.NETWORK_TYPE_CDMA,
179             TelephonyManager.NETWORK_TYPE_EVDO_0,
180             TelephonyManager.NETWORK_TYPE_EVDO_A,
181             TelephonyManager.NETWORK_TYPE_1xRTT,
182             TelephonyManager.NETWORK_TYPE_HSDPA,
183             TelephonyManager.NETWORK_TYPE_HSUPA,
184             TelephonyManager.NETWORK_TYPE_HSPA,
185             TelephonyManager.NETWORK_TYPE_IDEN,
186             TelephonyManager.NETWORK_TYPE_EVDO_B,
187             TelephonyManager.NETWORK_TYPE_LTE,
188             TelephonyManager.NETWORK_TYPE_EHRPD,
189             TelephonyManager.NETWORK_TYPE_HSPAP,
190             TelephonyManager.NETWORK_TYPE_GSM,
191             TelephonyManager.NETWORK_TYPE_TD_SCDMA,
192             TelephonyManager.NETWORK_TYPE_IWLAN,
193             TelephonyManager.NETWORK_TYPE_LTE_CA,
194             TelephonyManager.NETWORK_TYPE_NR);
195 
196     private static final int EMERGENCY_NUMBER_SOURCE_RIL_ECCLIST = 0;
197     private static final Set<Integer> EMERGENCY_NUMBER_SOURCE_SET;
198 
199     private static final String PLMN_A = "123456";
200     private static final String PLMN_B = "78901";
201     private static final List<String> FPLMN_TEST = Arrays.asList(PLMN_A, PLMN_B);
202     private static final int MAX_FPLMN_NUM = 100;
203     private static final int MIN_FPLMN_NUM = 3;
204 
205     private static final String THERMAL_MITIGATION_COMMAND_BASE = "cmd phone thermal-mitigation ";
206     private static final String ALLOW_PACKAGE_SUBCOMMAND = "allow-package ";
207     private static final String DISALLOW_PACKAGE_SUBCOMMAND = "disallow-package ";
208     private static final String TELEPHONY_CTS_PACKAGE = "android.telephony.cts";
209 
210     private static final String TEST_FORWARD_NUMBER = "54321";
211     private static final String TESTING_PLMN = "12345";
212 
213     private static final String BAD_IMSI_CERT_URL = "https:badurl.badurl:8080";
214     private static final String IMSI_CERT_STRING_EPDG = "-----BEGIN CERTIFICATE-----"
215             + "\nMIIDkzCCAnugAwIBAgIEJ4MVZDANBgkqhkiG9w0BAQsFADB6MQswCQYDVQQGEwJV"
216             + "\nUzEOMAwGA1UECBMFVGV4YXMxDzANBgNVBAcTBklydmluZzEiMCAGA1UEChMZVmVy"
217             + "\naXpvbiBEYXRhIFNlcnZpY2VzIExMQzEMMAoGA1UECxMDTk5PMRgwFgYDVQQDEw9F"
218             + "\nQVAtSURFLlZaVy5DT00wHhcNMTcxMTEzMTkxMTA1WhcNMjcxMTExMTkxMTA1WjB6"
219             + "\nMQswCQYDVQQGEwJVUzEOMAwGA1UECBMFVGV4YXMxDzANBgNVBAcTBklydmluZzEi"
220             + "\nMCAGA1UEChMZVmVyaXpvbiBEYXRhIFNlcnZpY2VzIExMQzEMMAoGA1UECxMDTk5P"
221             + "\nMRgwFgYDVQQDEw9FQVAtSURFLlZaVy5DT00wggEiMA0GCSqGSIb3DQEBAQUAA4IB"
222             + "\nDwAwggEKAoIBAQCrQ28TvN0uUV/vK4YUS7+zcYMKAe5IYtDa3Wa0r64iyBSz6Eau"
223             + "\nT+YHNNzCV4xMqURM5mIY6796LnmWR5jViUgrHyw0d06mLE54uUET/drn2pwhaobK"
224             + "\nNVvbYzpm5W3dvext+klEgIhpRW4fR/uNUmD0O9n/5ofpg++wbvMNWEIjeTVUGPRT"
225             + "\nCeVblH3tK8bKdCKjp48HtuciY7gE8LMoHhMHA1cob9VktSYTy2ABa+rKAPAaqVz4"
226             + "\nL0Arlbi9INHSDNFlLvy1xE5dyYIqhRMicM2i4LCMwJnwf0tz8m7DmDxfdmC4HY2Q"
227             + "\nz4VpbQOu10oRhXXrhZFkZEmqp6RYQmDRDDDtAgMBAAGjITAfMB0GA1UdDgQWBBSg"
228             + "\nFA6liox07smzfITrvjSlgWkMMTANBgkqhkiG9w0BAQsFAAOCAQEAIoFKLgLfS9f1"
229             + "\n0UG85rb+noaeXY0YofSY0dxFIW3rA5zjRD0kus9iyw9CfADDD305hefJ4Kq/NLAF"
230             + "\n0odR4MOTan5KhXTlD9/8mZjSSeEktgCX3BbmMqKoKcaV6Oo9C0RfwGccDms6D+Dw"
231             + "\n3GkgsvKJEB8LjApzQSmDwCV9BVJsC60041cndqBxMr3RMxCkO6/sQRKyAuzx5f91"
232             + "\nWn5cpYxvl4//TatSc9oeU+ootlxfXszdRPM5xqCodm6gWmxRkK6DePlhpaZ1sKdw"
233             + "\nCQg/mA35Eh5ZgOpZT2YG+a8BbDRCF5gj/pu1tPt8VfApPHq6lAoitlrx1cEdJWx6"
234             + "\n5JXaFrs0UA=="
235             + "\n-----END CERTIFICATE-----";
236     private static final String IMSI_CERT_STRING_WLAN = "-----BEGIN CERTIFICATE-----"
237             + "\nMIIFbzCCBFegAwIBAgIUAz8I/cK3fILeJ9PSbi7MkN8yZBkwDQYJKoZIhvcNAQEL"
238             + "\nBQAwgY0xCzAJBgNVBAYTAk5MMRIwEAYDVQQHEwlBbXN0ZXJkYW0xJTAjBgNVBAoT"
239             + "\nHFZlcml6b24gRW50ZXJwcmlzZSBTb2x1dGlvbnMxEzARBgNVBAsTCkN5YmVydHJ1"
240             + "\nc3QxLjAsBgNVBAMTJVZlcml6b24gUHVibGljIFN1cmVTZXJ2ZXIgQ0EgRzE0LVNI"
241             + "\nQTIwHhcNMTcxMTE2MTU1NjMzWhcNMTkxMTE2MTU1NjMzWjB6MQswCQYDVQQGEwJV"
242             + "\nUzEOMAwGA1UECBMFVGV4YXMxDzANBgNVBAcTBklydmluZzEiMCAGA1UEChMZVmVy"
243             + "\naXpvbiBEYXRhIFNlcnZpY2VzIExMQzEMMAoGA1UECxMDTk5PMRgwFgYDVQQDEw9F"
244             + "\nQVAtSURFLlZaVy5DT00wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCr"
245             + "\nQ28TvN0uUV/vK4YUS7+zcYMKAe5IYtDa3Wa0r64iyBSz6EauT+YHNNzCV4xMqURM"
246             + "\n5mIY6796LnmWR5jViUgrHyw0d06mLE54uUET/drn2pwhaobKNVvbYzpm5W3dvext"
247             + "\n+klEgIhpRW4fR/uNUmD0O9n/5ofpg++wbvMNWEIjeTVUGPRTCeVblH3tK8bKdCKj"
248             + "\np48HtuciY7gE8LMoHhMHA1cob9VktSYTy2ABa+rKAPAaqVz4L0Arlbi9INHSDNFl"
249             + "\nLvy1xE5dyYIqhRMicM2i4LCMwJnwf0tz8m7DmDxfdmC4HY2Qz4VpbQOu10oRhXXr"
250             + "\nhZFkZEmqp6RYQmDRDDDtAgMBAAGjggHXMIIB0zAMBgNVHRMBAf8EAjAAMEwGA1Ud"
251             + "\nIARFMEMwQQYJKwYBBAGxPgEyMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vc2VjdXJl"
252             + "\nLm9tbmlyb290LmNvbS9yZXBvc2l0b3J5MIGpBggrBgEFBQcBAQSBnDCBmTAtBggr"
253             + "\nBgEFBQcwAYYhaHR0cDovL3Zwc3NnMTQyLm9jc3Aub21uaXJvb3QuY29tMDMGCCsG"
254             + "\nAQUFBzAChidodHRwOi8vY2FjZXJ0Lm9tbmlyb290LmNvbS92cHNzZzE0Mi5jcnQw"
255             + "\nMwYIKwYBBQUHMAKGJ2h0dHA6Ly9jYWNlcnQub21uaXJvb3QuY29tL3Zwc3NnMTQy"
256             + "\nLmRlcjAaBgNVHREEEzARgg9FQVAtSURFLlZaVy5DT00wDgYDVR0PAQH/BAQDAgWg"
257             + "\nMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAfBgNVHSMEGDAWgBTkLbuR"
258             + "\nAWUmH7R6P6MVJaTOjEQzOzA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vdnBzc2cx"
259             + "\nNDIuY3JsLm9tbmlyb290LmNvbS92cHNzZzE0Mi5jcmwwHQYDVR0OBBYEFKAUDqWK"
260             + "\njHTuybN8hOu+NKWBaQwxMA0GCSqGSIb3DQEBCwUAA4IBAQAbSrvVrdxRPLnVu6vc"
261             + "\n4BiFT2gWDhZ63EyV4f877sC1iMJRFlfwWQQfHVyhGTFa8JnhbEhhTxCP+L00Q8rX"
262             + "\nKbOw9ei5g2yp7OjStwhHz5T20UejjKkl7hKtMduZXxFToqhVwIpqG58Tzl/35FX4"
263             + "\nu+YDPgwTX5gbpbJxpbncn9voxWGWu3AbHVvzaskfBgZfWAuJnbgq0WTEt7bGOfiI"
264             + "\nelIIQe7XL6beFcdAM9C7DlgOLqpR/31LncrMC46cPA5HmfV4mnpeK/9uq0mMbUJK"
265             + "\nx2vNRWONSm2UGwdb00tLsTloxeqCOMpbkBiqi/RhOlIKIOWMPojukA5+xryh2FVs"
266             + "\n7bdw"
267             + "\n-----END CERTIFICATE-----";
268 
269     private static final int RADIO_HAL_VERSION_1_3 = makeRadioVersion(1, 3);
270     private static final int RADIO_HAL_VERSION_1_5 = makeRadioVersion(1, 5);
271     private static final int RADIO_HAL_VERSION_1_6 = makeRadioVersion(1, 6);
272 
273     static {
274         EMERGENCY_NUMBER_SOURCE_SET = new HashSet<Integer>();
275         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
276         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM);
277         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE);
278         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
279         EMERGENCY_NUMBER_SOURCE_SET.add(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT);
280     }
281 
282     private static final Set<Integer> EMERGENCY_SERVICE_CATEGORY_SET;
283     static {
284         EMERGENCY_SERVICE_CATEGORY_SET = new HashSet<Integer>();
285         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
286         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
287         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE);
288         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD);
289         EMERGENCY_SERVICE_CATEGORY_SET.add(
290                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE);
291         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC);
292         EMERGENCY_SERVICE_CATEGORY_SET.add(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC);
293     }
294 
295     private int mTestSub;
296     private TelephonyManagerTest.CarrierConfigReceiver mReceiver;
297     private int mRadioVersion;
298     private boolean mIsAllowedNetworkTypeChanged;
299     private Map<Integer, Long> mAllowedNetworkTypesList = new HashMap<>();
300 
301     private static class CarrierConfigReceiver extends BroadcastReceiver {
302         private CountDownLatch mLatch = new CountDownLatch(1);
303         private final int mSubId;
304 
CarrierConfigReceiver(int subId)305         CarrierConfigReceiver(int subId) {
306             mSubId = subId;
307         }
308 
309         @Override
onReceive(Context context, Intent intent)310         public void onReceive(Context context, Intent intent) {
311             if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
312                 int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
313                         SubscriptionManager.INVALID_SUBSCRIPTION_ID);
314                 if (mSubId == subId) {
315                     mLatch.countDown();
316                 }
317             }
318         }
319 
clearQueue()320         void clearQueue() {
321             mLatch = new CountDownLatch(1);
322         }
323 
waitForCarrierConfigChanged()324         void waitForCarrierConfigChanged() throws Exception {
325             mLatch.await(5000, TimeUnit.MILLISECONDS);
326         }
327     }
328 
329     @Before
setUp()330     public void setUp() throws Exception {
331         mCm = getContext().getSystemService(ConnectivityManager.class);
332         mSubscriptionManager = getContext().getSystemService(SubscriptionManager.class);
333         mPackageManager = getContext().getPackageManager();
334         mCarrierConfigManager = getContext().getSystemService(CarrierConfigManager.class);
335         mSelfPackageName = getContext().getPackageName();
336         mSelfCertHash = getCertHash(mSelfPackageName);
337         mTestSub = SubscriptionManager.getDefaultSubscriptionId();
338         mTelephonyManager = getContext().getSystemService(TelephonyManager.class)
339                 .createForSubscriptionId(mTestSub);
340         mReceiver = new CarrierConfigReceiver(mTestSub);
341         Pair<Integer, Integer> radioVersion = mTelephonyManager.getRadioHalVersion();
342         mRadioVersion = makeRadioVersion(radioVersion.first, radioVersion.second);
343         IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
344         // ACTION_CARRIER_CONFIG_CHANGED is sticky, so we will get a callback right away.
345         getContext().registerReceiver(mReceiver, filter);
346         InstrumentationRegistry.getInstrumentation().getUiAutomation()
347                 .adoptShellPermissionIdentity("android.permission.READ_PHONE_STATE");
348         saveAllowedNetworkTypesForAllReasons();
349     }
350 
351     @After
tearDown()352     public void tearDown() throws Exception {
353         if (mListener != null) {
354             // unregister the listener
355             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
356         }
357         if (mReceiver != null) {
358             getContext().unregisterReceiver(mReceiver);
359             mReceiver = null;
360         }
361         if (mIsAllowedNetworkTypeChanged) {
362             recoverAllowedNetworkType();
363         }
364 
365         StringBuilder cmdBuilder = new StringBuilder();
366         cmdBuilder.append(THERMAL_MITIGATION_COMMAND_BASE).append(DISALLOW_PACKAGE_SUBCOMMAND)
367                 .append(TELEPHONY_CTS_PACKAGE);
368         TelephonyUtils.executeShellCommand(InstrumentationRegistry.getInstrumentation(),
369                 cmdBuilder.toString());
370     }
371 
saveAllowedNetworkTypesForAllReasons()372     private void saveAllowedNetworkTypesForAllReasons() {
373         if (!hasCellular()) return;
374         mIsAllowedNetworkTypeChanged = false;
375         if (mAllowedNetworkTypesList == null) {
376             mAllowedNetworkTypesList = new HashMap<>();
377         }
378         long allowedNetworkTypesUser = ShellIdentityUtils.invokeMethodWithShellPermissions(
379                 mTelephonyManager, (tm) -> {
380                     return tm.getAllowedNetworkTypesForReason(
381                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
382                 }
383         );
384         long allowedNetworkTypesPower = ShellIdentityUtils.invokeMethodWithShellPermissions(
385                 mTelephonyManager, (tm) -> {
386                     return tm.getAllowedNetworkTypesForReason(
387                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER);
388                 }
389         );
390         long allowedNetworkTypesCarrier = ShellIdentityUtils.invokeMethodWithShellPermissions(
391                 mTelephonyManager, (tm) -> {
392                     return tm.getAllowedNetworkTypesForReason(
393                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER);
394                 }
395         );
396         long allowedNetworkTypesEnable2g = ShellIdentityUtils.invokeMethodWithShellPermissions(
397                 mTelephonyManager, (tm) -> {
398                     return tm.getAllowedNetworkTypesForReason(
399                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
400                 }
401         );
402         mAllowedNetworkTypesList.put(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
403                 allowedNetworkTypesUser);
404         mAllowedNetworkTypesList.put(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER,
405                 allowedNetworkTypesPower);
406         mAllowedNetworkTypesList.put(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER,
407                 allowedNetworkTypesCarrier);
408         mAllowedNetworkTypesList.put(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G,
409                 allowedNetworkTypesEnable2g);
410     }
411 
recoverAllowedNetworkType()412     private void recoverAllowedNetworkType() {
413         if (mAllowedNetworkTypesList == null) {
414             return;
415         }
416         for (Integer key : mAllowedNetworkTypesList.keySet()) {
417             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
418                     mTelephonyManager,
419                     (tm) -> tm.setAllowedNetworkTypesForReason(
420                             key,
421                             mAllowedNetworkTypesList.get(key)));
422         }
423     }
424 
getCertHash(String pkgName)425     private String getCertHash(String pkgName) throws Exception {
426         try {
427             PackageInfo pInfo = mPackageManager.getPackageInfo(pkgName,
428                     PackageManager.GET_SIGNATURES
429                             | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
430             MessageDigest md = MessageDigest.getInstance("SHA-1");
431             return IccUtils.bytesToHexString(md.digest(pInfo.signatures[0].toByteArray()));
432         } catch (PackageManager.NameNotFoundException ex) {
433             Log.e(TAG, pkgName + " not found", ex);
434             throw ex;
435         } catch (NoSuchAlgorithmException ex) {
436             Log.e(TAG, "Algorithm SHA1 is not found.");
437             throw ex;
438         }
439     }
440 
441     /** Checks whether the cellular stack should be running on this device. */
hasCellular()442     private boolean hasCellular() {
443         return mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
444                 && mTelephonyManager.getPhoneCount() > 0;
445     }
446 
447     @Test
testHasCarrierPrivilegesViaCarrierConfigs()448     public void testHasCarrierPrivilegesViaCarrierConfigs() throws Exception {
449         if (!hasCellular()) return;
450         PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mTestSub);
451 
452         try {
453             assertNotNull("CarrierConfigManager#getConfigForSubId() returned null",
454                     carrierConfig);
455             assertFalse("CarrierConfigManager#getConfigForSubId() returned empty bundle",
456                     carrierConfig.isEmpty());
457 
458             // purge the certs in carrierConfigs first
459             carrierConfig.putStringArray(
460                     CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY, new String[]{});
461             overrideCarrierConfig(carrierConfig);
462             // verify we don't have privilege through carrierConfigs or Uicc
463             assertFalse(mTelephonyManager.hasCarrierPrivileges());
464 
465             carrierConfig.putStringArray(
466                     CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
467                     new String[]{mSelfCertHash});
468 
469             // verify we now have privilege after adding certificate to carrierConfigs
470             overrideCarrierConfig(carrierConfig);
471             assertTrue(mTelephonyManager.hasCarrierPrivileges());
472         } finally {
473             // purge the newly added certificate
474             carrierConfig.putStringArray(
475                     CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY, new String[]{});
476             // carrierConfig.remove(CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
477             overrideCarrierConfig(carrierConfig);
478 
479             // verify we no longer have privilege after removing certificate
480             assertFalse(mTelephonyManager.hasCarrierPrivileges());
481         }
482     }
483 
overrideCarrierConfig(PersistableBundle bundle)484     private void overrideCarrierConfig(PersistableBundle bundle) throws Exception {
485         mReceiver.clearQueue();
486         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mCarrierConfigManager,
487                 (cm) -> cm.overrideConfig(mTestSub, bundle));
488         mReceiver.waitForCarrierConfigChanged();
489     }
490 
grantLocationPermissions()491     public static void grantLocationPermissions() {
492         UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
493         String packageName = getContext().getPackageName();
494         uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_COARSE_LOCATION);
495         uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_FINE_LOCATION);
496         uiAutomation.grantRuntimePermission(packageName, permission.ACCESS_BACKGROUND_LOCATION);
497     }
498 
499     @Test
testDevicePolicyApn()500     public void testDevicePolicyApn() {
501         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
502             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
503             return;
504         }
505         // These methods aren't accessible to anything except system and phone by design, so we just
506         // look for security exceptions here.
507         try {
508             List<ApnSetting> apns = mTelephonyManager.getDevicePolicyOverrideApns(getContext());
509             fail("SecurityException expected");
510         } catch (SecurityException e) {
511             // expected
512         }
513 
514         try {
515             ApnSetting.Builder builder = new ApnSetting.Builder();
516 
517             ApnSetting setting = builder
518                     .setEntryName("asdf")
519                     .setApnName("asdf")
520                     .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
521                     .build();
522             int id = mTelephonyManager.addDevicePolicyOverrideApn(getContext(), setting);
523             fail("SecurityException expected");
524         } catch (SecurityException e) {
525             // expected
526         }
527 
528         try {
529             ApnSetting.Builder builder = new ApnSetting.Builder();
530 
531             ApnSetting setting = builder
532                     .setEntryName("asdf")
533                     .setApnName("asdf")
534                     .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
535                     .build();
536             boolean success = mTelephonyManager.modifyDevicePolicyOverrideApn(
537                     getContext(), 0, setting);
538             fail("SecurityException expected");
539         } catch (SecurityException e) {
540             // expected
541         }
542     }
543 
544     @Test
testListen()545     public void testListen() throws Throwable {
546         if (!InstrumentationRegistry.getContext().getPackageManager()
547                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
548             Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
549             return;
550         }
551 
552         if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
553             // TODO: temp workaround, need to adjust test to for CDMA
554             return;
555         }
556 
557         grantLocationPermissions();
558 
559         TestThread t = new TestThread(new Runnable() {
560             public void run() {
561                 Looper.prepare();
562                 mListener = new PhoneStateListener() {
563                     @Override
564                     public void onCellLocationChanged(CellLocation location) {
565                         if(!mOnCellLocationChangedCalled) {
566                             synchronized (mLock) {
567                                 mOnCellLocationChangedCalled = true;
568                                 mLock.notify();
569                             }
570                         }
571                     }
572                 };
573 
574                 synchronized (mLock) {
575                     mLock.notify(); // mListener is ready
576                 }
577 
578                 Looper.loop();
579             }
580         });
581 
582         synchronized (mLock) {
583             t.start();
584             mLock.wait(TOLERANCE); // wait for mListener
585         }
586 
587         // Test register
588         synchronized (mLock) {
589             // .listen generates an onCellLocationChanged event
590             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
591             mLock.wait(TOLERANCE);
592 
593             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
594                     mOnCellLocationChangedCalled);
595         }
596 
597         synchronized (mLock) {
598             mOnCellLocationChangedCalled = false;
599             CellLocation.requestLocationUpdate();
600             mLock.wait(TOLERANCE);
601 
602             // Starting with Android S, this API will silently drop all requests from apps
603             // targeting Android S due to unfixable limitations with the API.
604             assertFalse("Test register, mOnCellLocationChangedCalled should be false.",
605                     mOnCellLocationChangedCalled);
606         }
607 
608         // unregister the listener
609         mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
610         Thread.sleep(TOLERANCE);
611 
612         // Test unregister
613         synchronized (mLock) {
614             mOnCellLocationChangedCalled = false;
615             // unregister again, to make sure doing so does not call the listener
616             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
617             CellLocation.requestLocationUpdate();
618             mLock.wait(TOLERANCE);
619 
620             assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.",
621                     mOnCellLocationChangedCalled);
622         }
623     }
624 
625     /**
626      * The getter methods here are all related to the information about the telephony.
627      * These getters are related to concrete location, phone, service provider company, so
628      * it's no need to get details of these information, just make sure they are in right
629      * condition(>0 or not null).
630      */
631     @Test
testTelephonyManager()632     public void testTelephonyManager() {
633         if (!InstrumentationRegistry.getContext().getPackageManager()
634                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
635             Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
636             return;
637         }
638         assertTrue(mTelephonyManager.getNetworkType() >= TelephonyManager.NETWORK_TYPE_UNKNOWN);
639         assertTrue(mTelephonyManager.getPhoneType() >= TelephonyManager.PHONE_TYPE_NONE);
640         assertTrue(mTelephonyManager.getSimState() >= TelephonyManager.SIM_STATE_UNKNOWN);
641         assertTrue(mTelephonyManager.getDataActivity() >= TelephonyManager.DATA_ACTIVITY_NONE);
642         assertTrue(mTelephonyManager.getDataState() >= TelephonyManager.DATA_DISCONNECTED);
643         assertTrue(mTelephonyManager.getCallState() >= TelephonyManager.CALL_STATE_IDLE);
644 
645         for (int i = 0; i < mTelephonyManager.getPhoneCount(); ++i) {
646             assertTrue(mTelephonyManager.getSimState(i) >= TelephonyManager.SIM_STATE_UNKNOWN);
647         }
648 
649         // Make sure devices without MMS service won't fail on this
650         if (InstrumentationRegistry.getContext().getPackageManager()
651                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
652                 && (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE)) {
653             assertFalse(mTelephonyManager.getMmsUserAgent().isEmpty());
654             assertFalse(mTelephonyManager.getMmsUAProfUrl().isEmpty());
655         }
656 
657         // The following methods may return any value depending on the state of the device. Simply
658         // call them to make sure they do not throw any exceptions.
659         mTelephonyManager.getVoiceMailNumber();
660         mTelephonyManager.getSimOperatorName();
661         mTelephonyManager.getNetworkCountryIso();
662         mTelephonyManager.getCellLocation();
663         mTelephonyManager.getSimCarrierId();
664         mTelephonyManager.getSimCarrierIdName();
665         mTelephonyManager.getSimSpecificCarrierId();
666         mTelephonyManager.getSimSpecificCarrierIdName();
667         mTelephonyManager.getCarrierIdFromSimMccMnc();
668         mTelephonyManager.isDataRoamingEnabled();
669         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
670                 (tm) -> tm.getSimSerialNumber());
671         mTelephonyManager.getSimOperator();
672         mTelephonyManager.getSignalStrength();
673         mTelephonyManager.getNetworkOperatorName();
674         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
675                 (tm) -> tm.getSubscriberId());
676         mTelephonyManager.getLine1Number();
677         mTelephonyManager.getNetworkOperator();
678 
679         try {
680             InstrumentationRegistry.getInstrumentation().getUiAutomation()
681                     .adoptShellPermissionIdentity(
682                             "android.permission.READ_PRIVILEGED_PHONE_STATE");
683             mTelephonyManager.getPhoneAccountHandle();
684         } catch (SecurityException e) {
685             fail("TelephonyManager#getPhoneAccountHandle requires READ_PRIVILEGED_PHONE_STATE");
686         } finally {
687             InstrumentationRegistry.getInstrumentation().getUiAutomation()
688                     .dropShellPermissionIdentity();
689         }
690         mTelephonyManager.getSimCountryIso();
691         mTelephonyManager.getVoiceMailAlphaTag();
692         mTelephonyManager.isNetworkRoaming();
693         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
694                 (tm) -> tm.getDeviceId());
695         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
696                 (tm) -> tm.getDeviceId(mTelephonyManager.getSlotIndex()));
697         mTelephonyManager.getDeviceSoftwareVersion();
698         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
699                 (tm) -> tm.getDeviceSoftwareVersion(mTelephonyManager.getSlotIndex()));
700         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
701                 (tm) -> tm.getImei());
702         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
703                 (tm) -> tm.getImei(mTelephonyManager.getSlotIndex()));
704         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
705                 (tm) -> tm.isManualNetworkSelectionAllowed());
706         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
707                 (tm) -> tm.getManualNetworkSelectionPlmn());
708 
709         mTelephonyManager.getPhoneCount();
710         mTelephonyManager.getDataEnabled();
711         mTelephonyManager.getNetworkSpecifier();
712         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager, (tm) -> tm.getNai());
713         TelecomManager telecomManager = getContext().getSystemService(TelecomManager.class);
714         PhoneAccountHandle defaultAccount = telecomManager
715                 .getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
716         mTelephonyManager.getVoicemailRingtoneUri(defaultAccount);
717         mTelephonyManager.isVoicemailVibrationEnabled(defaultAccount);
718         mTelephonyManager.getSubscriptionId(defaultAccount);
719         mTelephonyManager.getCarrierConfig();
720         mTelephonyManager.isVoiceCapable();
721         mTelephonyManager.isSmsCapable();
722         mTelephonyManager.isLteCdmaEvdoGsmWcdmaEnabled();
723         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
724                 (tm) -> tm.isDataConnectionAllowed());
725         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
726                 (tm) -> tm.isAnyRadioPoweredOn());
727         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
728                 (tm) -> tm.resetIms(tm.getSlotIndex()));
729 
730         // Verify TelephonyManager.getCarrierPrivilegeStatus
731         List<Integer> validCarrierPrivilegeStatus = new ArrayList<>();
732         validCarrierPrivilegeStatus.add(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
733         validCarrierPrivilegeStatus.add(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
734         validCarrierPrivilegeStatus.add(
735                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED);
736         validCarrierPrivilegeStatus.add(
737                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES);
738         int carrierPrivilegeStatusResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
739                 mTelephonyManager, (tm) -> tm.getCarrierPrivilegeStatus(Process.myUid()));
740         assertTrue(validCarrierPrivilegeStatus.contains(carrierPrivilegeStatusResult));
741 
742         // Verify TelephonyManager.getCarrierPrivilegedPackagesForAllActiveSubscriptions
743         List<String> resultForGetCarrierPrivilegedApis =
744                 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
745                         (tm) -> tm.getCarrierPrivilegedPackagesForAllActiveSubscriptions());
746         assertNotNull(resultForGetCarrierPrivilegedApis);
747         for (String result : resultForGetCarrierPrivilegedApis) {
748             assertFalse(TextUtils.isEmpty(result));
749         }
750 
751         mTelephonyManager.getDefaultRespondViaMessageApplication();
752         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
753                 TelephonyManager::getAndUpdateDefaultRespondViaMessageApplication);
754 
755         // Verify getImei/getSubscriberId/getIccAuthentication:
756         // With app ops permision USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, should not throw
757         // SecurityException.
758         try {
759             setAppOpsPermissionAllowed(true, OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER);
760 
761             mTelephonyManager.getImei();
762             mTelephonyManager.getSubscriberId();
763             mTelephonyManager.getIccAuthentication(
764                     TelephonyManager.APPTYPE_USIM, TelephonyManager.AUTHTYPE_EAP_AKA, "");
765         } finally {
766             setAppOpsPermissionAllowed(false, OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER);
767         }
768     }
769 
770     @Test
testGetCallForwarding()771     public void testGetCallForwarding() throws Exception {
772         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
773             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
774             return;
775         }
776         List<Integer> callForwardingReasons = new ArrayList<>();
777         callForwardingReasons.add(CallForwardingInfo.REASON_UNCONDITIONAL);
778         callForwardingReasons.add(CallForwardingInfo.REASON_BUSY);
779         callForwardingReasons.add(CallForwardingInfo.REASON_NO_REPLY);
780         callForwardingReasons.add(CallForwardingInfo.REASON_NOT_REACHABLE);
781         callForwardingReasons.add(CallForwardingInfo.REASON_ALL);
782         callForwardingReasons.add(CallForwardingInfo.REASON_ALL_CONDITIONAL);
783 
784         Set<Integer> callForwardingErrors = new HashSet<Integer>();
785         callForwardingErrors.add(TelephonyManager.CallForwardingInfoCallback
786                 .RESULT_ERROR_FDN_CHECK_FAILURE);
787         callForwardingErrors.add(TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
788         callForwardingErrors.add(TelephonyManager.CallForwardingInfoCallback
789                 .RESULT_ERROR_NOT_SUPPORTED);
790 
791         for (int callForwardingReasonToGet : callForwardingReasons) {
792             Log.d(TAG, "[testGetCallForwarding] callForwardingReasonToGet: "
793                     + callForwardingReasonToGet);
794             AtomicReference<CallForwardingInfo> receivedForwardingInfo = new AtomicReference<>();
795             AtomicReference<Integer> receivedErrorCode = new AtomicReference<>();
796             CountDownLatch latch = new CountDownLatch(1);
797             TelephonyManager.CallForwardingInfoCallback callback =
798                     new TelephonyManager.CallForwardingInfoCallback() {
799                         @Override
800                         public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
801                             receivedForwardingInfo.set(info);
802                             latch.countDown();
803                         }
804 
805                         @Override
806                         public void onError(int error) {
807                             receivedErrorCode.set(error);
808                             latch.countDown();
809                         }
810             };
811             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
812                     (tm) -> tm.getCallForwarding(callForwardingReasonToGet,
813                             getContext().getMainExecutor(), callback));
814 
815             assertTrue(latch.await(TIMEOUT_FOR_NETWORK_OPS, TimeUnit.MILLISECONDS));
816             // Make sure only one of the callbacks gets invoked
817             assertTrue((receivedForwardingInfo.get() != null) ^ (receivedErrorCode.get() != null));
818             if (receivedForwardingInfo.get() != null) {
819                 CallForwardingInfo info = receivedForwardingInfo.get();
820                 assertTrue("Got reason not in expected set:" + info.getReason(),
821                         callForwardingReasons.contains(info.getReason()));
822                 if (info.isEnabled()) {
823                     assertNotNull(info.getNumber());
824                     assertTrue("Got negative timeoutSeconds=" + info.getTimeoutSeconds(),
825                             info.getTimeoutSeconds() >= 0);
826                 }
827             }
828 
829             if (receivedErrorCode.get() != null) {
830                 assertTrue("Got code not in expected set:" + receivedErrorCode.get(),
831                         callForwardingErrors.contains(receivedErrorCode.get()));
832             }
833         }
834     }
835 
836     @Test
testSetCallForwarding()837     public void testSetCallForwarding() throws Exception {
838         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
839             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
840             return;
841         }
842         List<Integer> callForwardingReasons = new ArrayList<>();
843         callForwardingReasons.add(CallForwardingInfo.REASON_UNCONDITIONAL);
844         callForwardingReasons.add(CallForwardingInfo.REASON_BUSY);
845         callForwardingReasons.add(CallForwardingInfo.REASON_NO_REPLY);
846         callForwardingReasons.add(CallForwardingInfo.REASON_NOT_REACHABLE);
847         callForwardingReasons.add(CallForwardingInfo.REASON_ALL);
848         callForwardingReasons.add(CallForwardingInfo.REASON_ALL_CONDITIONAL);
849 
850         // Enable Call Forwarding
851         for (int callForwardingReasonToEnable : callForwardingReasons) {
852             CountDownLatch latch = new CountDownLatch(1);
853             // Disregard success or failure; just make sure it reports back.
854             Consumer<Integer> ignoringResultListener = (x) -> latch.countDown();
855 
856             final CallForwardingInfo callForwardingInfoToEnable = new CallForwardingInfo(
857                     true,
858                     callForwardingReasonToEnable,
859                     TEST_FORWARD_NUMBER,
860                     // time seconds
861                     1);
862             Log.d(TAG, "[testSetCallForwarding] Enable Call Forwarding. Reason: "
863                     + callForwardingReasonToEnable + " Number: " + TEST_FORWARD_NUMBER
864                     + " Time Seconds: 1");
865             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
866                     (tm) -> tm.setCallForwarding(callForwardingInfoToEnable,
867                             getContext().getMainExecutor(), ignoringResultListener));
868             // TODO: this takes way too long on a real network (upwards of 40s).
869             // assertTrue("No response for forwarding for reason " + callForwardingReasonToEnable,
870             //        latch.await(TIMEOUT_FOR_NETWORK_OPS * 3, TimeUnit.MILLISECONDS));
871         }
872 
873         // Disable Call Forwarding
874         for (int callForwardingReasonToDisable : callForwardingReasons) {
875             CountDownLatch latch = new CountDownLatch(1);
876             // Disregard success or failure; just make sure it reports back.
877             Consumer<Integer> ignoringResultListener = (x) -> latch.countDown();
878 
879             final CallForwardingInfo callForwardingInfoToDisable = new CallForwardingInfo(
880                     false,
881                     callForwardingReasonToDisable,
882                     TEST_FORWARD_NUMBER,
883                     // time seconds
884                     1);
885             Log.d(TAG, "[testSetCallForwarding] Disable Call Forwarding. Reason: "
886                     + callForwardingReasonToDisable + " Number: " + TEST_FORWARD_NUMBER
887                     + " Time Seconds: 1");
888             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
889                     (tm) -> tm.setCallForwarding(callForwardingInfoToDisable,
890                             getContext().getMainExecutor(), ignoringResultListener));
891             // TODO: this takes way too long on a real network (upwards of 40s).
892             //assertTrue("No response for forwarding for reason " + callForwardingReasonToDisable,
893             //        latch.await(TIMEOUT_FOR_NETWORK_OPS * 3, TimeUnit.MILLISECONDS));
894         }
895     }
896 
897     @Test
testGetCallWaitingStatus()898     public void testGetCallWaitingStatus() throws Exception {
899         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
900             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
901             return;
902         }
903         Set<Integer> validCallWaitingStatuses = new HashSet<Integer>();
904         validCallWaitingStatuses.add(TelephonyManager.CALL_WAITING_STATUS_ENABLED);
905         validCallWaitingStatuses.add(TelephonyManager.CALL_WAITING_STATUS_DISABLED);
906         validCallWaitingStatuses.add(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
907         validCallWaitingStatuses.add(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
908 
909         LinkedBlockingQueue<Integer> callWaitingStatusResult = new LinkedBlockingQueue<>(1);
910         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
911                 mTelephonyManager, (tm) -> tm.getCallWaitingStatus(getContext().getMainExecutor(),
912                         callWaitingStatusResult::offer));
913         assertTrue(validCallWaitingStatuses.contains(
914                 callWaitingStatusResult.poll(TIMEOUT_FOR_NETWORK_OPS, TimeUnit.MILLISECONDS)));
915     }
916 
917     @Test
testSetCallWaitingStatus()918     public void testSetCallWaitingStatus() throws Exception {
919         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
920             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
921             return;
922         }
923         Set<Integer> validCallWaitingErrors = new HashSet<Integer>();
924         validCallWaitingErrors.add(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
925         validCallWaitingErrors.add(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
926         Executor executor = getContext().getMainExecutor();
927         {
928             LinkedBlockingQueue<Integer> callWaitingResult = new LinkedBlockingQueue<>(1);
929 
930             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
931                     (tm) -> tm.setCallWaitingEnabled(true, executor, callWaitingResult::offer));
932             Integer result = callWaitingResult.poll(TIMEOUT_FOR_NETWORK_OPS, TimeUnit.MILLISECONDS);
933             assertNotNull("Never got callback from set call waiting", result);
934             if (result != TelephonyManager.CALL_WAITING_STATUS_ENABLED) {
935                 assertTrue("Call waiting callback got an invalid value: " + result,
936                         validCallWaitingErrors.contains(result));
937             }
938         }
939 
940         {
941             LinkedBlockingQueue<Integer> callWaitingResult = new LinkedBlockingQueue<>(1);
942 
943             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
944                     (tm) -> tm.setCallWaitingEnabled(false, executor, callWaitingResult::offer));
945             Integer result = callWaitingResult.poll(TIMEOUT_FOR_NETWORK_OPS, TimeUnit.MILLISECONDS);
946             assertNotNull("Never got callback from set call waiting", result);
947             if (result != TelephonyManager.CALL_WAITING_STATUS_DISABLED) {
948                 assertTrue("Call waiting callback got an invalid value: " + result,
949                         validCallWaitingErrors.contains(result));
950             }
951         }
952     }
953 
954     @Test
testGetRadioHalVersion()955     public void testGetRadioHalVersion() {
956         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
957             Log.d(TAG,"skipping test on device without FEATURE_TELEPHONY present");
958             return;
959         }
960 
961         Pair<Integer, Integer> version = mTelephonyManager.getRadioHalVersion();
962 
963         // The version must be valid, and the versions start with 1.0
964         assertFalse("Invalid Radio HAL Version: " + version,
965                 version.first < 1 || version.second < 0);
966     }
967 
968     @Test
testCreateForPhoneAccountHandle()969     public void testCreateForPhoneAccountHandle() {
970         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
971             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
972             return;
973         }
974         if (!mTelephonyManager.isVoiceCapable()) {
975             Log.d(TAG, "Skipping test that requires config_voice_capable is true");
976             return;
977         }
978         int subId = SubscriptionManager.getDefaultDataSubscriptionId();
979         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
980             Log.d(TAG, "Skipping test that requires DefaultDataSubscriptionId setting");
981             return;
982         }
983 
984         TelecomManager telecomManager = getContext().getSystemService(TelecomManager.class);
985         PhoneAccountHandle handle =
986                 telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
987         TelephonyManager telephonyManager = mTelephonyManager.createForPhoneAccountHandle(handle);
988         String globalSubscriberId = ShellIdentityUtils.invokeMethodWithShellPermissions(
989                 mTelephonyManager, (tm) -> tm.getSubscriberId());
990         String localSubscriberId = ShellIdentityUtils.invokeMethodWithShellPermissions(
991                 telephonyManager, (tm) -> tm.getSubscriberId());
992         assertEquals(globalSubscriberId, localSubscriberId);
993     }
994 
995     @Test
testCreateForPhoneAccountHandle_InvalidHandle()996     public void testCreateForPhoneAccountHandle_InvalidHandle(){
997         PhoneAccountHandle handle =
998                 new PhoneAccountHandle(new ComponentName("com.example.foo", "bar"), "baz");
999         assertNull(mTelephonyManager.createForPhoneAccountHandle(handle));
1000     }
1001 
1002     @Test
testGetPhoneAccountHandle()1003     public void testGetPhoneAccountHandle() {
1004         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1005             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
1006             return;
1007         }
1008         TelecomManager telecomManager = getContext().getSystemService(TelecomManager.class);
1009         PhoneAccountHandle defaultAccount = telecomManager
1010                 .getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
1011         try {
1012             InstrumentationRegistry.getInstrumentation().getUiAutomation()
1013                     .adoptShellPermissionIdentity(
1014                             "android.permission.READ_PRIVILEGED_PHONE_STATE");
1015             PhoneAccountHandle phoneAccountHandle = mTelephonyManager.getPhoneAccountHandle();
1016             assertEquals(phoneAccountHandle, defaultAccount);
1017         } catch (SecurityException e) {
1018             fail("TelephonyManager#getPhoneAccountHandle requires READ_PRIVILEGED_PHONE_STATE");
1019         } finally {
1020             InstrumentationRegistry.getInstrumentation().getUiAutomation()
1021                     .dropShellPermissionIdentity();
1022         }
1023     }
1024 
1025     /**
1026      * Tests that the phone count returned is valid.
1027      */
1028     @Test
testGetPhoneCount()1029     public void testGetPhoneCount() {
1030         int phoneCount = mTelephonyManager.getPhoneCount();
1031         int phoneType = mTelephonyManager.getPhoneType();
1032         switch (phoneType) {
1033             case TelephonyManager.PHONE_TYPE_GSM:
1034             case TelephonyManager.PHONE_TYPE_CDMA:
1035                 assertTrue("Phone count should be > 0", phoneCount > 0);
1036                 break;
1037             case TelephonyManager.PHONE_TYPE_NONE:
1038                 assertTrue("Phone count should be >= 0", phoneCount >= 0);
1039                 break;
1040             default:
1041                 throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
1042         }
1043     }
1044 
1045     /**
1046      * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address
1047      * if only a WiFi device. At least one of them must be valid.
1048      */
1049     @Test
testGetDeviceId()1050     public void testGetDeviceId() {
1051         String deviceId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1052                 (tm) -> tm.getDeviceId());
1053         verifyDeviceId(deviceId);
1054     }
1055 
1056     /**
1057      * Tests the max number of active SIMs method
1058      */
1059     @Test
testGetMaxNumberOfSimultaneouslyActiveSims()1060     public void testGetMaxNumberOfSimultaneouslyActiveSims() {
1061         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1062             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
1063             return;
1064         }
1065 
1066         int maxNum = mTelephonyManager.getMaxNumberOfSimultaneouslyActiveSims();
1067         assertTrue(maxNum >= 1);
1068     }
1069 
1070     /**
1071      * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address
1072      * if only a WiFi device. At least one of them must be valid.
1073      */
1074     @Test
testGetDeviceIdForSlot()1075     public void testGetDeviceIdForSlot() {
1076         String deviceId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1077                 (tm) -> tm.getDeviceId(mTelephonyManager.getSlotIndex()));
1078         verifyDeviceId(deviceId);
1079         // Also verify that no exception is thrown for any slot index (including invalid ones)
1080         for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) {
1081             // The compiler error 'local variables referenced from a lambda expression must be final
1082             // or effectively final' is reported when using i, so assign it to a final variable.
1083             final int currI = i;
1084             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1085                     (tm) -> tm.getDeviceId(currI));
1086         }
1087     }
1088 
verifyDeviceId(String deviceId)1089     private void verifyDeviceId(String deviceId) {
1090         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1091             // Either IMEI or MEID need to be valid.
1092             try {
1093                 assertImei(deviceId);
1094             } catch (AssertionError e) {
1095                 assertMeidEsn(deviceId);
1096             }
1097         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
1098             assertSerialNumber();
1099             assertMacAddress(getWifiMacAddress());
1100         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
1101             assertSerialNumber();
1102             assertMacAddress(getBluetoothMacAddress());
1103         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {
1104             assertTrue(mCm.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET) != null);
1105         }
1106     }
1107 
assertImei(String id)1108     private static void assertImei(String id) {
1109         assertFalse("Imei should not be empty or null", TextUtils.isEmpty(id));
1110         // IMEI may include the check digit
1111         String imeiPattern = "[0-9]{14,15}";
1112         String invalidPattern = "[0]{14,15}";
1113         assertTrue("IMEI " + id + " does not match pattern " + imeiPattern,
1114                 Pattern.matches(imeiPattern, id));
1115         assertFalse("IMEI " + id + " must not be a zero sequence" + invalidPattern,
1116                 Pattern.matches(invalidPattern, id));
1117         if (id.length() == 15) {
1118             // if the ID is 15 digits, the 15th must be a check digit.
1119             assertImeiCheckDigit(id);
1120         }
1121     }
1122 
assertImeiCheckDigit(String deviceId)1123     private static void assertImeiCheckDigit(String deviceId) {
1124         int expectedCheckDigit = getLuhnCheckDigit(deviceId.substring(0, 14));
1125         int actualCheckDigit = Character.digit(deviceId.charAt(14), 10);
1126         assertEquals("Incorrect check digit for " + deviceId, expectedCheckDigit, actualCheckDigit);
1127     }
1128 
1129     /**
1130      * Use decimal value (0-9) to index into array to get sum of its digits
1131      * needed by Lunh check.
1132      *
1133      * Example: DOUBLE_DIGIT_SUM[6] = 3 because 6 * 2 = 12 => 1 + 2 = 3
1134      */
1135     private static final int[] DOUBLE_DIGIT_SUM = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
1136 
1137     /**
1138      * Calculate the check digit by starting from the right, doubling every
1139      * each digit, summing all the digits including the doubled ones, and
1140      * finding a number to make the sum divisible by 10.
1141      *
1142      * @param deviceId not including the check digit
1143      * @return the check digit
1144      */
getLuhnCheckDigit(String deviceId)1145     private static int getLuhnCheckDigit(String deviceId) {
1146         int sum = 0;
1147         int dontDoubleModulus = deviceId.length() % 2;
1148         for (int i = deviceId.length() - 1; i >= 0; --i) {
1149             int digit = Character.digit(deviceId.charAt(i), 10);
1150             if (i % 2 == dontDoubleModulus) {
1151                 sum += digit;
1152             } else {
1153                 sum += DOUBLE_DIGIT_SUM[digit];
1154             }
1155         }
1156         sum %= 10;
1157         return sum == 0 ? 0 : 10 - sum;
1158     }
1159 
assertMeidEsn(String id)1160     private static void assertMeidEsn(String id) {
1161         // CDMA device IDs may either be a 14-hex-digit MEID or an
1162         // 8-hex-digit ESN.  If it's an ESN, it may not be a
1163         // pseudo-ESN.
1164         assertFalse("Meid ESN should not be empty or null", TextUtils.isEmpty(id));
1165         if (id.length() == 14) {
1166             assertMeidFormat(id);
1167         } else if (id.length() == 8) {
1168             assertHexadecimalEsnFormat(id);
1169         } else {
1170             fail("device id on CDMA must be 14-digit hex MEID or 8-digit hex ESN.");
1171         }
1172     }
1173 
assertHexadecimalEsnFormat(String deviceId)1174     private static void assertHexadecimalEsnFormat(String deviceId) {
1175         String esnPattern = "[0-9a-fA-F]{8}";
1176         String invalidPattern = "[0]{8}";
1177         assertTrue("ESN hex device id " + deviceId + " does not match pattern " + esnPattern,
1178                 Pattern.matches(esnPattern, deviceId));
1179         assertFalse("ESN hex device id " + deviceId + " must not be a pseudo-ESN",
1180                 "80".equals(deviceId.substring(0, 2)));
1181         assertFalse("ESN hex device id " + deviceId + "must not be a zero sequence",
1182                 Pattern.matches(invalidPattern, deviceId));
1183     }
1184 
assertMeidFormat(String deviceId)1185     private static void assertMeidFormat(String deviceId) {
1186         // MEID must NOT include the check digit.
1187         String meidPattern = "[0-9a-fA-F]{14}";
1188         String invalidPattern = "[0]{14}";
1189         assertTrue("MEID device id " + deviceId + " does not match pattern "
1190                 + meidPattern, Pattern.matches(meidPattern, deviceId));
1191         assertFalse("MEID device id " + deviceId + "must not be a zero sequence",
1192                 Pattern.matches(invalidPattern, deviceId));
1193     }
1194 
assertSerialNumber()1195     private void assertSerialNumber() {
1196         String serial = ShellIdentityUtils.invokeStaticMethodWithShellPermissions(
1197                 Build::getSerial);
1198         assertNotNull("Non-telephony devices must have a Build.getSerial() number.",
1199                 serial);
1200         assertTrue("Hardware id must be no longer than 20 characters.",
1201                 serial.length() <= 20);
1202         assertTrue("Hardware id must be alphanumeric.",
1203                 Pattern.matches("[0-9A-Za-z]+", serial));
1204     }
1205 
assertMacAddress(String macAddress)1206     private void assertMacAddress(String macAddress) {
1207         String macPattern = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}";
1208         assertTrue("MAC Address " + macAddress + " does not match pattern " + macPattern,
1209                 Pattern.matches(macPattern, macAddress));
1210     }
1211 
1212     /** @return mac address which requires the WiFi system to be enabled */
getWifiMacAddress()1213     private String getWifiMacAddress() {
1214         WifiManager wifiManager = getContext().getSystemService(WifiManager.class);
1215 
1216         if (wifiManager.isWifiEnabled()) {
1217             return wifiManager.getConnectionInfo().getMacAddress();
1218         } else {
1219             try {
1220                 runWithShellPermissionIdentity(() -> wifiManager.setWifiEnabled(true));
1221 
1222                 return wifiManager.getConnectionInfo().getMacAddress();
1223 
1224             } finally {
1225                 runWithShellPermissionIdentity(() -> wifiManager.setWifiEnabled(false));
1226             }
1227         }
1228     }
1229 
getBluetoothMacAddress()1230     private String getBluetoothMacAddress() {
1231         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1232         if (adapter == null) {
1233             return "";
1234         }
1235 
1236         return adapter.getAddress();
1237     }
1238 
1239     private static final String ISO_COUNTRY_CODE_PATTERN = "[a-z]{2}";
1240 
1241     @Test
testGetNetworkCountryIso()1242     public void testGetNetworkCountryIso() {
1243         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1244             String countryCode = mTelephonyManager.getNetworkCountryIso();
1245             assertTrue("Country code '" + countryCode + "' did not match "
1246                             + ISO_COUNTRY_CODE_PATTERN,
1247                     Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
1248 
1249             for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) {
1250                 countryCode = mTelephonyManager.getNetworkCountryIso(i);
1251 
1252                 assertTrue("Country code '" + countryCode + "' did not match "
1253                                 + ISO_COUNTRY_CODE_PATTERN + " for slot " + i,
1254                         Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
1255             }
1256         } else {
1257             // Non-telephony may still have the property defined if it has a SIM.
1258         }
1259     }
1260 
1261     @Test
testSetSystemSelectionChannels()1262     public void testSetSystemSelectionChannels() {
1263         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1264             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
1265             return;
1266         }
1267         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(1);
1268         final UiAutomation uiAutomation =
1269                 InstrumentationRegistry.getInstrumentation().getUiAutomation();
1270         try {
1271             uiAutomation.adoptShellPermissionIdentity();
1272             // This is a oneway binder call, meaning we may return before the permission check
1273             // happens. Hold shell permissions until we get a response.
1274             mTelephonyManager.setSystemSelectionChannels(Collections.emptyList(),
1275                     getContext().getMainExecutor(), queue::offer);
1276             Boolean result = queue.poll(1000, TimeUnit.MILLISECONDS);
1277             // Ensure we get a result
1278             assertNotNull(result);
1279             // Only verify the result for supported devices on IRadio 1.3+
1280             if (mRadioVersion >= RADIO_HAL_VERSION_1_3) {
1281                 assertTrue(result);
1282             }
1283         } catch (InterruptedException e) {
1284             fail("interrupted");
1285         } finally {
1286             uiAutomation.dropShellPermissionIdentity();
1287         }
1288 
1289         // Try calling the API that doesn't provide feedback. We have no way of knowing if it
1290         // succeeds, so just make sure nothing crashes.
1291         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1292                 tp -> tp.setSystemSelectionChannels(Collections.emptyList()));
1293 
1294         // TODO (b/189255895): Uncomment once getSystemSelection channels is functional in S QPR
1295         /**
1296         // getSystemSelectionChannels was added in IRadio 1.6, so ensure it returns
1297         // the value that was set by setSystemSelectionChannels.
1298         if (mRadioVersion >= RADIO_HAL_VERSION_1_6) {
1299             assertEquals(Collections.emptyList(),
1300                     ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1301                     TelephonyManager::getSystemSelectionChannels));
1302         }
1303          **/
1304     }
1305 
1306     @Test
testGetSimCountryIso()1307     public void testGetSimCountryIso() {
1308         String countryCode = mTelephonyManager.getSimCountryIso();
1309         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1310             assertTrue("Country code '" + countryCode + "' did not match "
1311                             + ISO_COUNTRY_CODE_PATTERN,
1312                     Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
1313         } else {
1314             // Non-telephony may still have the property defined if it has a SIM.
1315         }
1316     }
1317 
1318     @Test
testResetSettings()1319     public void testResetSettings() throws Exception {
1320         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1321             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
1322             return;
1323         }
1324 
1325         UserManager userManager = getContext().getSystemService(UserManager.class);
1326 
1327         boolean canChangeMobileNetworkSettings = userManager != null
1328                 && !userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
1329         assertTrue("Primary user must be able to configure mobile networks to pass this test",
1330                 canChangeMobileNetworkSettings);
1331         boolean initialDataSetting = isDataEnabled();
1332 
1333         //First check permissions are correct
1334         try {
1335             mTelephonyManager.resetSettings();
1336             fail("TelephonyManager#resetSettings requires the"
1337                     + " android.Manifest.permission.NETWORK_SETTINGS permission");
1338         } catch (SecurityException e) {
1339             //expected
1340         }
1341         // and then do a reset to move data to default.
1342         try {
1343             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1344                     TelephonyManager::resetSettings,
1345                     "android.permission.NETWORK_SETTINGS",
1346                     "android.permission.MODIFY_PHONE_STATE");
1347         } catch (SecurityException e) {
1348             e.printStackTrace();
1349             fail(e.toString());
1350         }
1351         // This may timeout because the default is equal to the initial data setting, but there is
1352         // no way to definitively check what the default should be, so assume the default will be
1353         // set within TOLERANCE time.
1354         TelephonyUtils.pollUntilTrue(() -> initialDataSetting != isDataEnabled(), 5 /*times*/,
1355                 TOLERANCE/5 /*timeout per poll*/);
1356 
1357         boolean defaultDataSetting = isDataEnabled();
1358 
1359         // set data to not the default!
1360         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1361                 tm -> tm.setDataEnabled(!defaultDataSetting));
1362         assertTrue("Data enable change didn't work",
1363                 TelephonyUtils.pollUntilTrue(() -> defaultDataSetting != isDataEnabled(),
1364                         5 /*times*/, TOLERANCE/5 /*timeout per poll*/));
1365 
1366         // and then do a reset to move data to default again.
1367         try {
1368             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1369                     TelephonyManager::resetSettings,
1370                     "android.permission.NETWORK_SETTINGS",
1371                     "android.permission.MODIFY_PHONE_STATE");
1372         } catch (SecurityException e) {
1373             e.printStackTrace();
1374             fail(e.toString());
1375         }
1376 
1377         assertTrue("resetSettings did not reset default data",
1378                 TelephonyUtils.pollUntilTrue(() -> defaultDataSetting == isDataEnabled(),
1379                         5 /*times*/, TOLERANCE/5 /*timeout per poll*/));
1380     }
1381 
1382     @Test
testGetServiceState()1383     public void testGetServiceState() throws InterruptedException {
1384         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
1385             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
1386             return;
1387         }
1388 
1389         TestThread t = new TestThread(new Runnable() {
1390             public void run() {
1391                 Looper.prepare();
1392 
1393                 mListener = new PhoneStateListener() {
1394                     @Override
1395                     public void onServiceStateChanged(ServiceState serviceState) {
1396                         synchronized (mLock) {
1397                             mServiceState = serviceState;
1398                             mLock.notify();
1399                         }
1400                     }
1401                 };
1402                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
1403                 Looper.loop();
1404             }
1405         });
1406 
1407         synchronized (mLock) {
1408             t.start();
1409             mLock.wait(TOLERANCE);
1410         }
1411 
1412         assertEquals(mServiceState, mTelephonyManager.getServiceState());
1413     }
1414 
1415     @Test
testGetServiceStateForInactiveSub()1416     public void testGetServiceStateForInactiveSub() {
1417         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
1418             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
1419             return;
1420         }
1421 
1422         int[] allSubs = mSubscriptionManager.getActiveSubscriptionIdList();
1423         // generate a subscription that is valid (>0) but inactive (not part of active subId list)
1424         // A simple way to do this is sum the active subIds and add 1
1425         int inactiveValidSub = 1;
1426         for (int sub : allSubs) {
1427             inactiveValidSub += sub;
1428         }
1429 
1430         assertNull(mTelephonyManager.createForSubscriptionId(inactiveValidSub).getServiceState());
1431     }
1432 
1433     private MockPhoneCapabilityListener mMockPhoneCapabilityListener;
1434 
1435     private class MockPhoneCapabilityListener extends TelephonyCallback
1436             implements TelephonyCallback.PhoneCapabilityListener {
1437         @Override
onPhoneCapabilityChanged(PhoneCapability capability)1438         public void onPhoneCapabilityChanged(PhoneCapability capability) {
1439             synchronized (mLock) {
1440                 mPhoneCapability = capability;
1441                 mOnPhoneCapabilityChanged = true;
1442                 mLock.notify();
1443             }
1444         }
1445     }
1446 
1447     @Test
testGetPhoneCapabilityAndVerify()1448     public void testGetPhoneCapabilityAndVerify() {
1449         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1450             Log.d(TAG,"skipping test that requires Telephony");
1451             return;
1452         }
1453         boolean is5gStandalone = getContext().getResources().getBoolean(
1454                 com.android.internal.R.bool.config_telephony5gStandalone);
1455         boolean is5gNonStandalone = getContext().getResources().getBoolean(
1456                 com.android.internal.R.bool.config_telephony5gNonStandalone);
1457         int[] deviceNrCapabilities = new int[0];
1458         if (is5gStandalone || is5gNonStandalone) {
1459             List<Integer> list = new ArrayList<>();
1460             if (is5gNonStandalone) {
1461                 list.add(DEVICE_NR_CAPABILITY_NSA);
1462             }
1463             if (is5gStandalone) {
1464                 list.add(DEVICE_NR_CAPABILITY_SA);
1465             }
1466             deviceNrCapabilities = list.stream().mapToInt(Integer::valueOf).toArray();
1467         }
1468 
1469         PhoneCapability phoneCapability = ShellIdentityUtils.invokeMethodWithShellPermissions(
1470                 mTelephonyManager, (tm) -> tm.getPhoneCapability());
1471 
1472         assertArrayEquals(deviceNrCapabilities, phoneCapability.getDeviceNrCapabilities());
1473     }
1474 
1475     @Test
testGetSimLocale()1476     public void testGetSimLocale() throws InterruptedException {
1477         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1478             Log.d(TAG,"skipping test that requires Telephony");
1479             return;
1480         }
1481         if (SubscriptionManager.getDefaultSubscriptionId()
1482                 == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1483             fail("Expected SIM inserted");
1484         }
1485         Locale locale = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1486                 (tm) -> tm.getSimLocale());
1487         Log.d(TAG, "testGetSimLocale: " + locale);
1488         assertNotNull(locale);
1489     }
1490 
1491     /**
1492      * Tests that a GSM device properly reports either the correct TAC (type allocation code) or
1493      * null.
1494      * The TAC should match the first 8 digits of the IMEI.
1495      */
1496     @Test
testGetTac()1497     public void testGetTac() {
1498         String tac = mTelephonyManager.getTypeAllocationCode();
1499         String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1500                 (tm) -> tm.getImei());
1501 
1502         if (tac == null || imei == null) {
1503             return;
1504         }
1505 
1506         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1507             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
1508                 assertEquals(imei.substring(0, 8), tac);
1509             }
1510         }
1511     }
1512 
1513     /**
1514      * Tests that a CDMA device properly reports either the correct MC (manufacturer code) or null.
1515      * The MC should match the first 8 digits of the MEID.
1516      */
1517     @Test
testGetMc()1518     public void testGetMc() {
1519         String mc = mTelephonyManager.getManufacturerCode();
1520         String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1521                 (tm) -> tm.getMeid());
1522 
1523         if (mc == null || meid == null) {
1524             return;
1525         }
1526 
1527         // mc and meid should either be null or supported. empty string is not expected even if
1528         // the device does not support mc/meid.
1529         assertNotEquals("", mc);
1530         assertNotEquals("", meid);
1531 
1532         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1533             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
1534                 assertEquals(meid.substring(0, 8), mc);
1535             }
1536         }
1537     }
1538 
1539     /**
1540      * Tests that the device properly reports either a valid IMEI or null.
1541      */
1542     @Test
testGetImei()1543     public void testGetImei() {
1544         String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1545                 (tm) -> tm.getImei());
1546 
1547         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1548             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
1549                 assertImei(imei);
1550             }
1551         }
1552     }
1553 
1554     /**
1555      * Tests that the device properly reports either a valid IMEI or null.
1556      */
1557     @Test
testGetImeiForSlot()1558     public void testGetImeiForSlot() {
1559         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1560             return;
1561         }
1562 
1563         for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) {
1564             // The compiler error 'local variables referenced from a lambda expression must be final
1565             // or effectively final' is reported when using i, so assign it to a final variable.
1566             final int currI = i;
1567             String imei = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1568                     (tm) -> tm.getImei(currI));
1569             if (!TextUtils.isEmpty(imei)) {
1570                 assertImei(imei);
1571             }
1572         }
1573 
1574         // Also verify that no exception is thrown for any slot index (including invalid ones)
1575         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1576                 (tm) -> tm.getImei(-1));
1577         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1578                 (tm) -> tm.getImei(mTelephonyManager.getPhoneCount()));
1579     }
1580 
1581     /**
1582      * Verifies that {@link TelephonyManager#getRadioPowerState()} does not throw any exception
1583      * and returns radio on.
1584      */
1585     @Test
testGetRadioPowerState()1586     public void testGetRadioPowerState() {
1587         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1588             return;
1589         }
1590 
1591         // Also verify that no exception is thrown.
1592         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
1593                 TelephonyManager.RADIO_POWER_ON);
1594     }
1595 
1596     /**
1597      * Verifies that {@link TelephonyManager#setCarrierDataEnabled(boolean)} does not throw any
1598      * exception. TODO enhance later if we have an API to get data enabled state.
1599      */
1600     @Test
testSetCarrierDataEnabled()1601     public void testSetCarrierDataEnabled() {
1602         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1603             return;
1604         }
1605         // Also verify that no exception is thrown.
1606         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1607                 (tm) -> tm.setCarrierDataEnabled(false));
1608         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1609                 (tm) -> tm.setCarrierDataEnabled(true));
1610     }
1611 
1612     /**
1613      * Verifies that {@link TelephonyManager#rebootRadio()} does not throw any exception
1614      * and final radio state is radio power on.
1615      */
1616     @Test
testRebootRadio()1617     public void testRebootRadio() throws Throwable {
1618         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1619             return;
1620         }
1621         TestThread t = new TestThread(new Runnable() {
1622             public void run() {
1623                 Looper.prepare();
1624 
1625                 mListener = new PhoneStateListener() {
1626                     @Override
1627                     public void onRadioPowerStateChanged(
1628                             @RadioPowerState int state) {
1629                         synchronized (mLock) {
1630                             if (state == TelephonyManager.RADIO_POWER_ON && mHasRadioPowerOff) {
1631                                 mRadioRebootTriggered = true;
1632                                 mLock.notify();
1633                             } else if (state == TelephonyManager.RADIO_POWER_OFF) {
1634                                 // reboot must go to power off
1635                                 mHasRadioPowerOff = true;
1636                             }
1637                         }
1638                     }
1639                 };
1640                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1641                         (tm) -> tm.listen(mListener,
1642                                 PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
1643                 Looper.loop();
1644             }
1645         });
1646 
1647         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
1648                 TelephonyManager.RADIO_POWER_ON);
1649         assertThat(mRadioRebootTriggered).isFalse();
1650         assertThat(mHasRadioPowerOff).isFalse();
1651         boolean success = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1652                 (tm) -> tm.rebootRadio());
1653         //skip this test if not supported or unsuccessful (success=false)
1654         if(!success) {
1655             return;
1656         }
1657 
1658         t.start();
1659         synchronized (mLock) {
1660             // reboot takes longer time
1661             if (!mRadioRebootTriggered) {
1662                 mLock.wait(20000);
1663             }
1664         }
1665         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
1666                 TelephonyManager.RADIO_POWER_ON);
1667         assertThat(mRadioRebootTriggered).isTrue();
1668 
1669         // note, other telephony states might not resumes properly at this point. e.g, service state
1670         // might still in the transition from OOS to In service. Thus we need to wait for in
1671         // service state before running next tests.
1672         t = new TestThread(new Runnable() {
1673             public void run() {
1674                 Looper.prepare();
1675 
1676                 mListener = new PhoneStateListener() {
1677                     @Override
1678                     public void onServiceStateChanged(ServiceState serviceState) {
1679                         synchronized (mLock) {
1680                             if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
1681                                 mServiceStateChangedCalled = true;
1682                                 mLock.notify();
1683                             }
1684                         }
1685                     }
1686                 };
1687                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
1688                         (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE));
1689                 Looper.loop();
1690             }
1691         });
1692 
1693         synchronized (mLock) {
1694             t.start();
1695             if (!mServiceStateChangedCalled) {
1696                 mLock.wait(60000);
1697             }
1698         }
1699         InstrumentationRegistry.getInstrumentation().getUiAutomation()
1700                 .adoptShellPermissionIdentity("android.permission.READ_PHONE_STATE");
1701         assertThat(mTelephonyManager.getServiceState().getState()).isEqualTo(
1702                 ServiceState.STATE_IN_SERVICE);
1703     }
1704 
1705     /**
1706      * Verifies that {@link TelephonyManager#getAidForAppType(int)} does not throw any exception
1707      * for all supported subscription app type.
1708      */
1709     @Test
testGetAidForAppType()1710     public void testGetAidForAppType() {
1711         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1712             return;
1713         }
1714         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1715                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_SIM));
1716         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1717                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_CSIM));
1718         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1719                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_RUIM));
1720         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1721                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_ISIM));
1722         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1723                 (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_USIM));
1724     }
1725 
1726     /**
1727      * Verifies that {@link TelephonyManager#getIsimDomain()} does not throw any exception
1728      */
1729     @Test
testGetIsimDomain()1730     public void testGetIsimDomain() {
1731         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1732             return;
1733         }
1734         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1735                 (tm) -> tm.getIsimDomain());
1736     }
1737 
1738     /**
1739      * Verifies that {@link TelephonyManager#getIsimImpu()} does not throw any exception when called
1740      * and has the correct permissions.
1741      */
1742     @Ignore("API moved back to @hide for Android R.")
1743     @Test
testGetIsimImpu()1744     public void testGetIsimImpu() {
1745         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1746             return;
1747         }
1748         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1749                 TelephonyManager::getIsimImpu);
1750         // Try without the correct permissions and ensure it fails.
1751         try {
1752             mTelephonyManager.getIsimImpu();
1753             fail();
1754         } catch (SecurityException e) {
1755             // expected
1756         }
1757     }
1758 
1759     /**
1760      * Basic test to ensure {@link NetworkRegistrationInfo#getRegisteredPlmn()} provides valid
1761      * information.
1762      */
1763     @Test
testNetworkRegistrationInfoRegisteredPlmn()1764     public void testNetworkRegistrationInfoRegisteredPlmn() {
1765         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1766             return;
1767         }
1768         // get NetworkRegistration object
1769         ServiceState ss = mTelephonyManager.getServiceState();
1770         assertNotNull(ss);
1771 
1772         boolean hasRegistered = false;
1773         for (NetworkRegistrationInfo nwReg : ss.getNetworkRegistrationInfoList()) {
1774             if (nwReg.isRegistered()
1775                         && nwReg.getTransportType() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
1776                 hasRegistered = true;
1777                 String plmnId = nwReg.getRegisteredPlmn();
1778                 // CDMA doesn't have PLMN IDs. Rather than put CID|NID here, instead it will be
1779                 // empty. It's a case that's becoming less important over time, but for now a
1780                 // device that's only registered on CDMA needs to pass this test.
1781                 if (nwReg.getCellIdentity() instanceof android.telephony.CellIdentityCdma) {
1782                     assertTrue(TextUtils.isEmpty(plmnId));
1783                 } else {
1784                     assertFalse(TextUtils.isEmpty(plmnId));
1785                     assertTrue("PlmnId() out of range [00000 - 999999], PLMN ID=" + plmnId,
1786                             plmnId.matches("^[0-9]{5,6}$"));
1787                 }
1788             }
1789         }
1790         assertTrue(hasRegistered);
1791     }
1792 
1793     /**
1794      * Basic test to ensure {@link NetworkRegistrationInfo#isRoaming()} does not throw any
1795      * exception.
1796      */
1797     @Test
testNetworkRegistrationInfoIsRoaming()1798     public void testNetworkRegistrationInfoIsRoaming() {
1799         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1800             return;
1801         }
1802         // get NetworkRegistration object
1803         NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
1804                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
1805                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1806         assertThat(nwReg).isNotNull();
1807         nwReg.isRoaming();
1808     }
1809 
1810     /**
1811      * Basic test to ensure {@link NetworkRegistrationInfo#getRoamingType()} ()} does not throw any
1812      * exception and returns valid result
1813      * @see ServiceState.RoamingType
1814      */
1815     @Test
testNetworkRegistrationInfoGetRoamingType()1816     public void testNetworkRegistrationInfoGetRoamingType() {
1817         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1818             return;
1819         }
1820         // get NetworkRegistration object for voice
1821         NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
1822                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
1823                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1824         assertNotNull(nwReg);
1825         assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
1826 
1827         // getNetworkRegistration object for data
1828         // get NetworkRegistration object for voice
1829         nwReg = mTelephonyManager.getServiceState()
1830                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
1831                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1832         assertThat(nwReg).isNotNull();
1833         assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
1834     }
1835 
1836     /**
1837      * Basic test to ensure {@link NetworkRegistrationInfo#getAccessNetworkTechnology()} not
1838      * throw any exception and returns valid result
1839      * @see android.telephony.Annotation.NetworkType
1840      */
1841     @Test
testNetworkRegistationStateGetAccessNetworkTechnology()1842     public void testNetworkRegistationStateGetAccessNetworkTechnology() {
1843         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1844             return;
1845         }
1846         // get NetworkRegistration object for voice
1847         NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
1848                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
1849                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1850         assertThat(nwReg).isNotNull();
1851         assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
1852 
1853         // get NetworkRegistation object for data
1854         nwReg = mTelephonyManager.getServiceState()
1855                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
1856                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
1857         assertThat(nwReg).isNotNull();
1858         assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
1859     }
1860 
1861 
1862     /**
1863      * Tests that the device properly reports either a valid MEID or null.
1864      */
1865     @Test
testGetMeid()1866     public void testGetMeid() {
1867         String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1868                 (tm) -> tm.getMeid());
1869 
1870         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1871             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
1872                 assertMeidEsn(meid);
1873             }
1874         }
1875     }
1876 
1877     /**
1878      * Tests that the device properly reports either a valid MEID or null.
1879      */
1880     @Test
testGetMeidForSlot()1881     public void testGetMeidForSlot() {
1882         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1883             return;
1884         }
1885 
1886         SubscriptionManager sm = getContext().getSystemService(SubscriptionManager.class);
1887         List<SubscriptionInfo> subInfos = sm.getActiveSubscriptionInfoList();
1888 
1889         if (subInfos != null) {
1890             for (SubscriptionInfo subInfo : subInfos) {
1891                 int slotIndex = subInfo.getSimSlotIndex();
1892                 int subId = subInfo.getSubscriptionId();
1893                 TelephonyManager tm = mTelephonyManager.createForSubscriptionId(subId);
1894                 if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
1895                     String meid = ShellIdentityUtils.invokeMethodWithShellPermissions(
1896                             mTelephonyManager,
1897                             (telephonyManager) -> telephonyManager.getMeid(slotIndex));
1898 
1899                     if (!TextUtils.isEmpty(meid)) {
1900                         assertMeidEsn(meid);
1901                     }
1902                 }
1903             }
1904         }
1905 
1906         // Also verify that no exception is thrown for any slot index (including invalid ones)
1907         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1908                 (tm) -> tm.getMeid(-1));
1909         ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
1910                 (tm) -> tm.getMeid(mTelephonyManager.getPhoneCount()));
1911     }
1912 
1913     /**
1914      * Tests sendDialerSpecialCode API.
1915      * Expects a security exception since the caller does not have carrier privileges or is not the
1916      * current default dialer app.
1917      */
1918     @Test
testSendDialerSpecialCode()1919     public void testSendDialerSpecialCode() {
1920         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1921             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
1922             return;
1923         }
1924         try {
1925             mTelephonyManager.sendDialerSpecialCode("4636");
1926             fail("Expected SecurityException. App does not have carrier privileges or is not the "
1927                     + "default dialer app");
1928         } catch (SecurityException expected) {
1929         }
1930     }
1931 
1932     /**
1933      * Tests that the device properly reports the contents of EF_FPLMN or null
1934      */
1935     @Test
testGetForbiddenPlmns()1936     public void testGetForbiddenPlmns() {
1937         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
1938             return;
1939         }
1940         String[] plmns = mTelephonyManager.getForbiddenPlmns();
1941 
1942         int phoneType = mTelephonyManager.getPhoneType();
1943         switch (phoneType) {
1944             case TelephonyManager.PHONE_TYPE_GSM:
1945                 assertNotNull("Forbidden PLMNs must be valid or an empty list!", plmns);
1946             case TelephonyManager.PHONE_TYPE_CDMA:
1947             case TelephonyManager.PHONE_TYPE_NONE:
1948                 if (plmns == null) {
1949                     return;
1950                 }
1951         }
1952 
1953         for(String plmn : plmns) {
1954             assertTrue(
1955                     "Invalid Length for PLMN-ID, must be 5 or 6! plmn=" + plmn,
1956                     plmn.length() >= 5 && plmn.length() <= 6);
1957             assertTrue(
1958                     "PLMNs must be strings of digits 0-9! plmn=" + plmn,
1959                     android.text.TextUtils.isDigitsOnly(plmn));
1960         }
1961     }
1962 
1963     /**
1964      * Tests that the device properly sets and pads the contents of EF_FPLMN
1965      */
1966     @Test
testSetForbiddenPlmns()1967     public void testSetForbiddenPlmns() {
1968         if (!supportSetFplmn()) {
1969             return;
1970         }
1971         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
1972         try {
1973             int numFplmnsSet = mTelephonyManager.setForbiddenPlmns(FPLMN_TEST);
1974             String[] writtenFplmns = mTelephonyManager.getForbiddenPlmns();
1975             assertEquals("Wrong return value for setFplmns with less than required fplmns: "
1976                     + numFplmnsSet, FPLMN_TEST.size(), numFplmnsSet);
1977             assertEquals("Wrong Fplmns content written", FPLMN_TEST, Arrays.asList(writtenFplmns));
1978         } finally {
1979             // Restore
1980             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
1981         }
1982     }
1983 
1984     /**
1985      * Tests that the device properly truncates the contents of EF_FPLMN when provided size
1986      * is too big.
1987      */
1988     @Test
testSetForbiddenPlmnsTruncate()1989     public void testSetForbiddenPlmnsTruncate() {
1990         if (!supportSetFplmn()) {
1991             return;
1992         }
1993         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
1994         try {
1995             List<String> targetFplmns = new ArrayList<>();
1996             for (int i = 0; i < MIN_FPLMN_NUM; i++) {
1997                 targetFplmns.add(PLMN_A);
1998             }
1999             for (int i = MIN_FPLMN_NUM; i < MAX_FPLMN_NUM; i++) {
2000                 targetFplmns.add(PLMN_B);
2001             }
2002             int numFplmnsSet = mTelephonyManager.setForbiddenPlmns(targetFplmns);
2003             String[] writtenFplmns = mTelephonyManager.getForbiddenPlmns();
2004             assertTrue("Wrong return value for setFplmns with overflowing fplmns: " + numFplmnsSet,
2005                     numFplmnsSet < MAX_FPLMN_NUM);
2006             assertEquals("Number of Fplmns set does not equal number of Fplmns available",
2007                     numFplmnsSet, writtenFplmns.length);
2008             assertEquals("Wrong Fplmns content written", targetFplmns.subList(0, numFplmnsSet),
2009                     Arrays.asList(writtenFplmns));
2010         } finally {
2011             // Restore
2012             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
2013         }
2014     }
2015 
2016     /**
2017      * Tests that the device properly deletes the contents of EF_FPLMN
2018      */
2019     @Test
testSetForbiddenPlmnsDelete()2020     public void testSetForbiddenPlmnsDelete() {
2021         if (!supportSetFplmn()) {
2022             return;
2023         }
2024         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
2025         try {
2026             // Support test for empty SIM
2027             List<String> targetDummyFplmns = new ArrayList<>();
2028             for (int i = 0; i < MIN_FPLMN_NUM; i++) {
2029                 targetDummyFplmns.add(PLMN_A);
2030             }
2031             mTelephonyManager.setForbiddenPlmns(targetDummyFplmns);
2032             String[] writtenDummyFplmns = mTelephonyManager.getForbiddenPlmns();
2033             assertEquals(targetDummyFplmns, Arrays.asList(writtenDummyFplmns));
2034 
2035             List<String> targetFplmns = new ArrayList<>();
2036             int numFplmnsSet = mTelephonyManager.setForbiddenPlmns(targetFplmns);
2037             String[] writtenFplmns = mTelephonyManager.getForbiddenPlmns();
2038             assertEquals("Wrong return value for setFplmns with empty list", 0, numFplmnsSet);
2039             assertEquals("Wrong number of Fplmns written", 0, writtenFplmns.length);
2040             // TODO wait for 10 minutes or so for the FPLMNS list to grow back
2041         } finally {
2042             // Restore
2043             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
2044         }
2045     }
2046 
2047 
2048     /**
2049      * Tests that setForbiddenPlmns properly handles null input
2050      */
2051     @Test
testSetForbiddenPlmnsVoid()2052     public void testSetForbiddenPlmnsVoid() {
2053         if (!supportSetFplmn()) {
2054             return;
2055         }
2056         String[] originalFplmns = mTelephonyManager.getForbiddenPlmns();
2057         try {
2058             mTelephonyManager.setForbiddenPlmns(null);
2059             fail("Expected IllegalArgumentException. Null input is not allowed");
2060         } catch (IllegalArgumentException expected) {
2061         } finally {
2062             // Restore
2063             mTelephonyManager.setForbiddenPlmns(Arrays.asList(originalFplmns));
2064         }
2065     }
2066 
2067     @Test
testGetEquivalentHomePlmns()2068     public void testGetEquivalentHomePlmns() {
2069         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2070             return;
2071         }
2072 
2073         List<String> plmns = mTelephonyManager.getEquivalentHomePlmns();
2074 
2075         if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_GSM) {
2076             assertEquals(0, plmns.size());
2077         } else {
2078             for (String plmn : plmns) {
2079                 assertTrue(
2080                         "Invalid Length for PLMN-ID, must be 5 or 6! plmn=" + plmn,
2081                         plmn.length() >= 5 && plmn.length() <= 6);
2082                 assertTrue(
2083                         "PLMNs must be strings of digits 0-9! plmn=" + plmn,
2084                         android.text.TextUtils.isDigitsOnly(plmn));
2085             }
2086         }
2087     }
2088 
2089     /**
2090      * Tests that the device properly reports the contents of ManualNetworkSelectionPlmn
2091      * The setting is not persisted selection
2092      */
2093     @Test
testGetManualNetworkSelectionPlmnNonPersisted()2094     public void testGetManualNetworkSelectionPlmnNonPersisted() {
2095         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2096             return;
2097         }
2098         if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_GSM) return;
2099 
2100         try {
2101             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2102                     (tm) -> tm.setNetworkSelectionModeManual(
2103                      TESTING_PLMN/* operatorNumeric */, false /* persistSelection */));
2104             String plmn = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2105                      (tm) -> tm.getManualNetworkSelectionPlmn());
2106             assertEquals(TESTING_PLMN, plmn);
2107         } finally {
2108             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2109                     (tm) -> tm.setNetworkSelectionModeAutomatic());
2110         }
2111     }
2112 
2113     /**
2114      * Tests that the device properly reports the contents of ManualNetworkSelectionPlmn
2115      * The setting is persisted selection
2116      */
2117     @Test
testGetManualNetworkSelectionPlmnPersisted()2118     public void testGetManualNetworkSelectionPlmnPersisted() {
2119         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2120             return;
2121         }
2122         if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_GSM) return;
2123 
2124         try {
2125             ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2126                     (tm) -> tm.setNetworkSelectionModeManual(
2127                      TESTING_PLMN/* operatorNumeric */, true /* persistSelection */));
2128             String plmn = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2129                      (tm) -> tm.getManualNetworkSelectionPlmn());
2130             assertEquals(TESTING_PLMN, plmn);
2131         } finally {
2132             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2133                     (tm) -> tm.setNetworkSelectionModeAutomatic());
2134         }
2135     }
2136 
2137     /**
2138      * Verify that TelephonyManager.getCardIdForDefaultEuicc returns a positive value or either
2139      * UNINITIALIZED_CARD_ID or UNSUPPORTED_CARD_ID.
2140      */
2141     @Test
testGetCardIdForDefaultEuicc()2142     public void testGetCardIdForDefaultEuicc() {
2143         int cardId = mTelephonyManager.getCardIdForDefaultEuicc();
2144         assertTrue("Card ID for default EUICC is not a valid value",
2145                 cardId == TelephonyManager.UNSUPPORTED_CARD_ID
2146                         || cardId == TelephonyManager.UNINITIALIZED_CARD_ID
2147                         || cardId >= 0);
2148     }
2149 
2150     /**
2151      * Tests that a SecurityException is thrown when trying to access UiccCardsInfo.
2152      */
2153     @Test
testGetUiccCardsInfoException()2154     public void testGetUiccCardsInfoException() {
2155         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2156             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
2157             return;
2158         }
2159         try {
2160             // Requires READ_PRIVILEGED_PHONE_STATE or carrier privileges
2161             List<UiccCardInfo> infos = mTelephonyManager.getUiccCardsInfo();
2162             fail("Expected SecurityException. App does not have carrier privileges");
2163         } catch (SecurityException e) {
2164         }
2165     }
2166 
2167     /**
2168      * Tests that UiccCardsInfo methods don't crash.
2169      */
2170     @Test
testGetUiccCardsInfo()2171     public void testGetUiccCardsInfo() {
2172         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2173             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
2174             return;
2175         }
2176         // Requires READ_PRIVILEGED_PHONE_STATE or carrier privileges
2177         List<UiccCardInfo> infos =
2178                 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2179                 (tm) -> tm.getUiccCardsInfo());
2180         // test that these methods don't crash
2181         if (infos.size() > 0) {
2182             UiccCardInfo info = infos.get(0);
2183             info.getIccId();
2184             info.getEid();
2185             info.isRemovable();
2186             info.isEuicc();
2187             info.getCardId();
2188             info.getSlotIndex();
2189         }
2190     }
2191 
getContext()2192     private static Context getContext() {
2193         return InstrumentationRegistry.getContext();
2194     }
2195 
2196     /**
2197      * Tests that the device properly reports the contents of NetworkSelectionMode
2198      */
2199     @Test
testGetNetworkSelectionMode()2200     public void testGetNetworkSelectionMode() {
2201         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2202             return;
2203         }
2204 
2205         try {
2206             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2207                     (tm) -> tm.setNetworkSelectionModeAutomatic());
2208         } catch (Exception e) {
2209         }
2210 
2211         int networkMode = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2212                 (tm) -> tm.getNetworkSelectionMode());
2213 
2214         assertEquals(TelephonyManager.NETWORK_SELECTION_MODE_AUTO, networkMode);
2215     }
2216 
2217     /**
2218      * Tests that the device properly sets the network selection mode to automatic.
2219      * Expects a security exception since the caller does not have carrier privileges.
2220      */
2221     @Test
testSetNetworkSelectionModeAutomatic()2222     public void testSetNetworkSelectionModeAutomatic() {
2223         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2224             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
2225             return;
2226         }
2227         try {
2228             mTelephonyManager.setNetworkSelectionModeAutomatic();
2229             fail("Expected SecurityException. App does not have carrier privileges.");
2230         } catch (SecurityException expected) {
2231         }
2232     }
2233 
2234     /**
2235      * Tests that the device properly asks the radio to connect to the input network and change
2236      * selection mode to manual.
2237      * Expects a security exception since the caller does not have carrier privileges.
2238      */
2239     @Test
testSetNetworkSelectionModeManual()2240     public void testSetNetworkSelectionModeManual() {
2241         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2242             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
2243             return;
2244         }
2245         try {
2246             mTelephonyManager.setNetworkSelectionModeManual(
2247                     "" /* operatorNumeric */, false /* persistSelection */);
2248             fail("Expected SecurityException. App does not have carrier privileges.");
2249         } catch (SecurityException expected) {
2250         }
2251     }
2252 
2253     /**
2254      * Tests that the device properly check whether selection mode was manual.
2255      */
2256     @Test
testIsManualNetworkSelectionAllowed()2257     public void testIsManualNetworkSelectionAllowed() {
2258         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2259             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
2260             return;
2261         }
2262         if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_GSM) return;
2263 
2264         assertTrue(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2265                 (tm) -> tm.isManualNetworkSelectionAllowed()));
2266     }
2267 
2268     /**
2269      * Construct a CallAttributes object and test getters.
2270      */
2271     @Test
testCallAttributes()2272     public void testCallAttributes() {
2273         CallQuality cq = new CallQuality();
2274         PreciseCallState pcs = new PreciseCallState();
2275         CallAttributes ca = new CallAttributes(pcs, TelephonyManager.NETWORK_TYPE_UNKNOWN, cq);
2276         assertEquals(pcs, ca.getPreciseCallState());
2277         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, ca.getNetworkType());
2278         assertEquals(cq, ca.getCallQuality());
2279     }
2280 
2281     /**
2282      * Checks that a zeroed-out default CallQuality object can be created
2283      */
2284     @Test
testCallQuality()2285     public void testCallQuality() {
2286         CallQuality cq = new CallQuality();
2287         assertEquals(0, cq.getDownlinkCallQualityLevel());
2288         assertEquals(0, cq.getUplinkCallQualityLevel());
2289         assertEquals(0, cq.getCallDuration());
2290         assertEquals(0, cq.getNumRtpPacketsTransmitted());
2291         assertEquals(0, cq.getNumRtpPacketsReceived());
2292         assertEquals(0, cq.getNumRtpPacketsTransmittedLost());
2293         assertEquals(0, cq.getNumRtpPacketsNotReceived());
2294         assertEquals(0, cq.getAverageRelativeJitter());
2295         assertEquals(0, cq.getMaxRelativeJitter());
2296         assertEquals(0, cq.getAverageRoundTripTime());
2297         assertEquals(0, cq.getCodecType());
2298         assertEquals(false, cq.isRtpInactivityDetected());
2299         assertEquals(false, cq.isIncomingSilenceDetectedAtCallSetup());
2300         assertEquals(false, cq.isOutgoingSilenceDetectedAtCallSetup());
2301     }
2302 
2303 
2304     // Reference: packages/services/Telephony/ecc/input/eccdata.txt
2305     private static final Map<String, String> EMERGENCY_NUMBERS_FOR_COUNTRIES =
2306             new HashMap<String, String>() {{
2307                 put("au", "000");
2308                 put("ca", "911");
2309                 put("de", "112");
2310                 put("gb", "999");
2311                 put("in", "112");
2312                 put("jp", "110");
2313                 put("sg", "999");
2314                 put("tw", "110");
2315                 put("us", "911");
2316             }};
2317 
2318     /**
2319      * Tests TelephonyManager.getEmergencyNumberList.
2320      *
2321      * Also enforce country-specific emergency number in CTS.
2322      */
2323     @Test
testGetEmergencyNumberList()2324     public void testGetEmergencyNumberList() {
2325         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2326             return;
2327         }
2328         Map<Integer, List<EmergencyNumber>> emergencyNumberList =
2329                 mTelephonyManager.getEmergencyNumberList();
2330 
2331         assertFalse(emergencyNumberList == null);
2332 
2333         checkEmergencyNumberFormat(emergencyNumberList);
2334 
2335         int defaultSubId = mSubscriptionManager.getDefaultSubscriptionId();
2336         for (Map.Entry<String, String> entry : EMERGENCY_NUMBERS_FOR_COUNTRIES.entrySet()) {
2337             if (mTelephonyManager.getNetworkCountryIso().equals(entry.getKey())) {
2338                 assertTrue(checkIfEmergencyNumberListHasSpecificAddress(
2339                         emergencyNumberList.get(defaultSubId), entry.getValue()));
2340             }
2341         }
2342     }
2343 
2344     /**
2345      * Tests TelephonyManager.getEmergencyNumberList(@EmergencyServiceCategories int categories).
2346      *
2347      */
2348     @Test
testGetEmergencyNumberListForCategories()2349     public void testGetEmergencyNumberListForCategories() {
2350         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2351             return;
2352         }
2353         Map<Integer, List<EmergencyNumber>> emergencyNumberList =
2354                 mTelephonyManager.getEmergencyNumberList(
2355                         EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
2356 
2357         assertFalse(emergencyNumberList == null);
2358 
2359         checkEmergencyNumberFormat(emergencyNumberList);
2360 
2361         int defaultSubId = mSubscriptionManager.getDefaultSubscriptionId();
2362         final String country_us = "us";
2363         final String country_us_police_number = "911";
2364         if (mTelephonyManager.getNetworkCountryIso().equals(country_us)) {
2365             assertTrue(checkIfEmergencyNumberListHasSpecificAddress(
2366                     emergencyNumberList.get(defaultSubId), country_us_police_number));
2367         }
2368         for (EmergencyNumber num : emergencyNumberList.get(defaultSubId)) {
2369             assertTrue(num.isInEmergencyServiceCategories(
2370                     EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
2371         }
2372     }
2373 
2374     /**
2375      * Tests TelephonyManager.isEmergencyNumber.
2376      *
2377      * Also enforce country-specific emergency number in CTS.
2378      */
2379     @Test
testIsEmergencyNumber()2380     public void testIsEmergencyNumber() {
2381         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2382             return;
2383         }
2384 
2385         for (Map.Entry<String, String> entry : EMERGENCY_NUMBERS_FOR_COUNTRIES.entrySet()) {
2386             if (mTelephonyManager.getNetworkCountryIso().equals(entry.getKey())) {
2387                 assertTrue(mTelephonyManager.isEmergencyNumber(entry.getValue()));
2388             }
2389         }
2390     }
2391 
2392     /**
2393      * Tests TelephonyManager.isPotentialEmergencyNumber.
2394      */
2395     @Test
testIsPotentialEmergencyNumber()2396     public void testIsPotentialEmergencyNumber() {
2397         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2398             return;
2399         }
2400 
2401         String countryIso = mTelephonyManager.getNetworkCountryIso();
2402         String potentialEmergencyAddress = "91112345";
2403         // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
2404         // these countries, if extra digits are added to an emergency number,
2405         // it no longer connects to the emergency service.
2406         if (countryIso.equals("br") || countryIso.equals("cl") || countryIso.equals("ni")) {
2407             assertFalse(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2408                     (tm) -> tm.isPotentialEmergencyNumber(potentialEmergencyAddress)));
2409         } else {
2410             assertTrue(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2411                     (tm) -> tm.isPotentialEmergencyNumber(potentialEmergencyAddress)));
2412         }
2413     }
2414 
2415     /**
2416      * Tests TelephonyManager.setCallComposerStatus and TelephonyManager.getCallComposerStatus.
2417      */
2418     @Test
testSetGetCallComposerStatus()2419     public void testSetGetCallComposerStatus() {
2420         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2421             return;
2422         }
2423 
2424         boolean hasImsFeature = mPackageManager.hasSystemFeature(
2425                 PackageManager.FEATURE_TELEPHONY_IMS);
2426 
2427         if (hasImsFeature) {
2428             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2429                     tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_OFF));
2430             int status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2431                     tm -> tm.getCallComposerStatus());
2432             assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2433 
2434             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2435                     tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_ON));
2436             status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2437                     tm -> tm.getCallComposerStatus());
2438             assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_ON);
2439         } else {
2440             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2441                     tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_OFF));
2442             int status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2443                     tm -> tm.getCallComposerStatus());
2444             assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2445 
2446             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2447                     tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_ON));
2448             status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2449                     tm -> tm.getCallComposerStatus());
2450             assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2451         }
2452     }
2453 
2454     /**
2455      * Tests {@link TelephonyManager#getSupportedRadioAccessFamily()}
2456      */
2457     @Test
testGetRadioAccessFamily()2458     public void testGetRadioAccessFamily() {
2459         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2460             return;
2461         }
2462         long raf = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2463                 (tm) -> tm.getSupportedRadioAccessFamily());
2464         assertThat(raf).isNotEqualTo(TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN);
2465     }
2466 
assertSetOpportunisticSubSuccess(int value)2467     private static void assertSetOpportunisticSubSuccess(int value) {
2468         assertThat(value).isEqualTo(TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS);
2469     }
2470 
assertSetOpportunisticNoOpportunisticSub(int value)2471     private static void assertSetOpportunisticNoOpportunisticSub(int value) {
2472         assertThat(value).isEqualTo(
2473                 TelephonyManager.SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE);
2474     }
2475 
2476     /**
2477      * Tests {@link TelephonyManager#setPreferredOpportunisticDataSubscription} and
2478      * {@link TelephonyManager#getPreferredOpportunisticDataSubscription}
2479      */
2480     @Test
testPreferredOpportunisticDataSubscription()2481     public void testPreferredOpportunisticDataSubscription() {
2482         int randomSubId = 1;
2483         int activeSubscriptionInfoCount = ShellIdentityUtils.invokeMethodWithShellPermissions(
2484                 mSubscriptionManager, (tm) -> tm.getActiveSubscriptionInfoCount());
2485         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2486             return;
2487         }
2488         if (mTelephonyManager.getPhoneCount() == 1) {
2489             return;
2490         }
2491         if (mTelephonyManager.getPhoneCount() == 2 && activeSubscriptionInfoCount != 2) {
2492             return;
2493         }
2494         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2495                 (tm) -> tm.setPreferredOpportunisticDataSubscription(
2496                         SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false,
2497                         null, null));
2498         // wait for the data change to take effect
2499         waitForMs(500);
2500         int subId =
2501                 ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2502                         (tm) -> tm.getPreferredOpportunisticDataSubscription());
2503         assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
2504         List<SubscriptionInfo> subscriptionInfoList =
2505                 ShellIdentityUtils.invokeMethodWithShellPermissions(mSubscriptionManager,
2506                         (tm) -> tm.getOpportunisticSubscriptions());
2507         Consumer<Integer> callbackSuccess = TelephonyManagerTest::assertSetOpportunisticSubSuccess;
2508         Consumer<Integer> callbackNoOpSub =
2509                 TelephonyManagerTest::assertSetOpportunisticNoOpportunisticSub;
2510         if (subscriptionInfoList == null || subscriptionInfoList.size() == 0) {
2511             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2512                     (tm) -> tm.setPreferredOpportunisticDataSubscription(randomSubId, false,
2513                             AsyncTask.SERIAL_EXECUTOR, callbackNoOpSub));
2514             // wait for the data change to take effect
2515             waitForMs(500);
2516             subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2517                     (tm) -> tm.getPreferredOpportunisticDataSubscription());
2518             assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
2519         } else {
2520             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2521                     (tm) -> tm.setPreferredOpportunisticDataSubscription(
2522                             subscriptionInfoList.get(0).getSubscriptionId(), false,
2523                             AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
2524             // wait for the data change to take effect
2525             waitForMs(500);
2526             subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2527                     (tm) -> tm.getPreferredOpportunisticDataSubscription());
2528             assertThat(subId).isEqualTo(subscriptionInfoList.get(0).getSubscriptionId());
2529         }
2530 
2531         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2532                 (tm) -> tm.setPreferredOpportunisticDataSubscription(
2533                         SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false,
2534                         AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
2535         // wait for the data change to take effect
2536         waitForMs(500);
2537         subId = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
2538                 (tm) -> tm.getPreferredOpportunisticDataSubscription());
2539         assertThat(subId).isEqualTo(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
2540     }
2541 
assertUpdateAvailableNetworkSuccess(int value)2542     private static void assertUpdateAvailableNetworkSuccess(int value) {
2543         assertThat(value).isEqualTo(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS);
2544     }
2545 
assertUpdateAvailableNetworkNoOpportunisticSub(int value)2546     private static void assertUpdateAvailableNetworkNoOpportunisticSub(int value) {
2547         assertThat(value).isEqualTo(
2548                 TelephonyManager.UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE);
2549     }
2550 
checkIfEmergencyNumberListHasSpecificAddress( List<EmergencyNumber> emergencyNumberList, String address)2551     private static boolean checkIfEmergencyNumberListHasSpecificAddress(
2552             List<EmergencyNumber> emergencyNumberList, String address) {
2553         for (EmergencyNumber emergencyNumber : emergencyNumberList) {
2554             if (address.equals(emergencyNumber.getNumber())) {
2555                 return true;
2556             }
2557         }
2558         return false;
2559     }
2560 
checkEmergencyNumberFormat( Map<Integer, List<EmergencyNumber>> emergencyNumberLists)2561     private static void checkEmergencyNumberFormat(
2562             Map<Integer, List<EmergencyNumber>> emergencyNumberLists) {
2563         for (List<EmergencyNumber> emergencyNumberList : emergencyNumberLists.values()) {
2564             for (EmergencyNumber emergencyNumber : emergencyNumberList) {
2565 
2566                 // Validate Emergency number address
2567                 assertTrue(validateEmergencyNumberAddress(emergencyNumber.getNumber()));
2568 
2569                 // Validate Emergency number country Iso
2570                 assertTrue(validateEmergencyNumberCountryIso(emergencyNumber.getCountryIso()));
2571 
2572                 // Validate Emergency number mnc
2573                 assertTrue(validateEmergencyNumberMnc(emergencyNumber.getMnc()));
2574 
2575                 // Validate Emergency service category list
2576                 assertTrue(validateEmergencyServiceCategoryList(
2577                         emergencyNumber.getEmergencyServiceCategories()));
2578 
2579                 // Validate Emergency number source list
2580                 assertTrue(validateEmergencyNumberSourceList(
2581                         emergencyNumber.getEmergencyNumberSources()));
2582 
2583                 // Validate Emergency URN list
2584                 // (just verify it is not null, because the support of this field is optional)
2585                 assertTrue(emergencyNumber.getEmergencyUrns() != null);
2586 
2587                 // Validat Emergency call routing
2588                 assertTrue(validateEmergencyCallRouting(
2589                         emergencyNumber.getEmergencyCallRouting()));
2590 
2591                 // Valid the emergency number should be at least in a valid source.
2592                 assertTrue(validateEmergencyNumberFromAnySource(emergencyNumber));
2593 
2594                 // Valid the emergency number should be at least in a valid category.
2595                 assertTrue(validateEmergencyNumberInAnyCategory(emergencyNumber));
2596             }
2597 
2598             // Validate compareTo
2599             assertTrue(validateEmergencyNumberCompareTo(emergencyNumberList));
2600         }
2601     }
2602 
2603     /**
2604      * Tests {@link TelephonyManager#updateAvailableNetworks}
2605      */
2606     @Test
testUpdateAvailableNetworks()2607     public void testUpdateAvailableNetworks() {
2608         int randomSubId = 1;
2609         int activeSubscriptionInfoCount = ShellIdentityUtils.invokeMethodWithShellPermissions(
2610                 mSubscriptionManager, (tm) -> tm.getActiveSubscriptionInfoCount());
2611         boolean isOpportunisticNetworkEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(
2612                 mTelephonyManager, (tm) -> tm.isOpportunisticNetworkEnabled());
2613 
2614         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2615             return;
2616         }
2617         if (!isOpportunisticNetworkEnabled) {
2618             return;
2619         }
2620         if (mTelephonyManager.getPhoneCount() == 1) {
2621             return;
2622         }
2623         if (mTelephonyManager.getPhoneCount() == 2 && activeSubscriptionInfoCount != 2) {
2624             return;
2625         }
2626 
2627         List<SubscriptionInfo> subscriptionInfoList =
2628                 ShellIdentityUtils.invokeMethodWithShellPermissions(mSubscriptionManager,
2629                         (tm) -> tm.getOpportunisticSubscriptions());
2630         List<String> mccMncs = new ArrayList<String>();
2631         List<Integer> bands = new ArrayList<Integer>();
2632         List<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<AvailableNetworkInfo>();
2633         Consumer<Integer> callbackSuccess =
2634                 TelephonyManagerTest::assertUpdateAvailableNetworkSuccess;
2635         Consumer<Integer> callbackNoOpSub =
2636                 TelephonyManagerTest::assertUpdateAvailableNetworkNoOpportunisticSub;
2637         if (subscriptionInfoList == null || subscriptionInfoList.size() == 0
2638                 || !mSubscriptionManager.isActiveSubscriptionId(
2639                 subscriptionInfoList.get(0).getSubscriptionId())) {
2640             AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(randomSubId,
2641                     AvailableNetworkInfo.PRIORITY_HIGH, mccMncs, bands);
2642             availableNetworkInfos.add(availableNetworkInfo);
2643             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2644                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2645                             AsyncTask.SERIAL_EXECUTOR, callbackNoOpSub));
2646             // wait for the data change to take effect
2647             waitForMs(500);
2648             // clear all the operations at the end of test.
2649             availableNetworkInfos.clear();
2650             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2651                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2652                             AsyncTask.SERIAL_EXECUTOR, callbackNoOpSub));
2653         } else {
2654             AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(
2655                     subscriptionInfoList.get(0).getSubscriptionId(),
2656                     AvailableNetworkInfo.PRIORITY_HIGH, mccMncs, bands);
2657             availableNetworkInfos.add(availableNetworkInfo);
2658             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2659                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2660                             AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
2661             // wait for the data change to take effect
2662             waitForMs(500);
2663             // clear all the operations at the end of test.
2664             availableNetworkInfos.clear();
2665             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
2666                     (tm) -> tm.updateAvailableNetworks(availableNetworkInfos,
2667                             AsyncTask.SERIAL_EXECUTOR, callbackSuccess));
2668         }
2669     }
2670 
2671     @Test
testSwitchMultiSimConfig()2672     public void testSwitchMultiSimConfig() {
2673         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2674             return;
2675         }
2676         try {
2677             mTelephonyManager.switchMultiSimConfig(mTelephonyManager.getActiveModemCount());
2678             fail("TelephonyManager#switchMultiSimConfig should require the MODIFY_PHONE_STATE"
2679                     + " permission to access.");
2680         } catch (SecurityException e) {
2681             // expected
2682         }
2683         try {
2684             // This should result in no-op.
2685             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mTelephonyManager,
2686                     (tm) -> tm.switchMultiSimConfig(mTelephonyManager.getActiveModemCount()),
2687                     SecurityException.class, "android.permission.MODIFY_PHONE_STATE");
2688         } catch (SecurityException e) {
2689             fail("TelephonyManager#switchMultiSimConfig should require MODIFY_PHONE_STATE"
2690                     + "permission to access.");
2691         }
2692     }
2693 
2694     @Test
testIccOpenLogicalChannelBySlot()2695     public void testIccOpenLogicalChannelBySlot() {
2696         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2697             return;
2698         }
2699         // just verify no crash
2700         try {
2701             ShellIdentityUtils.invokeMethodWithShellPermissions(
2702                     mTelephonyManager, (tm) -> tm.iccOpenLogicalChannelBySlot(0, null, 0));
2703         } catch (IllegalArgumentException e) {
2704             // IllegalArgumentException is okay, just not SecurityException
2705         }
2706     }
2707 
2708     @Test
testIccCloseLogicalChannelBySlot()2709     public void testIccCloseLogicalChannelBySlot() {
2710         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2711             return;
2712         }
2713         // just verify no crash
2714         try {
2715             ShellIdentityUtils.invokeMethodWithShellPermissions(
2716                     mTelephonyManager, (tm) -> tm.iccCloseLogicalChannelBySlot(0, 0));
2717         } catch (IllegalArgumentException e) {
2718             // IllegalArgumentException is okay, just not SecurityException
2719         }
2720     }
2721 
2722     @Test
testIccTransmitApduLogicalChannelBySlot()2723     public void testIccTransmitApduLogicalChannelBySlot() {
2724         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2725             return;
2726         }
2727         int slotIndex = getValidSlotIndex();
2728         String result = ShellIdentityUtils.invokeMethodWithShellPermissions(
2729                 mTelephonyManager, (tm) -> tm.iccTransmitApduLogicalChannelBySlot(
2730                         slotIndex,
2731                         0 /* channel */,
2732                         0 /* cla */,
2733                         0 /* instruction */,
2734                         0 /* p1 */,
2735                         0 /* p2 */,
2736                         0 /* p3 */,
2737                         null /* data */));
2738         assertTrue(TextUtils.isEmpty(result));
2739     }
2740 
2741     @Test
testIccTransmitApduBasicChannelBySlot()2742     public void testIccTransmitApduBasicChannelBySlot() {
2743         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2744             return;
2745         }
2746         // just verify no crash
2747         int slotIndex = getValidSlotIndex();
2748         try {
2749             ShellIdentityUtils.invokeMethodWithShellPermissions(
2750                     mTelephonyManager, (tm) -> tm.iccTransmitApduBasicChannelBySlot(
2751                             slotIndex,
2752                             0 /* cla */,
2753                             0 /* instruction */,
2754                             0 /* p1 */,
2755                             0 /* p2 */,
2756                             0 /* p3 */,
2757                             null /* data */));
2758         } catch (IllegalArgumentException e ) {
2759             // IllegalArgumentException is okay, just not SecurityException
2760         }
2761     }
2762 
2763     @Test
testIsIccLockEnabled()2764     public void testIsIccLockEnabled() {
2765         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2766             return;
2767         }
2768         // verify SecurityException
2769         try {
2770             mTelephonyManager.isIccLockEnabled();
2771             fail("testIsIccLockEnabled: Expected SecurityException on isIccLockEnabled");
2772         } catch (SecurityException se) {
2773             // expected
2774         }
2775 
2776         // test with permission
2777         try {
2778             ShellIdentityUtils.invokeMethodWithShellPermissions(
2779                     mTelephonyManager, (tm) -> tm.isIccLockEnabled());
2780         } catch (SecurityException se) {
2781             fail("testIsIccLockEnabled: SecurityException not expected");
2782         }
2783     }
2784 
2785     @Test
testIsDataEnabledForApn()2786     public void testIsDataEnabledForApn() {
2787         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2788             return;
2789         }
2790         // verify SecurityException
2791         try {
2792             mTelephonyManager.isDataEnabledForApn(ApnSetting.TYPE_MMS);
2793             fail("testIsDataEnabledForApn: Expected SecurityException on isDataEnabledForApn");
2794         } catch (SecurityException se) {
2795             // expected
2796         }
2797 
2798         // test with permission
2799         try {
2800             ShellIdentityUtils.invokeMethodWithShellPermissions(
2801                     mTelephonyManager, (tm) -> tm.isDataEnabledForApn(ApnSetting.TYPE_MMS));
2802         } catch (SecurityException se) {
2803             fail("testIsDataEnabledForApn: SecurityException not expected");
2804         }
2805     }
2806 
2807     @Test
testIsTetheringApnRequired()2808     public void testIsTetheringApnRequired() {
2809         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2810             return;
2811         }
2812         // verify SecurityException
2813         try {
2814             mTelephonyManager.isTetheringApnRequired();
2815             fail("testIsTetheringApnRequired: Expected SecurityException on "
2816                     + "isTetheringApnRequired");
2817         } catch (SecurityException se) {
2818             // expected
2819         }
2820 
2821         // test with permission
2822         try {
2823             ShellIdentityUtils.invokeMethodWithShellPermissions(
2824                     mTelephonyManager, (tm) -> tm.isTetheringApnRequired());
2825         } catch (SecurityException se) {
2826             fail("testIsIccLockEnabled: SecurityException not expected");
2827         }
2828     }
2829 
2830     @Test
testGetCarrierInfoForImsiEncryption()2831     public void testGetCarrierInfoForImsiEncryption() {
2832         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2833             return;
2834         }
2835         // test without permission: verify SecurityException
2836         try {
2837             mTelephonyManager.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_EPDG);
2838             fail("testGetCarrierInfoForImsiEncryption: "
2839                     + "SecurityException expected on getCarrierInfoForImsiEncryption");
2840         } catch (SecurityException se) {
2841             // expected
2842         }
2843         try {
2844             mTelephonyManager.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_WLAN);
2845             fail("testGetCarrierInfoForImsiEncryption: "
2846                     + "SecurityException expected on getCarrierInfoForImsiEncryption");
2847         } catch (SecurityException se) {
2848             // expected
2849         }
2850         // test with permission
2851         PublicKey epdgKey = null;
2852         PublicKey wlanKey = null;
2853         try {
2854             PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mTestSub);
2855 
2856             assertNotNull("CarrierConfigManager#getConfigForSubId() returned null",
2857                     carrierConfig);
2858             assertFalse("CarrierConfigManager#getConfigForSubId() returned empty bundle",
2859                     carrierConfig.isEmpty());
2860 
2861             // purge the certs in carrierConfigs first
2862             carrierConfig.putInt(
2863                     CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3);
2864             carrierConfig.putString(
2865                     CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, BAD_IMSI_CERT_URL);
2866             carrierConfig.putString(
2867                     CarrierConfigManager.IMSI_CARRIER_PUBLIC_KEY_EPDG_STRING,
2868                     IMSI_CERT_STRING_EPDG);
2869             carrierConfig.putString(
2870                     CarrierConfigManager.IMSI_CARRIER_PUBLIC_KEY_WLAN_STRING,
2871                     IMSI_CERT_STRING_WLAN);
2872             overrideCarrierConfig(carrierConfig);
2873         } catch (Exception e) {
2874             fail("Could not override carrier config. e=" + e.toString());
2875         }
2876 
2877         try {
2878             // It appears that the two certs actually have the same public key. Ideally we would
2879             // want these to be different for testing, but it's challenging to create a valid
2880             // certificate string for testing and these are the only two examples available
2881             InputStream inStream = new ByteArrayInputStream(IMSI_CERT_STRING_WLAN.getBytes());
2882             CertificateFactory cf = CertificateFactory.getInstance("X.509");
2883             X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
2884             wlanKey = cert.getPublicKey();
2885 
2886             inStream = new ByteArrayInputStream(IMSI_CERT_STRING_EPDG.getBytes());
2887             cert = (X509Certificate) cf.generateCertificate(inStream);
2888             epdgKey = cert.getPublicKey();
2889         } catch (CertificateException e) {
2890             fail("Could not create certs. e=" + e.toString());
2891         }
2892 
2893         try {
2894             ImsiEncryptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(
2895                     mTelephonyManager,
2896                     (tm) -> {
2897                         return tm.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_EPDG);
2898                     });
2899             assertNotNull("Encryption info returned null", info);
2900             assertEquals(epdgKey, info.getPublicKey());
2901             assertEquals(TelephonyManager.KEY_TYPE_EPDG, info.getKeyType());
2902         } catch (SecurityException se) {
2903             fail("testGetCarrierInfoForImsiEncryption: SecurityException not expected");
2904         } catch (IllegalArgumentException iae) {
2905             // IllegalArgumentException is okay, just not SecurityException
2906         }
2907         try {
2908             ImsiEncryptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(
2909                     mTelephonyManager,
2910                     (tm) -> {
2911                         return tm.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_WLAN);
2912                     });
2913             assertNotNull("Encryption info returned null", info);
2914             assertEquals(wlanKey, info.getPublicKey());
2915             assertEquals(TelephonyManager.KEY_TYPE_WLAN, info.getKeyType());
2916         } catch (SecurityException se) {
2917             fail("testGetCarrierInfoForImsiEncryption: SecurityException not expected");
2918         } catch (IllegalArgumentException iae) {
2919             // IllegalArgumentException is okay, just not SecurityException
2920         }
2921     }
2922 
2923     @Test
testResetCarrierKeysForImsiEncryption()2924     public void testResetCarrierKeysForImsiEncryption() {
2925         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2926             return;
2927         }
2928         // test without permission: verify SecurityException
2929         try {
2930             mTelephonyManager.resetCarrierKeysForImsiEncryption();
2931             fail("testResetCarrierKeysForImsiEncryption: SecurityException expected");
2932         } catch (SecurityException se) {
2933             // expected
2934         }
2935         // test with permission
2936         try {
2937             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2938                     mTelephonyManager,
2939                     (tm) -> tm.resetCarrierKeysForImsiEncryption());
2940         } catch (SecurityException se) {
2941             fail("testResetCarrierKeysForImsiEncryption: SecurityException not expected");
2942         }
2943     }
2944 
2945     @Test
testIsInEmergencySmsMode()2946     public void testIsInEmergencySmsMode() {
2947         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2948             return;
2949         }
2950         // test without permission: verify SecurityException
2951         try {
2952             mTelephonyManager.isInEmergencySmsMode();
2953             fail("testIsInEmergencySmsMode: SecurityException expected");
2954         } catch (SecurityException se) {
2955             // expected
2956         }
2957         // test with permission
2958         try {
2959             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2960                     mTelephonyManager,
2961                     (tm) -> tm.isInEmergencySmsMode());
2962         } catch (SecurityException se) {
2963             fail("testIsInEmergencySmsMode: SecurityException not expected");
2964         }
2965     }
2966 
2967     @Test
testGetSubscriptionId()2968     public void testGetSubscriptionId() {
2969         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2970             return;
2971         }
2972 
2973         TelephonyManager tm = mTelephonyManager.createForSubscriptionId(1);
2974         int subId = tm.getSubscriptionId();
2975         assertEquals(1, subId);
2976     }
2977 
2978     @Test
testSetAllowedNetworkTypes()2979     public void testSetAllowedNetworkTypes() {
2980         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
2981             return;
2982         }
2983 
2984         // test without permission: verify SecurityException
2985         long allowedNetworkTypes = TelephonyManager.NETWORK_TYPE_BITMASK_NR;
2986         try {
2987             mTelephonyManager.setAllowedNetworkTypes(allowedNetworkTypes);
2988             fail("testSetPolicyDataEnabled: SecurityException expected");
2989         } catch (SecurityException se) {
2990             // expected
2991         }
2992 
2993         // test with permission
2994         try {
2995             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
2996                     mTelephonyManager,
2997                     (tm) -> tm.setAllowedNetworkTypes(allowedNetworkTypes));
2998 
2999             long deviceAllowedNetworkTypes = ShellIdentityUtils.invokeMethodWithShellPermissions(
3000                     mTelephonyManager, (tm) -> {
3001                         return tm.getAllowedNetworkTypes();
3002                     }
3003             );
3004             assertEquals(allowedNetworkTypes, deviceAllowedNetworkTypes);
3005         } catch (SecurityException se) {
3006             fail("testSetAllowedNetworkTypes: SecurityException not expected");
3007         }
3008     }
3009 
3010     @Test
testDisAllowedNetworkTypes()3011     public void testDisAllowedNetworkTypes() {
3012         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3013             return;
3014         }
3015 
3016         long allowedNetworkTypes = -1 & (~TelephonyManager.NETWORK_TYPE_BITMASK_NR);
3017         long networkTypeBitmask = TelephonyManager.NETWORK_TYPE_BITMASK_NR
3018                 | TelephonyManager.NETWORK_TYPE_BITMASK_LTE
3019                 | TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
3020 
3021         try {
3022             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3023                     mTelephonyManager,
3024                     (tm) -> tm.setAllowedNetworkTypes(allowedNetworkTypes));
3025 
3026             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3027                     mTelephonyManager,
3028                     (tm) -> tm.setPreferredNetworkTypeBitmask(networkTypeBitmask));
3029 
3030             long modemNetworkTypeBitmask = ShellIdentityUtils.invokeMethodWithShellPermissions(
3031                     mTelephonyManager, (tm) -> {
3032                         return tm.getPreferredNetworkTypeBitmask();
3033                     }
3034             );
3035             long radioAccessFamily = ShellIdentityUtils.invokeMethodWithShellPermissions(
3036                     mTelephonyManager, (tm) -> {
3037                         return tm.getSupportedRadioAccessFamily();
3038                     }
3039             );
3040 
3041             // RadioAccessFamily won't include all bits of RAFs group, so transfer to preferred
3042             // network type instead of using bitmask directly
3043             int modemPreferredNetworkType = RadioAccessFamily.getNetworkTypeFromRaf(
3044                     (int) modemNetworkTypeBitmask);
3045             int preferredNetworkType = RadioAccessFamily.getNetworkTypeFromRaf(
3046                     (int) (networkTypeBitmask & allowedNetworkTypes & radioAccessFamily));
3047             assertEquals(preferredNetworkType, modemPreferredNetworkType);
3048         } catch (SecurityException se) {
3049             fail("testDisAllowedNetworkTypes: SecurityException not expected");
3050         }
3051     }
3052 
3053     @Test
testSetAllowedNetworkTypesForReason()3054     public void testSetAllowedNetworkTypesForReason() {
3055         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3056             return;
3057         }
3058 
3059         // test without permission: verify SecurityException
3060         long allowedNetworkTypes = TelephonyManager.NETWORK_TYPE_BITMASK_NR;
3061         try {
3062             mIsAllowedNetworkTypeChanged = true;
3063             mTelephonyManager.setAllowedNetworkTypesForReason(
3064                     TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER, allowedNetworkTypes);
3065             fail("testSetPolicyDataEnabled: SecurityException expected");
3066         } catch (SecurityException se) {
3067             // expected
3068         }
3069 
3070         // test with permission
3071         try {
3072             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3073                     mTelephonyManager,
3074                     (tm) -> tm.setAllowedNetworkTypesForReason(
3075                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER,
3076                             allowedNetworkTypes));
3077 
3078             long deviceAllowedNetworkTypes = ShellIdentityUtils.invokeMethodWithShellPermissions(
3079                     mTelephonyManager, (tm) -> {
3080                         return tm.getAllowedNetworkTypesForReason(
3081                                 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER);
3082                     }
3083             );
3084             assertEquals(allowedNetworkTypes, deviceAllowedNetworkTypes);
3085         } catch (SecurityException se) {
3086             fail("testSetAllowedNetworkTypes: SecurityException not expected");
3087         }
3088     }
3089 
3090     @Test
testSetAllowedNetworkTypesForReason_moreReason()3091     public void testSetAllowedNetworkTypesForReason_moreReason() {
3092         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3093             return;
3094         }
3095 
3096         // test without permission: verify SecurityException
3097         long allowedNetworkTypes1 = TelephonyManager.NETWORK_TYPE_BITMASK_NR
3098                 | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
3099         long allowedNetworkTypes2 = TelephonyManager.NETWORK_TYPE_BITMASK_LTE
3100                 | TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
3101         long allowedNetworkTypes3 = TelephonyManager.NETWORK_TYPE_BITMASK_NR
3102                 | TelephonyManager.NETWORK_TYPE_BITMASK_LTE
3103                 | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
3104         long allowedNetworkTypes4 = TelephonyManager.NETWORK_TYPE_LTE
3105                 | TelephonyManager.NETWORK_TYPE_EVDO_B;
3106 
3107         try {
3108             mIsAllowedNetworkTypeChanged = true;
3109             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3110                     mTelephonyManager,
3111                     (tm) -> tm.setAllowedNetworkTypesForReason(
3112                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER,
3113                             allowedNetworkTypes1));
3114 
3115             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3116                     mTelephonyManager,
3117                     (tm) -> tm.setAllowedNetworkTypesForReason(
3118                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
3119                             allowedNetworkTypes2));
3120             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3121                     mTelephonyManager,
3122                     (tm) -> tm.setAllowedNetworkTypesForReason(
3123                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER,
3124                             allowedNetworkTypes3));
3125             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3126                     mTelephonyManager,
3127                     (tm) -> tm.setAllowedNetworkTypesForReason(
3128                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G,
3129                             allowedNetworkTypes4));
3130             long deviceAllowedNetworkTypes1 = ShellIdentityUtils.invokeMethodWithShellPermissions(
3131                     mTelephonyManager, (tm) -> {
3132                         return tm.getAllowedNetworkTypesForReason(
3133                                 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER);
3134                     }
3135             );
3136             long deviceAllowedNetworkTypes2 = ShellIdentityUtils.invokeMethodWithShellPermissions(
3137                     mTelephonyManager, (tm) -> {
3138                         return tm.getAllowedNetworkTypesForReason(
3139                                 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3140                     }
3141             );
3142             long deviceAllowedNetworkTypes3 = ShellIdentityUtils.invokeMethodWithShellPermissions(
3143                     mTelephonyManager, (tm) -> {
3144                         return tm.getAllowedNetworkTypesForReason(
3145                                 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER);
3146                     }
3147             );
3148             long deviceAllowedNetworkTypes4 = ShellIdentityUtils.invokeMethodWithShellPermissions(
3149                     mTelephonyManager, (tm) -> {
3150                         return tm.getAllowedNetworkTypesForReason(
3151                                 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
3152                     }
3153             );
3154             assertEquals(allowedNetworkTypes1, deviceAllowedNetworkTypes1);
3155             assertEquals(allowedNetworkTypes2, deviceAllowedNetworkTypes2);
3156             assertEquals(allowedNetworkTypes3, deviceAllowedNetworkTypes3);
3157             assertEquals(allowedNetworkTypes4, deviceAllowedNetworkTypes4);
3158         } catch (SecurityException se) {
3159             fail("testSetAllowedNetworkTypes: SecurityException not expected");
3160         }
3161     }
3162 
3163     @Test
testIsApplicationOnUicc()3164     public void testIsApplicationOnUicc() {
3165         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3166             return;
3167         }
3168 
3169         // Expect a security exception without permission.
3170         try {
3171             mTelephonyManager.isApplicationOnUicc(TelephonyManager.APPTYPE_SIM);
3172             fail("Expected security exception");
3173         } catch (SecurityException se1) {
3174             // Expected
3175         }
3176 
3177         InstrumentationRegistry.getInstrumentation().getUiAutomation()
3178                 .adoptShellPermissionIdentity("android.permission.READ_PRIVILEGED_PHONE_STATE");
3179         try {
3180             mTelephonyManager.isApplicationOnUicc(TelephonyManager.APPTYPE_SIM);
3181         } catch (SecurityException se) {
3182             fail("Caller with READ_PRIVILEGED_PHONE_STATE should be able to call API");
3183         } finally {
3184             InstrumentationRegistry.getInstrumentation().getUiAutomation()
3185                     .dropShellPermissionIdentity();
3186         }
3187     }
3188 
3189     @Test
testRequestModemActivityInfo()3190     public void testRequestModemActivityInfo() throws Exception {
3191         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3192             return;
3193         }
3194 
3195         InstrumentationRegistry.getInstrumentation().getUiAutomation()
3196                 .adoptShellPermissionIdentity("android.permission.MODIFY_PHONE_STATE");
3197         try {
3198             // Get one instance of activity info and make sure it's valid
3199             CompletableFuture<ModemActivityInfo> future1 = new CompletableFuture<>();
3200             mTelephonyManager.requestModemActivityInfo(getContext().getMainExecutor(),
3201                     future1::complete);
3202             ModemActivityInfo activityInfo1 = future1.get(TOLERANCE, TimeUnit.MILLISECONDS);
3203             assertNotNull(activityInfo1);
3204             assertTrue("first activity info is" + activityInfo1, activityInfo1.isValid());
3205 
3206             // Wait a bit, then get another instance to make sure that some info has accumulated
3207             CompletableFuture<ModemActivityInfo> future2 = new CompletableFuture<>();
3208             mTelephonyManager.requestModemActivityInfo(getContext().getMainExecutor(),
3209                     future2::complete);
3210             ModemActivityInfo activityInfo2 = future2.get(TOLERANCE, TimeUnit.MILLISECONDS);
3211             assertNotNull(activityInfo2);
3212             assertTrue("second activity info is" + activityInfo2, activityInfo2.isValid());
3213 
3214             ModemActivityInfo diff = activityInfo1.getDelta(activityInfo2);
3215             assertNotNull(diff);
3216             assertTrue("diff is" + diff, diff.isValid() || diff.isEmpty());
3217         } finally {
3218             InstrumentationRegistry.getInstrumentation().getUiAutomation()
3219                     .dropShellPermissionIdentity();
3220         }
3221     }
3222 
3223     @Test
testModemActivityInfoException()3224     public void testModemActivityInfoException() {
3225         TelephonyManager.ModemActivityInfoException exception =
3226                 new TelephonyManager.ModemActivityInfoException(
3227                         TelephonyManager.ModemActivityInfoException.ERROR_PHONE_NOT_AVAILABLE);
3228         assertEquals(TelephonyManager.ModemActivityInfoException.ERROR_PHONE_NOT_AVAILABLE,
3229                 exception.getErrorCode());
3230     }
3231 
3232     @Test
testGetSupportedModemCount()3233     public void testGetSupportedModemCount() {
3234         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3235             return;
3236         }
3237 
3238         int supportedModemCount = mTelephonyManager.getSupportedModemCount();
3239         int activeModemCount = mTelephonyManager.getActiveModemCount();
3240         assertTrue(activeModemCount >= 0);
3241         assertTrue(supportedModemCount >= activeModemCount);
3242     }
3243 
3244     @Test
testGetAllNetworkTypes()3245     public void testGetAllNetworkTypes() {
3246         Set<Integer> expectedNetworkTypes = new HashSet<>(Arrays.asList(
3247                 TelephonyManager.NETWORK_TYPE_GPRS,
3248                 TelephonyManager.NETWORK_TYPE_EDGE,
3249                 TelephonyManager.NETWORK_TYPE_UMTS,
3250                 TelephonyManager.NETWORK_TYPE_CDMA,
3251                 TelephonyManager.NETWORK_TYPE_EVDO_0,
3252                 TelephonyManager.NETWORK_TYPE_EVDO_A,
3253                 TelephonyManager.NETWORK_TYPE_1xRTT,
3254                 TelephonyManager.NETWORK_TYPE_HSDPA,
3255                 TelephonyManager.NETWORK_TYPE_HSUPA,
3256                 TelephonyManager.NETWORK_TYPE_HSPA,
3257                 TelephonyManager.NETWORK_TYPE_IDEN,
3258                 TelephonyManager.NETWORK_TYPE_EVDO_B,
3259                 TelephonyManager.NETWORK_TYPE_LTE,
3260                 TelephonyManager.NETWORK_TYPE_EHRPD,
3261                 TelephonyManager.NETWORK_TYPE_HSPAP,
3262                 TelephonyManager.NETWORK_TYPE_GSM,
3263                 TelephonyManager.NETWORK_TYPE_TD_SCDMA,
3264                 TelephonyManager.NETWORK_TYPE_IWLAN,
3265                 TelephonyManager.NETWORK_TYPE_LTE_CA,
3266                 TelephonyManager.NETWORK_TYPE_NR
3267         ));
3268 
3269         Set<Integer> actualNetworkTypes = IntStream.of(TelephonyManager.getAllNetworkTypes())
3270                 .boxed().collect(Collectors.toSet());
3271         assertTrue(expectedNetworkTypes.containsAll(actualNetworkTypes));
3272         assertTrue(actualNetworkTypes.containsAll(expectedNetworkTypes));
3273     }
3274 
3275     @Test
testIsModemEnabledForSlot()3276     public void testIsModemEnabledForSlot() {
3277         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3278             return;
3279         }
3280 
3281         int activeModemCount = mTelephonyManager.getActiveModemCount();
3282         for (int i = 0; i < activeModemCount; i++) {
3283             // Call isModemEnabledForSlot for each slot and verify no crash.
3284             mTelephonyManager.isModemEnabledForSlot(i);
3285         }
3286     }
3287 
3288     @Test
testOpportunisticNetworkState()3289     public void testOpportunisticNetworkState() {
3290         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3291             return;
3292         }
3293         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
3294             return;
3295         }
3296 
3297         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3298                 tm -> tm.isOpportunisticNetworkEnabled());
3299         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3300                 tm -> tm.setOpportunisticNetworkState(true));
3301         assertTrue(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3302                 tm -> tm.isOpportunisticNetworkEnabled()));
3303         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3304                 tm -> tm.setOpportunisticNetworkState(false));
3305         assertFalse(ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3306                 tm -> tm.isOpportunisticNetworkEnabled()));
3307         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3308                 tm -> tm.setOpportunisticNetworkState(isEnabled));
3309     }
3310 
3311     @Test
testGetSimApplicationState()3312     public void testGetSimApplicationState() {
3313         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3314             return;
3315         }
3316         int simApplicationState = mTelephonyManager.getSimApplicationState();
3317         assertTrue(Arrays.asList(TelephonyManager.SIM_STATE_UNKNOWN,
3318                 TelephonyManager.SIM_STATE_PIN_REQUIRED,
3319                 TelephonyManager.SIM_STATE_PUK_REQUIRED,
3320                 TelephonyManager.SIM_STATE_NETWORK_LOCKED,
3321                 TelephonyManager.SIM_STATE_NOT_READY,
3322                 TelephonyManager.SIM_STATE_PERM_DISABLED,
3323                 TelephonyManager.SIM_STATE_LOADED).contains(simApplicationState));
3324     }
3325 
3326     @Test
testGetSimCardState()3327     public void testGetSimCardState() {
3328         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3329             return;
3330         }
3331         int simCardState = mTelephonyManager.getSimCardState();
3332         assertTrue(Arrays.asList(TelephonyManager.SIM_STATE_UNKNOWN,
3333                 TelephonyManager.SIM_STATE_ABSENT,
3334                 TelephonyManager.SIM_STATE_CARD_IO_ERROR,
3335                 TelephonyManager.SIM_STATE_CARD_RESTRICTED,
3336                 TelephonyManager.SIM_STATE_PRESENT).contains(simCardState));
3337     }
3338 
isDataEnabled()3339     private boolean isDataEnabled() {
3340         return ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3341                 TelephonyManager::isDataEnabled);
3342     }
3343 
3344     @Test
testThermalDataEnable()3345     public void testThermalDataEnable() {
3346         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3347             return;
3348         }
3349 
3350         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3351                 mTelephonyManager,
3352                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
3353                         false));
3354 
3355         boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3356                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3357                         TelephonyManager.DATA_ENABLED_REASON_THERMAL));
3358         assertFalse(isDataEnabledForReason);
3359 
3360         boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3361                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3362         assertFalse(isDataConnectionAvailable);
3363 
3364         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3365                 mTelephonyManager,
3366                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
3367                         true));
3368 
3369         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3370                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3371                         TelephonyManager.DATA_ENABLED_REASON_THERMAL));
3372         assertTrue(isDataEnabledForReason);
3373 
3374         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3375                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3376         assertTrue(isDataConnectionAvailable);
3377     }
3378 
3379     @Test
testPolicyDataEnable()3380     public void testPolicyDataEnable() {
3381         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3382             return;
3383         }
3384 
3385         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3386                 mTelephonyManager,
3387                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_POLICY,
3388                         false));
3389 
3390         boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3391                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3392                         TelephonyManager.DATA_ENABLED_REASON_POLICY));
3393         assertFalse(isDataEnabledForReason);
3394 
3395         boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3396                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3397         assertFalse(isDataConnectionAvailable);
3398 
3399         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3400                 mTelephonyManager,
3401                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_POLICY,
3402                         true));
3403 
3404         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3405                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3406                         TelephonyManager.DATA_ENABLED_REASON_POLICY));
3407         assertTrue(isDataEnabledForReason);
3408 
3409         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3410                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3411         assertTrue(isDataConnectionAvailable);
3412     }
3413 
3414     @Test
testCarrierDataEnable()3415     public void testCarrierDataEnable() {
3416         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3417             return;
3418         }
3419 
3420         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3421                 mTelephonyManager,
3422                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
3423                         false));
3424 
3425         waitForMs(500);
3426         boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3427                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3428                         TelephonyManager.DATA_ENABLED_REASON_CARRIER));
3429         assertFalse(isDataEnabledForReason);
3430 
3431         boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3432                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3433         assertFalse(isDataConnectionAvailable);
3434 
3435         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3436                 mTelephonyManager,
3437                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
3438                         true));
3439 
3440         waitForMs(500);
3441         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3442                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3443                         TelephonyManager.DATA_ENABLED_REASON_CARRIER));
3444         assertTrue(isDataEnabledForReason);
3445         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3446                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3447         assertTrue(isDataConnectionAvailable);
3448     }
3449 
3450     @Test
testUserDataEnable()3451     public void testUserDataEnable() {
3452         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3453             return;
3454         }
3455 
3456         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3457                 mTelephonyManager,
3458                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER,
3459                         false));
3460 
3461         waitForMs(500);
3462         boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3463                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3464                         TelephonyManager.DATA_ENABLED_REASON_USER));
3465         assertFalse(isDataEnabledForReason);
3466 
3467         boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3468                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3469         assertFalse(isDataConnectionAvailable);
3470 
3471         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3472                 mTelephonyManager,
3473                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER,
3474                         true));
3475 
3476         waitForMs(500);
3477         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
3478                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
3479                         TelephonyManager.DATA_ENABLED_REASON_USER));
3480         assertTrue(isDataEnabledForReason);
3481         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
3482                 mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
3483         assertTrue(isDataConnectionAvailable);
3484     }
3485 
3486     @Test
testDataDuringVoiceCallPolicy()3487     public void testDataDuringVoiceCallPolicy() {
3488         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3489             return;
3490         }
3491 
3492         ShellIdentityUtils.ShellPermissionMethodHelper<Boolean, TelephonyManager> getPolicyHelper =
3493                 (tm) -> tm.isMobileDataPolicyEnabled(
3494                         TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL);
3495 
3496         boolean allowDataDuringVoiceCall = ShellIdentityUtils.invokeMethodWithShellPermissions(
3497                 mTelephonyManager, getPolicyHelper);
3498 
3499         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3500                 mTelephonyManager, (tm) -> tm.setMobileDataPolicyEnabled(
3501                         TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL,
3502                         !allowDataDuringVoiceCall));
3503 
3504         assertNotEquals(allowDataDuringVoiceCall,
3505                 ShellIdentityUtils.invokeMethodWithShellPermissions(
3506                         mTelephonyManager, getPolicyHelper));
3507 
3508         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3509                 mTelephonyManager, (tm) -> tm.setMobileDataPolicyEnabled(
3510                         TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL,
3511                         allowDataDuringVoiceCall));
3512 
3513         assertEquals(allowDataDuringVoiceCall,
3514                 ShellIdentityUtils.invokeMethodWithShellPermissions(
3515                         mTelephonyManager, getPolicyHelper));
3516     }
3517 
3518     @Test
testAlwaysAllowMmsDataPolicy()3519     public void testAlwaysAllowMmsDataPolicy() {
3520         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3521             return;
3522         }
3523 
3524         ShellIdentityUtils.ShellPermissionMethodHelper<Boolean, TelephonyManager> getPolicyHelper =
3525                 (tm) -> tm.isMobileDataPolicyEnabled(
3526                         TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED);
3527 
3528         boolean mmsAlwaysAllowed = ShellIdentityUtils.invokeMethodWithShellPermissions(
3529                 mTelephonyManager, getPolicyHelper);
3530 
3531         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3532                 mTelephonyManager, (tm) -> tm.setMobileDataPolicyEnabled(
3533                         TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED,
3534                         !mmsAlwaysAllowed));
3535 
3536         assertNotEquals(mmsAlwaysAllowed,
3537                 ShellIdentityUtils.invokeMethodWithShellPermissions(
3538                         mTelephonyManager, getPolicyHelper));
3539 
3540         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3541                 mTelephonyManager, (tm) -> tm.setMobileDataPolicyEnabled(
3542                         TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED,
3543                         mmsAlwaysAllowed));
3544 
3545         assertEquals(mmsAlwaysAllowed,
3546                 ShellIdentityUtils.invokeMethodWithShellPermissions(
3547                         mTelephonyManager, getPolicyHelper));
3548     }
3549 
3550     @Test
testGetCdmaEnhancedRoamingIndicatorDisplayNumber()3551     public void testGetCdmaEnhancedRoamingIndicatorDisplayNumber() {
3552         int index = mTelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber();
3553         int phoneType = mTelephonyManager.getPhoneType();
3554         if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
3555             assertTrue(index >= 0 && index <= 255);
3556         } else {
3557             assertEquals(-1, index);
3558         }
3559     }
3560 
disableNrDualConnectivity()3561     private void disableNrDualConnectivity() {
3562         if (!ShellIdentityUtils.invokeMethodWithShellPermissions(
3563                 mTelephonyManager, (tm) -> tm.isRadioInterfaceCapabilitySupported(
3564                         TelephonyManager
3565                                 .CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE))) {
3566             return;
3567         }
3568 
3569         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3570                 mTelephonyManager,
3571                 (tm) -> tm.setNrDualConnectivityState(
3572                         TelephonyManager.NR_DUAL_CONNECTIVITY_DISABLE));
3573 
3574         boolean isNrDualConnectivityEnabled =
3575                 ShellIdentityUtils.invokeMethodWithShellPermissions(
3576                         mTelephonyManager, (tm) -> tm.isNrDualConnectivityEnabled());
3577         // Only verify the result for supported devices on IRadio 1.6+
3578         if (mRadioVersion >= RADIO_HAL_VERSION_1_6) {
3579             assertFalse(isNrDualConnectivityEnabled);
3580         }
3581     }
3582 
3583     @Test
testNrDualConnectivityEnable()3584     public void testNrDualConnectivityEnable() {
3585         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3586             return;
3587         }
3588 
3589         if (!ShellIdentityUtils.invokeMethodWithShellPermissions(
3590                 mTelephonyManager, (tm) -> tm.isRadioInterfaceCapabilitySupported(
3591                         TelephonyManager
3592                                 .CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE))) {
3593             return;
3594         }
3595 
3596         boolean isInitiallyEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(
3597                 mTelephonyManager, (tm) -> tm.isNrDualConnectivityEnabled());
3598         boolean isNrDualConnectivityEnabled;
3599         if (isInitiallyEnabled) {
3600             disableNrDualConnectivity();
3601         }
3602 
3603         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
3604                 mTelephonyManager,
3605                 (tm) -> tm.setNrDualConnectivityState(
3606                         TelephonyManager.NR_DUAL_CONNECTIVITY_ENABLE));
3607         isNrDualConnectivityEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(
3608                 mTelephonyManager, (tm) -> tm.isNrDualConnectivityEnabled());
3609         // Only verify the result for supported devices on IRadio 1.6+
3610         if (mRadioVersion >= RADIO_HAL_VERSION_1_6) {
3611             assertTrue(isNrDualConnectivityEnabled);
3612         }
3613 
3614         if (!isInitiallyEnabled) {
3615             disableNrDualConnectivity();
3616         }
3617     }
3618 
3619     @Test
testCdmaRoamingMode()3620     public void testCdmaRoamingMode() {
3621         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
3622                 || mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) {
3623             return;
3624         }
3625 
3626         // Save state
3627         int cdmaRoamingMode = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3628                 TelephonyManager::getCdmaRoamingMode);
3629 
3630         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3631                 tm -> tm.setCdmaRoamingMode(TelephonyManager.CDMA_ROAMING_MODE_HOME));
3632         assertEquals(TelephonyManager.CDMA_ROAMING_MODE_HOME,
3633                 (int) ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3634                         TelephonyManager::getCdmaRoamingMode));
3635         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3636                 tm -> tm.setCdmaRoamingMode(TelephonyManager.CDMA_ROAMING_MODE_AFFILIATED));
3637         assertEquals(TelephonyManager.CDMA_ROAMING_MODE_AFFILIATED,
3638                 (int) ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3639                         TelephonyManager::getCdmaRoamingMode));
3640 
3641         // Reset state
3642         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3643                 tm -> tm.setCdmaRoamingMode(cdmaRoamingMode));
3644     }
3645 
3646     @Test
testCdmaSubscriptionMode()3647     public void testCdmaSubscriptionMode() {
3648         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
3649                 || mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) {
3650             return;
3651         }
3652 
3653         // Save state
3654         int cdmaSubscriptionMode = ShellIdentityUtils.invokeMethodWithShellPermissions(
3655                 mTelephonyManager, TelephonyManager::getCdmaSubscriptionMode);
3656 
3657         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3658                 tm -> tm.setCdmaSubscriptionMode(TelephonyManager.CDMA_SUBSCRIPTION_NV));
3659         assertEquals(TelephonyManager.CDMA_SUBSCRIPTION_NV,
3660                 (int) ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3661                         TelephonyManager::getCdmaSubscriptionMode));
3662         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3663                 tm -> tm.setCdmaSubscriptionMode(TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM));
3664         assertEquals(TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM,
3665                 (int) ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
3666                         TelephonyManager::getCdmaSubscriptionMode));
3667 
3668         // Reset state
3669         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3670                 tm -> tm.setCdmaSubscriptionMode(cdmaSubscriptionMode));
3671     }
3672 
3673     @Test
testPinResult()3674     public void testPinResult() {
3675         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3676             return;
3677         }
3678 
3679         final String pin = "fake_pin";
3680         final String puk = "fake_puk";
3681         final String newPin = "fake_new_pin";
3682 
3683         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(
3684                 mTelephonyManager, TelephonyManager::isIccLockEnabled);
3685         PinResult result = ShellIdentityUtils.invokeMethodWithShellPermissions(
3686                 mTelephonyManager, (tm) -> tm.setIccLockEnabled(!isEnabled, pin));
3687         assertTrue(result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT
3688                 || result.getResult() == PinResult.PIN_RESULT_TYPE_FAILURE);
3689         assertTrue(result.getAttemptsRemaining() >= -1);
3690         assertEquals(isEnabled, ShellIdentityUtils.invokeMethodWithShellPermissions(
3691                 mTelephonyManager, TelephonyManager::isIccLockEnabled));
3692 
3693         result = ShellIdentityUtils.invokeMethodWithShellPermissions(
3694                 mTelephonyManager, (tm) -> tm.changeIccLockPin(pin, newPin));
3695         assertTrue(result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT
3696                 || result.getResult() == PinResult.PIN_RESULT_TYPE_FAILURE);
3697         assertTrue(result.getAttemptsRemaining() >= -1);
3698 
3699         result = ShellIdentityUtils.invokeMethodWithShellPermissions(
3700                 mTelephonyManager, (tm) -> tm.supplyIccLockPin(pin));
3701         assertTrue(result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT
3702                 || result.getResult() == PinResult.PIN_RESULT_TYPE_FAILURE);
3703         assertTrue(result.getAttemptsRemaining() >= -1);
3704 
3705         result = ShellIdentityUtils.invokeMethodWithShellPermissions(
3706                 mTelephonyManager, (tm) -> tm.supplyIccLockPuk(puk, pin));
3707         assertTrue(result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT
3708                 || result.getResult() == PinResult.PIN_RESULT_TYPE_FAILURE);
3709         assertTrue(result.getAttemptsRemaining() >= -1);
3710     }
3711 
3712     @Test
testSetSignalStrengthUpdateRequest_nullRequest()3713     public void testSetSignalStrengthUpdateRequest_nullRequest() {
3714         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3715             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3716             return;
3717         }
3718 
3719         // Verify NPE throws if set request with null object
3720         try {
3721             mTelephonyManager.setSignalStrengthUpdateRequest(null);
3722             fail("NullPointerException expected when setSignalStrengthUpdateRequest with null");
3723         } catch (NullPointerException expected) {
3724         }
3725     }
3726 
3727     @Test
testSetSignalStrengthUpdateRequest_noPermission()3728     public void testSetSignalStrengthUpdateRequest_noPermission() {
3729         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3730             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3731             return;
3732         }
3733 
3734         final SignalStrengthUpdateRequest normalRequest =
3735                 new SignalStrengthUpdateRequest.Builder()
3736                         .setSignalThresholdInfos(List.of(
3737                                 new SignalThresholdInfo.Builder()
3738                                         .setRadioAccessNetworkType(
3739                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3740                                         .setSignalMeasurementType(
3741                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3742                                         .setThresholds(new int[]{-113, -103, -97, -51})
3743                                         .build()))
3744                         .setReportingRequestedWhileIdle(true)
3745                         .build();
3746 
3747         // Verify SE throws for apps without carrier privilege or MODIFY_PHONE_STATE permission
3748         try {
3749             mTelephonyManager.setSignalStrengthUpdateRequest(normalRequest);
3750             fail("SecurityException expected when setSignalStrengthUpdateRequest without "
3751                     + "carrier privilege or MODIFY_PHONE_STATE permission");
3752         } catch (SecurityException expected) {
3753         }
3754     }
3755 
3756     @Test
testSetSignalStrengthUpdateRequest_systemThresholdReportingRequestedWhileIdle()3757     public void testSetSignalStrengthUpdateRequest_systemThresholdReportingRequestedWhileIdle() {
3758         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3759             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3760             return;
3761         }
3762 
3763         // Verify SE throws for app when set systemThresholdReportingRequestedWhileIdle to true
3764         SignalStrengthUpdateRequest requestWithSystemThresholdReportingRequestedWhileIdle =
3765                 new SignalStrengthUpdateRequest.Builder()
3766                         .setSignalThresholdInfos(List.of(
3767                                 new SignalThresholdInfo.Builder()
3768                                         .setRadioAccessNetworkType(
3769                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3770                                         .setSignalMeasurementType(
3771                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3772                                         .setThresholds(new int[]{-113, -103, -97, -51})
3773                                         .build()))
3774                         .setReportingRequestedWhileIdle(true)
3775                         //allowed for system caller only
3776                         .setSystemThresholdReportingRequestedWhileIdle(true)
3777                         .build();
3778         try {
3779             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3780                     (tm) -> tm.setSignalStrengthUpdateRequest(
3781                             requestWithSystemThresholdReportingRequestedWhileIdle));
3782             fail("IllegalArgumentException expected when set "
3783                     + "systemThresholdReportingRequestedWhileIdle");
3784         } catch (IllegalArgumentException expected) {
3785         }
3786     }
3787 
3788     @Test
testSetSignalStrengthUpdateRequest_systeresisDbSet()3789     public void testSetSignalStrengthUpdateRequest_systeresisDbSet() {
3790         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3791             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3792             return;
3793         }
3794 
3795         // Verify SE throws for app when set hysteresisDb in the SignalThresholdInfo
3796         SignalStrengthUpdateRequest requestWithHysteresisDbSet =
3797                 new SignalStrengthUpdateRequest.Builder()
3798                         .setSignalThresholdInfos(List.of(
3799                                 new SignalThresholdInfo.Builder()
3800                                         .setRadioAccessNetworkType(
3801                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3802                                         .setSignalMeasurementType(
3803                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3804                                         .setThresholds(new int[]{-113, -103, -97, -51})
3805                                         .setHysteresisDb(10) //allowed for system caller only
3806                                         .build()))
3807                         .setReportingRequestedWhileIdle(true)
3808                         .build();
3809         try {
3810             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3811                     (tm) -> tm.setSignalStrengthUpdateRequest(requestWithHysteresisDbSet));
3812             fail("IllegalArgumentException expected when set hysteresisDb in SignalThresholdInfo "
3813                     + "to true");
3814         } catch (IllegalArgumentException expected) {
3815         }
3816     }
3817 
3818     @Test
testSetSignalStrengthUpdateRequest_systeresisMsSet()3819     public void testSetSignalStrengthUpdateRequest_systeresisMsSet() {
3820         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3821             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3822             return;
3823         }
3824 
3825         // Verify SE throws for app when set hysteresisMs in the SignalThresholdInfo
3826         SignalStrengthUpdateRequest requestWithHysteresisMsSet =
3827                 new SignalStrengthUpdateRequest.Builder()
3828                         .setSignalThresholdInfos(List.of(
3829                                 new SignalThresholdInfo.Builder()
3830                                         .setRadioAccessNetworkType(
3831                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3832                                         .setSignalMeasurementType(
3833                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3834                                         .setThresholds(new int[]{-113, -103, -97, -51})
3835                                         .setHysteresisMs(1000) //allowed for system caller only
3836                                         .build()))
3837                         .setReportingRequestedWhileIdle(true)
3838                         .build();
3839         try {
3840             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3841                     (tm) -> tm.setSignalStrengthUpdateRequest(requestWithHysteresisMsSet));
3842             fail("IllegalArgumentException expected when set hysteresisMs in SignalThresholdInfo "
3843                     + "to true");
3844         } catch (IllegalArgumentException expected) {
3845         }
3846     }
3847 
3848     @Test
testSetSignalStrengthUpdateRequest_isEnabledSet()3849     public void testSetSignalStrengthUpdateRequest_isEnabledSet() {
3850         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3851             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3852             return;
3853         }
3854 
3855         // Verify SE throws for app when set isEnabled in the SignalThresholdInfo
3856         SignalStrengthUpdateRequest requestWithThresholdIsEnabledSet =
3857                 new SignalStrengthUpdateRequest.Builder()
3858                         .setSignalThresholdInfos(List.of(
3859                                 new SignalThresholdInfo.Builder()
3860                                         .setRadioAccessNetworkType(
3861                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3862                                         .setSignalMeasurementType(
3863                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3864                                         .setThresholds(new int[]{-113, -103, -97})
3865                                         .setIsEnabled(true) //allowed for system caller only
3866                                         .build()))
3867                         .setReportingRequestedWhileIdle(true)
3868                         .build();
3869         try {
3870             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3871                     (tm) -> tm.setSignalStrengthUpdateRequest(requestWithThresholdIsEnabledSet));
3872             fail("IllegalArgumentException expected when set isEnabled in SignalThresholdInfo "
3873                     + "with true");
3874         } catch (IllegalArgumentException expected) {
3875         }
3876     }
3877 
3878     @Test
testSetSignalStrengthUpdateRequest_tooShortThresholds()3879     public void testSetSignalStrengthUpdateRequest_tooShortThresholds() {
3880         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3881             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3882             return;
3883         }
3884 
3885         // verify SE throws if app set too short thresholds
3886         SignalStrengthUpdateRequest requestWithTooShortThresholds =
3887                 new SignalStrengthUpdateRequest.Builder()
3888                         .setSignalThresholdInfos(List.of(
3889                                 new SignalThresholdInfo.Builder()
3890                                         .setRadioAccessNetworkType(
3891                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3892                                         .setSignalMeasurementType(
3893                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3894                                         .setThresholds(new int[]{}, true /*isSystem*/)
3895                                         .build()))
3896                         .setReportingRequestedWhileIdle(true)
3897                         .build();
3898         try {
3899             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3900                     (tm) -> tm.setSignalStrengthUpdateRequest(requestWithTooShortThresholds));
3901             fail("IllegalArgumentException expected when set thresholds that is too short");
3902         } catch (IllegalArgumentException expected) {
3903         }
3904     }
3905 
3906     @Test
testSetSignalStrengthUpdateRequest_tooLongThresholds()3907     public void testSetSignalStrengthUpdateRequest_tooLongThresholds() {
3908         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3909             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3910             return;
3911         }
3912 
3913         // verify SE throws if app set too long thresholds
3914         SignalStrengthUpdateRequest requestWithTooLongThresholds =
3915                 new SignalStrengthUpdateRequest.Builder()
3916                         .setSignalThresholdInfos(List.of(
3917                                 new SignalThresholdInfo.Builder()
3918                                         .setRadioAccessNetworkType(
3919                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3920                                         .setSignalMeasurementType(
3921                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3922                                         .setThresholds(new int[]{-113, -103, -97, -61, -51},
3923                                             true /*isSystem*/)
3924                                         .build()))
3925                         .setReportingRequestedWhileIdle(true)
3926                         .build();
3927         try {
3928             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3929                     (tm) -> tm.setSignalStrengthUpdateRequest(requestWithTooLongThresholds));
3930             fail("IllegalArgumentException expected when set thresholds that is too long");
3931         } catch (IllegalArgumentException expected) {
3932         }
3933     }
3934 
3935     @Test
testSetSignalStrengthUpdateRequest_duplicatedRequest()3936     public void testSetSignalStrengthUpdateRequest_duplicatedRequest() {
3937         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3938             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3939             return;
3940         }
3941 
3942         final SignalStrengthUpdateRequest normalRequest =
3943                 new SignalStrengthUpdateRequest.Builder()
3944                         .setSignalThresholdInfos(List.of(
3945                                 new SignalThresholdInfo.Builder()
3946                                         .setRadioAccessNetworkType(
3947                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3948                                         .setSignalMeasurementType(
3949                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
3950                                         .setThresholds(new int[]{-113, -103, -97, -51})
3951                                         .build()))
3952                         .setReportingRequestedWhileIdle(true)
3953                         .build();
3954 
3955         // Verify IllegalStateException should throw when set the same request twice
3956         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3957                 (tm) -> tm.setSignalStrengthUpdateRequest(normalRequest));
3958         try {
3959             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3960                     (tm) -> tm.setSignalStrengthUpdateRequest(normalRequest));
3961             fail("IllegalStateException expected when setSignalStrengthUpdateRequest twice with "
3962                     + "same request object");
3963         } catch (IllegalStateException expected) {
3964         } finally {
3965             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
3966                     (tm) -> tm.clearSignalStrengthUpdateRequest(normalRequest));
3967         }
3968     }
3969 
3970     @Test
testClearSignalStrengthUpdateRequest_nullRequest()3971     public void testClearSignalStrengthUpdateRequest_nullRequest() {
3972         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3973             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3974             return;
3975         }
3976 
3977         // Verify NPE should throw if clear request with null object
3978         try {
3979             mTelephonyManager.clearSignalStrengthUpdateRequest(null);
3980             fail("NullPointerException expected when clearSignalStrengthUpdateRequest with null");
3981         } catch (NullPointerException expected) {
3982         }
3983     }
3984 
3985     @Test
testClearSignalStrengthUpdateRequest_noPermission()3986     public void testClearSignalStrengthUpdateRequest_noPermission() {
3987         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
3988             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
3989             return;
3990         }
3991 
3992         final SignalStrengthUpdateRequest normalRequest =
3993                 new SignalStrengthUpdateRequest.Builder()
3994                         .setSignalThresholdInfos(List.of(
3995                                 new SignalThresholdInfo.Builder()
3996                                         .setRadioAccessNetworkType(
3997                                                 AccessNetworkConstants.AccessNetworkType.GERAN)
3998                                         .setSignalMeasurementType(
3999                                                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
4000                                         .setThresholds(new int[]{-113, -103, -97, -51})
4001                                         .build()))
4002                         .setReportingRequestedWhileIdle(true)
4003                         .build();
4004 
4005         // Verify SE throws for apps without carrier privilege or MODIFY_PHONE_STATE permission
4006         try {
4007             mTelephonyManager.clearSignalStrengthUpdateRequest(normalRequest);
4008             fail("SecurityException expected when clearSignalStrengthUpdateRequest without "
4009                     + "carrier privilege or MODIFY_PHONE_STATE permission");
4010         } catch (SecurityException expected) {
4011         }
4012     }
4013 
4014     @Test
testClearSignalStrengthUpdateRequest_clearWithNoSet()4015     public void testClearSignalStrengthUpdateRequest_clearWithNoSet() {
4016         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
4017             Log.d(TAG, "skipping test on device without FEATURE_TELEPHONY present");
4018             return;
4019         }
4020 
4021         SignalStrengthUpdateRequest requestNeverSetBefore = new SignalStrengthUpdateRequest
4022                 .Builder()
4023                 .setSignalThresholdInfos(List.of(new SignalThresholdInfo.Builder()
4024                         .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
4025                         .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
4026                         .setThresholds(new int[]{-113, -103, -97, -51})
4027                         .build()))
4028                 .setReportingRequestedWhileIdle(true)
4029                 .build();
4030 
4031         // Verify clearSignalStrengthUpdateRequest is no-op when clear request that was not set
4032         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
4033                 (tm) -> tm.clearSignalStrengthUpdateRequest(requestNeverSetBefore));
4034     }
4035 
4036     @Test
testSendThermalMitigationRequest()4037     public void testSendThermalMitigationRequest() throws Exception {
4038         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
4039             return;
4040         }
4041 
4042         StringBuilder cmdBuilder = new StringBuilder();
4043         cmdBuilder.append(THERMAL_MITIGATION_COMMAND_BASE).append(ALLOW_PACKAGE_SUBCOMMAND)
4044                 .append(TELEPHONY_CTS_PACKAGE);
4045         TelephonyUtils.executeShellCommand(InstrumentationRegistry.getInstrumentation(),
4046                 cmdBuilder.toString());
4047 
4048         long arbitraryCompletionWindowSecs = 1L;
4049 
4050         boolean isDataThrottlingSupported = ShellIdentityUtils.invokeMethodWithShellPermissions(
4051                 mTelephonyManager, (tm) -> tm.isRadioInterfaceCapabilitySupported(
4052                         TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING));
4053 
4054         int thermalMitigationResult = -1;
4055         if (isDataThrottlingSupported) {
4056             // Test a proper data throttling thermal mitigation request.
4057             thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
4058                 mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
4059                         new ThermalMitigationRequest.Builder()
4060                                 .setThermalMitigationAction(ThermalMitigationRequest
4061                                         .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
4062                                 .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
4063                                         .setDataThrottlingAction(DataThrottlingRequest
4064                                                 .DATA_THROTTLING_ACTION_THROTTLE_SECONDARY_CARRIER)
4065                                         .setCompletionDurationMillis(arbitraryCompletionWindowSecs)
4066                                         .build())
4067                                 .build()));
4068 
4069             assertEquals(thermalMitigationResult,
4070                     TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS);
4071         }
4072         // Test negative completionDurationSecs is an invalid parameter.
4073         try {
4074             thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
4075                     mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
4076                             new ThermalMitigationRequest.Builder()
4077                                     .setThermalMitigationAction(ThermalMitigationRequest
4078                                             .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
4079                                     .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
4080                                             .setDataThrottlingAction(DataThrottlingRequest
4081                                                     .DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER
4082                                             )
4083                                             .setCompletionDurationMillis(-1)
4084                                             .build())
4085                                     .build()));
4086         } catch (IllegalArgumentException e) {
4087         }
4088 
4089         // Test non-zero completionDurationSecs is an invalid parameter for data throttling hold.
4090         try {
4091             thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
4092                     mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
4093                             new ThermalMitigationRequest.Builder()
4094                                     .setThermalMitigationAction(ThermalMitigationRequest
4095                                             .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
4096                                     .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
4097                                             .setDataThrottlingAction(
4098                                                     DataThrottlingRequest
4099                                                             .DATA_THROTTLING_ACTION_HOLD)
4100                                             .setCompletionDurationMillis(
4101                                                     arbitraryCompletionWindowSecs)
4102                                             .build())
4103                                     .build()));
4104         } catch (IllegalArgumentException e) {
4105         }
4106 
4107         // Test null DataThrottlingParams is an invalid parameter for data throttling request.
4108         try {
4109             thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
4110                     mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
4111                             new ThermalMitigationRequest.Builder()
4112                                     .setThermalMitigationAction(ThermalMitigationRequest
4113                                             .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
4114                                     .build()));
4115         } catch (IllegalArgumentException e) {
4116         }
4117 
4118         // Test non-null DataThrottlingParams is an invalid parameter for voice only request.
4119         try {
4120             thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
4121                     mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
4122                             new ThermalMitigationRequest.Builder()
4123                                     .setThermalMitigationAction(
4124                                             ThermalMitigationRequest
4125                                                     .THERMAL_MITIGATION_ACTION_VOICE_ONLY)
4126                                     .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
4127                                             .setDataThrottlingAction(
4128                                                     DataThrottlingRequest
4129                                                     .DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER
4130                                             )
4131                                             .setCompletionDurationMillis(-1)
4132                                             .build())
4133                             .build()));
4134         } catch (IllegalArgumentException e) {
4135         }
4136 
4137         // Test non-null DataThrottlingParams is an invalid parameter for radio off request.
4138         try {
4139             thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
4140                     mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
4141                             new ThermalMitigationRequest.Builder()
4142                                     .setThermalMitigationAction(
4143                                             ThermalMitigationRequest
4144                                                     .THERMAL_MITIGATION_ACTION_RADIO_OFF)
4145                                     .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
4146                                             .setDataThrottlingAction(DataThrottlingRequest
4147                                                     .DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER
4148                                             )
4149                                             .setCompletionDurationMillis(-1)
4150                                             .build())
4151                             .build()));
4152         } catch (IllegalArgumentException e) {
4153         }
4154     }
4155 
4156     @Test
testIsRadioInterfaceCapabilitySupported()4157     public void testIsRadioInterfaceCapabilitySupported() {
4158         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) return;
4159 
4160         assertFalse(mTelephonyManager.isRadioInterfaceCapabilitySupported("empty"));
4161         assertFalse(mTelephonyManager.isRadioInterfaceCapabilitySupported(null));
4162         assertFalse(mTelephonyManager.isRadioInterfaceCapabilitySupported(""));
4163     }
4164 
4165     @Test
testGetAllCellInfo()4166     public void testGetAllCellInfo() {
4167         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) return;
4168 
4169         // For IRadio <1.5, just verify that calling the method doesn't throw an error.
4170         if (mRadioVersion < RADIO_HAL_VERSION_1_5) {
4171             mTelephonyManager.getAllCellInfo();
4172             return;
4173         }
4174 
4175         for (CellInfo cellInfo : mTelephonyManager.getAllCellInfo()) {
4176             CellIdentity cellIdentity = cellInfo.getCellIdentity();
4177             int[] bands;
4178             if (cellIdentity instanceof CellIdentityLte) {
4179                 bands = ((CellIdentityLte) cellIdentity).getBands();
4180                 for (int band : bands) {
4181                     assertTrue(band >= AccessNetworkConstants.EutranBand.BAND_1
4182                             && band <= AccessNetworkConstants.EutranBand.BAND_88);
4183                 }
4184             } else if (cellIdentity instanceof CellIdentityNr) {
4185                 bands = ((CellIdentityNr) cellIdentity).getBands();
4186                 for (int band : bands) {
4187                     assertTrue((band >= AccessNetworkConstants.NgranBands.BAND_1
4188                             && band <= AccessNetworkConstants.NgranBands.BAND_95)
4189                             || (band >= AccessNetworkConstants.NgranBands.BAND_257
4190                             && band <= AccessNetworkConstants.NgranBands.BAND_261));
4191                 }
4192             } else {
4193                 continue;
4194             }
4195             assertTrue(bands.length > 0);
4196         }
4197     }
4198 
4199     /**
4200      * Validate Emergency Number address that only contains the dialable character.
4201      *
4202      * @param address Emergency number address to validate
4203      * @return {@code true} if the address is valid; {@code false} otherwise.
4204      */
validateEmergencyNumberAddress(String address)4205     private static boolean validateEmergencyNumberAddress(String address) {
4206         if (address == null) {
4207             return false;
4208         }
4209         for (char c : address.toCharArray()) {
4210             if (!isDialable(c)) {
4211                 return false;
4212             }
4213         }
4214         return true;
4215     }
4216 
4217     /**
4218      * Validate Emergency Number country Iso
4219      *
4220      * @param countryIso Emergency number country iso to validate
4221      * @return {@code true} if the country iso is valid; {@code false} otherwise.
4222      */
validateEmergencyNumberCountryIso(String countryIso)4223     private static boolean validateEmergencyNumberCountryIso(String countryIso) {
4224         if (countryIso == null) {
4225             return false;
4226         }
4227         int length = countryIso.length();
4228         return length >= 0 && length <= 2;
4229     }
4230 
4231     /**
4232      * Validate Emergency Number MNC
4233      *
4234      * @param mnc Emergency number MNC to validate
4235      * @return {@code true} if the MNC is valid; {@code false} otherwise.
4236      */
validateEmergencyNumberMnc(String mnc)4237     private static boolean validateEmergencyNumberMnc(String mnc) {
4238         if (mnc == null) {
4239             return false;
4240         }
4241         int length = mnc.length();
4242         return length >= 0 && length <= 3;
4243     }
4244 
4245     /**
4246      * Validate Emergency service category list
4247      *
4248      * @param categories Emergency service category list to validate
4249      * @return {@code true} if the category list is valid; {@code false} otherwise.
4250      */
validateEmergencyServiceCategoryList(List<Integer> categories)4251     private static boolean validateEmergencyServiceCategoryList(List<Integer> categories) {
4252         if (categories == null) {
4253             return false;
4254         }
4255         if (categories.contains(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED)) {
4256             return categories.size() == 1;
4257         }
4258         for (int category : categories) {
4259             if (!EMERGENCY_SERVICE_CATEGORY_SET.contains(category)) {
4260                 return false;
4261             }
4262         }
4263         return true;
4264     }
4265 
4266     /**
4267      * Validate Emergency number source list
4268      *
4269      * @param categories Emergency number source list to validate
4270      * @return {@code true} if the source list is valid; {@code false} otherwise.
4271      */
validateEmergencyNumberSourceList(List<Integer> sources)4272     private static boolean validateEmergencyNumberSourceList(List<Integer> sources) {
4273         if (sources == null) {
4274             return false;
4275         }
4276         for (int source : sources) {
4277             if (!EMERGENCY_NUMBER_SOURCE_SET.contains(source)) {
4278                 return false;
4279             }
4280         }
4281         return true;
4282     }
4283 
4284     /**
4285      * Validate Emergency call routing.
4286      *
4287      * @param routing Emergency call routing to validate
4288      * @return {@code true} if the emergency call routing is valid; {@code false} otherwise.
4289      */
validateEmergencyCallRouting(int routing)4290     private static boolean validateEmergencyCallRouting(int routing) {
4291         return routing >= EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN
4292                 && routing <= (EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY
4293                 | EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
4294     }
4295 
4296     /**
4297      * Valid the emergency number should be at least from a valid source.
4298      *
4299      * @param emergencyNumber Emergency number to verify
4300      * @return {@code true} if the emergency number is from any source; {@code false} otherwise.
4301      */
validateEmergencyNumberFromAnySource(EmergencyNumber emergencyNumber)4302     private static boolean validateEmergencyNumberFromAnySource(EmergencyNumber emergencyNumber) {
4303         boolean isFromAnySource = false;
4304         for (int possibleSourceValue = EMERGENCY_NUMBER_SOURCE_RIL_ECCLIST;
4305                 possibleSourceValue <= (EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
4306                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM
4307                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE
4308                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
4309                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT);
4310                 possibleSourceValue++) {
4311             if (emergencyNumber.isFromSources(possibleSourceValue)) {
4312                 isFromAnySource = true;
4313                 break;
4314             }
4315         }
4316         return isFromAnySource;
4317     }
4318 
4319     /**
4320      * Valid the emergency number should be at least in a valid category.
4321      *
4322      * @param emergencyNumber Emergency number to verify
4323      * @return {@code true} if it is in any category; {@code false} otherwise.
4324      */
validateEmergencyNumberInAnyCategory(EmergencyNumber emergencyNumber)4325     private static boolean validateEmergencyNumberInAnyCategory(EmergencyNumber emergencyNumber) {
4326         boolean isInAnyCategory = false;
4327         for (int possibleCategoryValue = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
4328                 possibleCategoryValue <= (EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
4329                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
4330                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE
4331                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD
4332                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE
4333                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC
4334                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC);
4335                 possibleCategoryValue++) {
4336             if (emergencyNumber.isInEmergencyServiceCategories(possibleCategoryValue)) {
4337                 isInAnyCategory = true;
4338                 break;
4339             }
4340         }
4341         return isInAnyCategory;
4342     }
4343 
validateEmergencyNumberCompareTo( List<EmergencyNumber> emergencyNumberList)4344     private static boolean validateEmergencyNumberCompareTo(
4345             List<EmergencyNumber> emergencyNumberList) {
4346         if (emergencyNumberList == null) {
4347             return false;
4348         }
4349         if (emergencyNumberList.size() > 0) {
4350             EmergencyNumber emergencyNumber = emergencyNumberList.get(0);
4351             if (emergencyNumber.compareTo(emergencyNumber) != 0) {
4352                 return false;
4353             }
4354         }
4355         return true;
4356     }
4357 
isDialable(char c)4358     private static boolean isDialable(char c) {
4359         return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N';
4360     }
4361 
getValidSlotIndex()4362     private int getValidSlotIndex() {
4363         return ShellIdentityUtils.invokeMethodWithShellPermissions(
4364                 mTelephonyManager, (tm) -> {
4365                     List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
4366                     Set<String> presentCards = Arrays.stream(mTelephonyManager.getUiccSlotsInfo())
4367                             .filter(Objects::nonNull)
4368                             .filter(UiccSlotInfo::getIsActive)
4369                             .map(UiccSlotInfo::getCardId)
4370                             .filter(Objects::nonNull)
4371                             // hack around getUiccSlotsInfo not stripping trailing F
4372                             .map(s -> s.endsWith("F") ? s.substring(0, s.length() - 1) : s)
4373                             .collect(Collectors.toSet());
4374                     int slotIndex = -1;
4375                     for (UiccCardInfo cardInfo : cardInfos) {
4376                         if (presentCards.contains(cardInfo.getIccId())
4377                                 || presentCards.contains(cardInfo.getEid())) {
4378                             slotIndex = cardInfo.getSlotIndex();
4379                             break;
4380                         }
4381                     }
4382                     if (slotIndex < 0) {
4383                         fail("Test must be run with SIM card inserted, presentCards = "
4384                                 + presentCards + "cardinfos = " + cardInfos);
4385                     }
4386                     return slotIndex;
4387                 });
4388     }
4389 
waitForMs(long ms)4390     public static void waitForMs(long ms) {
4391         try {
4392             Thread.sleep(ms);
4393         } catch (InterruptedException e) {
4394             Log.d(TAG, "InterruptedException while waiting: " + e);
4395         }
4396     }
4397 
4398     /**
4399      * Verify that the phone is supporting the action of setForbiddenPlmn.
4400      *
4401      * @return whether to proceed the test
4402      */
supportSetFplmn()4403     private boolean supportSetFplmn() {
4404         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
4405             return false;
4406         }
4407         return mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM;
4408     }
4409 
4410     /**
4411      * Verify that the phone is supporting the action of setForbiddenPlmn.
4412      *
4413      * @return whether to proceed the test
4414      */
test()4415     private boolean test() {
4416         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
4417             return false;
4418         }
4419         return mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM;
4420     }
4421 
makeRadioVersion(int major, int minor)4422     private static int makeRadioVersion(int major, int minor) {
4423         if (major < 0 || minor < 0) return 0;
4424         return major * 100 + minor;
4425     }
4426 
4427     private Executor mSimpleExecutor = new Executor() {
4428         @Override
4429         public void execute(Runnable r) {
4430             r.run();
4431         }
4432     };
4433 
4434     private static MockSignalStrengthsTelephonyCallback mMockSignalStrengthsTelephonyCallback;
4435 
4436     private class MockSignalStrengthsTelephonyCallback extends TelephonyCallback
4437             implements TelephonyCallback.SignalStrengthsListener {
4438         @Override
onSignalStrengthsChanged(SignalStrength signalStrength)4439         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
4440             if (!mOnSignalStrengthsChanged) {
4441                 synchronized (mLock) {
4442                     mOnSignalStrengthsChanged = true;
4443                     mLock.notify();
4444                 }
4445             }
4446         }
4447     }
4448 
4449     @Test
testRegisterTelephonyCallbackWithNonLooper()4450     public void testRegisterTelephonyCallbackWithNonLooper() throws Throwable {
4451         if (!InstrumentationRegistry.getContext().getPackageManager()
4452                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
4453             Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
4454             return;
4455         }
4456 
4457         mMockSignalStrengthsTelephonyCallback = new MockSignalStrengthsTelephonyCallback();
4458 
4459         // Test register, generates an mOnSignalStrengthsChanged event
4460         mTelephonyManager.registerTelephonyCallback(mSimpleExecutor,
4461                 mMockSignalStrengthsTelephonyCallback);
4462 
4463         synchronized (mLock) {
4464             if (!mOnSignalStrengthsChanged) {
4465                 mLock.wait(TOLERANCE);
4466             }
4467         }
4468         assertTrue("Test register, mOnSignalStrengthsChanged should be true.",
4469                 mOnSignalStrengthsChanged);
4470 
4471         // Test unregister
4472         mOnSignalStrengthsChanged = false;
4473         // unregister again, to make sure doing so does not call the listener
4474         mTelephonyManager.unregisterTelephonyCallback(mMockSignalStrengthsTelephonyCallback);
4475 
4476         assertFalse("Test unregister, mOnSignalStrengthsChanged should be false.",
4477                 mOnSignalStrengthsChanged);
4478     }
4479 
4480     private static MockCellInfoListener mMockCellInfoListener;
4481 
4482     private class MockCellInfoListener extends TelephonyCallback
4483             implements TelephonyCallback.CellInfoListener {
4484         @Override
onCellInfoChanged(@onNull List<CellInfo> cellInfo)4485         public void onCellInfoChanged(@NonNull List<CellInfo> cellInfo) {
4486             if (!mOnCellInfoChanged) {
4487                 synchronized (mLock) {
4488                     mOnCellInfoChanged = true;
4489                     mLock.notify();
4490                 }
4491             }
4492         }
4493     }
4494 
4495     @Test
testRegisterTelephonyCallback()4496     public void testRegisterTelephonyCallback() throws Throwable {
4497         if (!InstrumentationRegistry.getContext().getPackageManager()
4498                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
4499             Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
4500             return;
4501         }
4502 
4503         if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
4504             // TODO: temp workaround, need to adjust test to for CDMA
4505             return;
4506         }
4507         grantLocationPermissions();
4508 
4509         TestThread t = new TestThread(new Runnable() {
4510             public void run() {
4511                 Looper.prepare();
4512                 mMockCellInfoListener = new MockCellInfoListener();
4513                 synchronized (mLock) {
4514                     mLock.notify(); // listener is ready
4515                 }
4516 
4517                 Looper.loop();
4518             }
4519         });
4520 
4521         synchronized (mLock) {
4522             t.start();
4523             mLock.wait(TOLERANCE); // wait for listener
4524         }
4525 
4526         // Test register
4527         synchronized (mLock) {
4528             // .registerTelephonyCallback generates an onCellLocationChanged event
4529             mTelephonyManager.registerTelephonyCallback(mSimpleExecutor, mMockCellInfoListener);
4530             mLock.wait(TOLERANCE);
4531 
4532             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
4533                     mOnCellInfoChanged);
4534         }
4535 
4536         synchronized (mLock) {
4537             mOnCellInfoChanged = false;
4538 
4539             CellInfoResultsCallback resultsCallback = new CellInfoResultsCallback();
4540             mTelephonyManager.requestCellInfoUpdate(mSimpleExecutor, resultsCallback);
4541             mLock.wait(TOLERANCE);
4542 
4543             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
4544                     mOnCellInfoChanged);
4545         }
4546 
4547         // unregister the listener
4548         mTelephonyManager.unregisterTelephonyCallback(mMockCellInfoListener);
4549         Thread.sleep(TOLERANCE);
4550 
4551         // Test unregister
4552         synchronized (mLock) {
4553             mOnCellInfoChanged = false;
4554             // unregister again, to make sure doing so does not call the listener
4555             mTelephonyManager.unregisterTelephonyCallback(mMockCellInfoListener);
4556             CellLocation.requestLocationUpdate();
4557             mLock.wait(TOLERANCE);
4558 
4559             assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.",
4560                     mOnCellInfoChanged);
4561         }
4562     }
4563 
4564     private class CellInfoResultsCallback extends TelephonyManager.CellInfoCallback {
4565         public List<CellInfo> cellInfo;
4566 
4567         @Override
onCellInfo(List<CellInfo> cellInfo)4568         public synchronized void onCellInfo(List<CellInfo> cellInfo) {
4569             this.cellInfo = cellInfo;
4570             notifyAll();
4571         }
4572 
wait(int millis)4573         public synchronized void wait(int millis) throws InterruptedException {
4574             if (cellInfo == null) {
4575                 super.wait(millis);
4576             }
4577         }
4578     }
4579 
setAppOpsPermissionAllowed(boolean allowed, String op)4580     private void setAppOpsPermissionAllowed(boolean allowed, String op) {
4581         AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
4582         int mode = allowed ? AppOpsManager.MODE_ALLOWED : AppOpsManager.opToDefaultMode(op);
4583         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
4584                 appOpsManager, (appOps) -> appOps.setUidMode(op, Process.myUid(), mode));
4585     }
4586 
4587     /**
4588      * Verifies that {@link TelephonyManager#getNetworkSlicingConfiguration()} does not throw any
4589      * exception
4590      */
4591     @Test
testGetNetworkSlicingConfiguration()4592     public void testGetNetworkSlicingConfiguration() {
4593         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
4594             return;
4595         }
4596         CompletableFuture<NetworkSlicingConfig> resultFuture = new CompletableFuture<>();
4597         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
4598                 (tm) -> tm.getNetworkSlicingConfiguration(mSimpleExecutor, resultFuture::complete));
4599     }
4600 
4601     @Test
testCheckCarrierPrivilegesForPackageEnforcesReadPrivilege()4602     public void testCheckCarrierPrivilegesForPackageEnforcesReadPrivilege() {
4603         try {
4604             InstrumentationRegistry.getInstrumentation().getUiAutomation()
4605                 .adoptShellPermissionIdentity("android.permission.READ_PRIVILEGED_PHONE_STATE");
4606             mTelephonyManager.checkCarrierPrivilegesForPackage(mSelfPackageName);
4607         } catch (SecurityException e) {
4608             fail("TelephonyManager#checkCarrierPrivilegesForPackage requires "
4609                     + "READ_PRIVILEGED_PHONE_STATE");
4610         } finally {
4611             InstrumentationRegistry.getInstrumentation().getUiAutomation()
4612                 .dropShellPermissionIdentity();
4613         }
4614     }
4615 
4616     @Test
testCheckCarrierPrivilegesForPackageThrowsExceptionWithoutReadPrivilege()4617     public void testCheckCarrierPrivilegesForPackageThrowsExceptionWithoutReadPrivilege() {
4618         if (!hasCellular()) return;
4619         try {
4620             mTelephonyManager.checkCarrierPrivilegesForPackage(mSelfPackageName);
4621             fail("TelephonyManager#checkCarrierPrivilegesForPackage must be protected "
4622                     + "with READ_PRIVILEGED_PHONE_STATE");
4623         } catch (SecurityException e) {
4624             // expected
4625         }
4626     }
4627 
4628     @Test
testCheckCarrierPrivilegesForPackageAnyPhone()4629     public void testCheckCarrierPrivilegesForPackageAnyPhone() {
4630         try {
4631             mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(mSelfPackageName);
4632         } catch (SecurityException e) {
4633             fail("TelephonyManager#checkCarrierPrivilegesForPackageAnyPhone shouldn't require "
4634                     + "READ_PRIVILEGED_PHONE_STATE");
4635         }
4636     }
4637 
4638     @Test
testGetCarrierPackageNamesForIntentAndPhoneEnforcesReadPrivilege()4639     public void testGetCarrierPackageNamesForIntentAndPhoneEnforcesReadPrivilege() {
4640         try {
4641             InstrumentationRegistry.getInstrumentation().getUiAutomation()
4642                 .adoptShellPermissionIdentity("android.permission.READ_PRIVILEGED_PHONE_STATE");
4643             Intent intent = new Intent();
4644             int phoneId = 1;
4645             mTelephonyManager.getCarrierPackageNamesForIntentAndPhone(intent, phoneId);
4646         } catch (SecurityException e) {
4647             fail("TelephonyManager#getCarrierPackageNamesForIntentAndPhone requires "
4648                     + "READ_PRIVILEGED_PHONE_STATE");
4649         } finally {
4650             InstrumentationRegistry.getInstrumentation().getUiAutomation()
4651                 .dropShellPermissionIdentity();
4652         }
4653     }
4654 
4655     @Test
testGetCarrierPackageNamesForIntentAndPhoneThrowsExceptionWithoutReadPrivilege()4656     public void testGetCarrierPackageNamesForIntentAndPhoneThrowsExceptionWithoutReadPrivilege() {
4657         if (!hasCellular()) return;
4658         try {
4659             Intent intent = new Intent();
4660             int phoneId = 1;
4661             mTelephonyManager.getCarrierPackageNamesForIntentAndPhone(intent, phoneId);
4662             fail("TelephonyManager#getCarrierPackageNamesForIntentAndPhone must be protected "
4663                     + "with READ_PRIVILEGED_PHONE_STATE");
4664         } catch (SecurityException e) {
4665             // expected
4666         } finally {
4667             InstrumentationRegistry.getInstrumentation().getUiAutomation()
4668                 .dropShellPermissionIdentity();
4669         }
4670     }
4671 
4672     @Test
testGetPackagesWithCarrierPrivilegesEnforcesReadPrivilege()4673     public void testGetPackagesWithCarrierPrivilegesEnforcesReadPrivilege() {
4674         try {
4675             InstrumentationRegistry.getInstrumentation().getUiAutomation()
4676                 .adoptShellPermissionIdentity("android.permission.READ_PRIVILEGED_PHONE_STATE");
4677             mTelephonyManager.getPackagesWithCarrierPrivileges();
4678         } catch (SecurityException e) {
4679             fail("TelephonyManager#getPackagesWithCarrierPrivileges requires "
4680                     + "READ_PRIVILEGED_PHONE_STATE");
4681         } finally {
4682             InstrumentationRegistry.getInstrumentation().getUiAutomation()
4683                 .dropShellPermissionIdentity();
4684         }
4685     }
4686 
4687     @Test
testGetPackagesWithCarrierPrivilegesThrowsExceptionWithoutReadPrivilege()4688     public void testGetPackagesWithCarrierPrivilegesThrowsExceptionWithoutReadPrivilege() {
4689         if (!hasCellular()) return;
4690         try {
4691             mTelephonyManager.getPackagesWithCarrierPrivileges();
4692             fail("TelephonyManager#getPackagesWithCarrierPrivileges must be protected "
4693                     + "with READ_PRIVILEGED_PHONE_STATE");
4694         } catch (SecurityException e) {
4695             // expected
4696         }
4697     }
4698 }
4699 
4700