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