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