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