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