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