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