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