1 package org.robolectric.shadows; 2 3 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 4 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1; 5 import static android.os.Build.VERSION_CODES.M; 6 import static android.os.Build.VERSION_CODES.N; 7 import static android.os.Build.VERSION_CODES.O; 8 import static android.os.Build.VERSION_CODES.P; 9 import static android.os.Build.VERSION_CODES.Q; 10 import static android.os.Build.VERSION_CODES.R; 11 import static android.os.Build.VERSION_CODES.S; 12 import static android.os.Build.VERSION_CODES.TIRAMISU; 13 import static android.telephony.PhoneStateListener.LISTEN_CALL_STATE; 14 import static android.telephony.PhoneStateListener.LISTEN_CELL_INFO; 15 import static android.telephony.PhoneStateListener.LISTEN_CELL_LOCATION; 16 import static android.telephony.PhoneStateListener.LISTEN_NONE; 17 import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE; 18 import static android.telephony.TelephonyManager.CALL_STATE_IDLE; 19 import static android.telephony.TelephonyManager.CALL_STATE_RINGING; 20 21 import android.Manifest.permission; 22 import android.annotation.CallSuper; 23 import android.app.ActivityThread; 24 import android.app.PendingIntent; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.net.Uri; 28 import android.os.Build; 29 import android.os.Build.VERSION; 30 import android.os.PersistableBundle; 31 import android.os.SystemProperties; 32 import android.telecom.PhoneAccountHandle; 33 import android.telephony.Annotation.NetworkType; 34 import android.telephony.Annotation.OverrideNetworkType; 35 import android.telephony.CarrierRestrictionRules; 36 import android.telephony.CellInfo; 37 import android.telephony.CellLocation; 38 import android.telephony.PhoneStateListener; 39 import android.telephony.ServiceState; 40 import android.telephony.SignalStrength; 41 import android.telephony.SubscriptionManager; 42 import android.telephony.TelephonyCallback; 43 import android.telephony.TelephonyCallback.CallStateListener; 44 import android.telephony.TelephonyCallback.CellInfoListener; 45 import android.telephony.TelephonyCallback.CellLocationListener; 46 import android.telephony.TelephonyCallback.DisplayInfoListener; 47 import android.telephony.TelephonyCallback.ServiceStateListener; 48 import android.telephony.TelephonyCallback.SignalStrengthsListener; 49 import android.telephony.TelephonyDisplayInfo; 50 import android.telephony.TelephonyManager; 51 import android.telephony.TelephonyManager.CellInfoCallback; 52 import android.telephony.VisualVoicemailSmsFilterSettings; 53 import android.telephony.emergency.EmergencyNumber; 54 import android.text.TextUtils; 55 import com.google.common.base.Ascii; 56 import com.google.common.base.Preconditions; 57 import com.google.common.base.Predicate; 58 import com.google.common.collect.ImmutableList; 59 import com.google.common.collect.ImmutableMap; 60 import com.google.common.collect.ImmutableSet; 61 import com.google.common.collect.Iterables; 62 import java.util.ArrayList; 63 import java.util.Collections; 64 import java.util.HashSet; 65 import java.util.LinkedHashMap; 66 import java.util.List; 67 import java.util.Locale; 68 import java.util.Map; 69 import java.util.Set; 70 import java.util.concurrent.Executor; 71 import java.util.concurrent.atomic.AtomicInteger; 72 import org.robolectric.RuntimeEnvironment; 73 import org.robolectric.annotation.HiddenApi; 74 import org.robolectric.annotation.Implementation; 75 import org.robolectric.annotation.Implements; 76 import org.robolectric.annotation.RealObject; 77 import org.robolectric.annotation.Resetter; 78 import org.robolectric.shadow.api.Shadow; 79 import org.robolectric.util.ReflectionHelpers; 80 import org.robolectric.versioning.AndroidVersions.U; 81 import org.robolectric.versioning.AndroidVersions.V; 82 83 @Implements(value = TelephonyManager.class, looseSignatures = true) 84 public class ShadowTelephonyManager { 85 86 @RealObject protected TelephonyManager realTelephonyManager; 87 88 private final Map<PhoneStateListener, Integer> phoneStateRegistrations = 89 Collections.synchronizedMap(new LinkedHashMap<>()); 90 private final /*List<TelephonyCallback>*/ List<Object> telephonyCallbackRegistrations = 91 new ArrayList<>(); 92 private static final Map<Integer, String> slotIndexToDeviceId = 93 Collections.synchronizedMap(new LinkedHashMap<>()); 94 private static final Map<Integer, String> slotIndexToImei = 95 Collections.synchronizedMap(new LinkedHashMap<>()); 96 private static final Map<Integer, String> slotIndexToMeid = 97 Collections.synchronizedMap(new LinkedHashMap<>()); 98 private static final Map<PhoneAccountHandle, Boolean> voicemailVibrationEnabledMap = 99 Collections.synchronizedMap(new LinkedHashMap<>()); 100 private static final Map<PhoneAccountHandle, Uri> voicemailRingtoneUriMap = 101 Collections.synchronizedMap(new LinkedHashMap<>()); 102 private static final Map<PhoneAccountHandle, TelephonyManager> phoneAccountToTelephonyManagers = 103 Collections.synchronizedMap(new LinkedHashMap<>()); 104 private static final Map<PhoneAccountHandle, Integer> phoneAccountHandleSubscriptionId = 105 Collections.synchronizedMap(new LinkedHashMap<>()); 106 107 private PhoneStateListener lastListener; 108 private /*TelephonyCallback*/ Object lastTelephonyCallback; 109 private int lastEventFlags; 110 111 private String deviceId; 112 private String deviceSoftwareVersion; 113 private String imei; 114 private String meid; 115 private String groupIdLevel1; 116 private String networkOperatorName = ""; 117 private String networkCountryIso; 118 private String networkOperator = ""; 119 private String networkSpecifier = ""; 120 private Locale simLocale; 121 private String simOperator = ""; 122 private String simOperatorName; 123 private String simSerialNumber; 124 private static volatile boolean readPhoneStatePermission = true; 125 private int phoneType = TelephonyManager.PHONE_TYPE_GSM; 126 private String line1Number; 127 private int networkType; 128 private int dataNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 129 private int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 130 private static volatile List<CellInfo> allCellInfo = Collections.emptyList(); 131 private static volatile List<CellInfo> callbackCellInfos = null; 132 private static volatile CellLocation cellLocation = null; 133 private int callState = CALL_STATE_IDLE; 134 private int dataState = TelephonyManager.DATA_DISCONNECTED; 135 private int dataActivity = TelephonyManager.DATA_ACTIVITY_NONE; 136 private String incomingPhoneNumber = null; 137 private static volatile boolean isSmsCapable = true; 138 private static volatile boolean voiceCapable = true; 139 private String voiceMailNumber; 140 private String voiceMailAlphaTag; 141 private static volatile int phoneCount = 1; 142 private static volatile int activeModemCount = 1; 143 private static volatile Map<Integer, TelephonyManager> subscriptionIdsToTelephonyManagers = 144 Collections.synchronizedMap(new LinkedHashMap<>()); 145 private PersistableBundle carrierConfig; 146 private ServiceState serviceState; 147 private boolean isNetworkRoaming; 148 private static final Map<Integer, Integer> simStates = 149 Collections.synchronizedMap(new LinkedHashMap<>()); 150 private static final Map<Integer, Integer> currentPhoneTypes = 151 Collections.synchronizedMap(new LinkedHashMap<>()); 152 private static final Map<Integer, List<String>> carrierPackageNames = 153 Collections.synchronizedMap(new LinkedHashMap<>()); 154 private static final Map<Integer, String> simCountryIsoMap = 155 Collections.synchronizedMap(new LinkedHashMap<>()); 156 private int simCarrierId; 157 private int simSpecificCarrierId; 158 private CharSequence simCarrierIdName; 159 private int carrierIdFromSimMccMnc; 160 private String subscriberId; 161 private static volatile /*UiccSlotInfo[]*/ Object uiccSlotInfos; 162 private static volatile /*List<UiccCardInfo>*/ Object uiccCardsInfo = new ArrayList<>(); 163 private String visualVoicemailPackageName = null; 164 private SignalStrength signalStrength; 165 private boolean dataEnabled = false; 166 private final Set<Integer> dataDisabledReasons = new HashSet<>(); 167 private boolean isRttSupported; 168 private static volatile boolean isTtyModeSupported; 169 private static final Map<Integer, Boolean> subIdToHasCarrierPrivileges = 170 Collections.synchronizedMap(new LinkedHashMap<>()); 171 private static final List<String> sentDialerSpecialCodes = new ArrayList<>(); 172 private static volatile boolean hearingAidCompatibilitySupported = false; 173 private int requestCellInfoUpdateErrorCode = 0; 174 private Throwable requestCellInfoUpdateDetail = null; 175 private Object telephonyDisplayInfo; 176 private boolean isDataConnectionAllowed; 177 private static int callComposerStatus = 0; 178 private VisualVoicemailSmsParams lastVisualVoicemailSmsParams; 179 private VisualVoicemailSmsFilterSettings visualVoicemailSmsFilterSettings; 180 private static volatile boolean emergencyCallbackMode; 181 private static Map<Integer, List<EmergencyNumber>> emergencyNumbersList; 182 private static volatile boolean isDataRoamingEnabled; 183 private /*CarrierRestrictionRules*/ Object carrierRestrictionRules; 184 private final AtomicInteger modemRebootCount = new AtomicInteger(); 185 186 /** 187 * Should be {@link TelephonyManager.BootstrapAuthenticationCallback} but this object was 188 * introduced in Android S, so we are using Object to avoid breaking other SDKs 189 * 190 * <p>XXX Look into using the real types if we're now compiling against S 191 */ 192 private Object callback; 193 194 private static volatile /*PhoneCapability*/ Object phoneCapability; 195 196 static { resetAllSimStates()197 resetAllSimStates(); resetAllSimCountryIsos()198 resetAllSimCountryIsos(); 199 } 200 201 @Resetter reset()202 public static void reset() { 203 subscriptionIdsToTelephonyManagers.clear(); 204 resetAllSimStates(); 205 currentPhoneTypes.clear(); 206 carrierPackageNames.clear(); 207 resetAllSimCountryIsos(); 208 slotIndexToDeviceId.clear(); 209 slotIndexToImei.clear(); 210 slotIndexToMeid.clear(); 211 voicemailVibrationEnabledMap.clear(); 212 voicemailRingtoneUriMap.clear(); 213 phoneAccountToTelephonyManagers.clear(); 214 phoneAccountHandleSubscriptionId.clear(); 215 subIdToHasCarrierPrivileges.clear(); 216 allCellInfo = Collections.emptyList(); 217 cellLocation = null; 218 callbackCellInfos = null; 219 uiccSlotInfos = null; 220 uiccCardsInfo = new ArrayList<>(); 221 callComposerStatus = 0; 222 emergencyCallbackMode = false; 223 emergencyNumbersList = null; 224 phoneCapability = null; 225 isTtyModeSupported = false; 226 readPhoneStatePermission = true; 227 isSmsCapable = true; 228 voiceCapable = true; 229 phoneCount = 1; 230 activeModemCount = 1; 231 sentDialerSpecialCodes.clear(); 232 hearingAidCompatibilitySupported = false; 233 } 234 235 @Implementation(minSdk = S) setCallComposerStatus(int callComposerStatus)236 protected void setCallComposerStatus(int callComposerStatus) { 237 ShadowTelephonyManager.callComposerStatus = callComposerStatus; 238 } 239 240 @Implementation(minSdk = S) 241 @HiddenApi getCallComposerStatus()242 protected int getCallComposerStatus() { 243 return callComposerStatus; 244 } 245 getBootstrapAuthenticationCallback()246 public Object getBootstrapAuthenticationCallback() { 247 return callback; 248 } 249 250 @Implementation(minSdk = S) 251 @HiddenApi bootstrapAuthenticationRequest( Object appType, Object nafId, Object securityProtocol, Object forceBootStrapping, Object e, Object callback)252 public void bootstrapAuthenticationRequest( 253 Object appType, 254 Object nafId, 255 Object securityProtocol, 256 Object forceBootStrapping, 257 Object e, 258 Object callback) { 259 this.callback = callback; 260 } 261 setPhoneCapability( Object phoneCapability)262 public void setPhoneCapability(/*PhoneCapability*/ Object phoneCapability) { 263 ShadowTelephonyManager.phoneCapability = phoneCapability; 264 } 265 266 @Implementation(minSdk = S) 267 @HiddenApi getPhoneCapability()268 public /*PhoneCapability*/ Object getPhoneCapability() { 269 return phoneCapability; 270 } 271 272 @Implementation listen(PhoneStateListener listener, int flags)273 protected void listen(PhoneStateListener listener, int flags) { 274 lastListener = listener; 275 lastEventFlags = flags; 276 277 if (flags == LISTEN_NONE) { 278 phoneStateRegistrations.remove(listener); 279 } else { 280 initListener(listener, flags); 281 phoneStateRegistrations.put(listener, flags); 282 } 283 } 284 285 /** 286 * Returns the most recent listener passed to #listen(). 287 * 288 * @return Phone state listener. 289 * @deprecated Avoid using. 290 */ 291 @Deprecated getListener()292 public PhoneStateListener getListener() { 293 return lastListener; 294 } 295 296 /** 297 * Returns the most recent flags passed to #listen(). 298 * 299 * @return Event flags. 300 * @deprecated Avoid using. 301 */ 302 @Deprecated getEventFlags()303 public int getEventFlags() { 304 return lastEventFlags; 305 } 306 307 @Implementation(minSdk = S) registerTelephonyCallback( Object executor, Object callback)308 public void registerTelephonyCallback( 309 /*Executor*/ Object executor, /*TelephonyCallback*/ Object callback) { 310 Preconditions.checkArgument(executor instanceof Executor); 311 Preconditions.checkArgument(callback instanceof TelephonyCallback); 312 lastTelephonyCallback = callback; 313 initTelephonyCallback(callback); 314 telephonyCallbackRegistrations.add(callback); 315 } 316 317 @Implementation(minSdk = TIRAMISU) registerTelephonyCallback( Object includeLocationData, Object executor, Object callback)318 protected void registerTelephonyCallback( 319 /*int*/ Object includeLocationData, /*Executor*/ 320 Object executor, /*TelephonyCallback*/ 321 Object callback) { 322 Preconditions.checkArgument(includeLocationData instanceof Integer); 323 registerTelephonyCallback(executor, callback); 324 } 325 326 @Implementation(minSdk = S) unregisterTelephonyCallback( Object callback)327 public void unregisterTelephonyCallback(/*TelephonyCallback*/ Object callback) { 328 telephonyCallbackRegistrations.remove(callback); 329 } 330 331 /** Returns the most recent callback passed to #registerTelephonyCallback(). */ getLastTelephonyCallback()332 public /*TelephonyCallback*/ Object getLastTelephonyCallback() { 333 return lastTelephonyCallback; 334 } 335 336 /** Call state may be specified via {@link #setCallState(int)}. */ 337 @Implementation(minSdk = S) getCallStateForSubscription()338 protected int getCallStateForSubscription() { 339 checkReadPhoneStatePermission(); 340 return callState; 341 } 342 343 /** Call state may be specified via {@link #setCallState(int)}. */ 344 @Implementation getCallState()345 protected int getCallState() { 346 checkReadPhoneStatePermission(); 347 return callState; 348 } 349 350 /** Sets the current call state to the desired state and updates any listeners. */ setCallState(int callState)351 public void setCallState(int callState) { 352 setCallState(callState, null); 353 } 354 355 /** 356 * Sets the current call state with the option to specify an incoming phone number for the 357 * CALL_STATE_RINGING state. The incoming phone number will be ignored for all other cases. 358 */ setCallState(int callState, String incomingPhoneNumber)359 public void setCallState(int callState, String incomingPhoneNumber) { 360 if (callState != CALL_STATE_RINGING) { 361 incomingPhoneNumber = null; 362 } 363 364 this.callState = callState; 365 this.incomingPhoneNumber = incomingPhoneNumber; 366 367 for (PhoneStateListener listener : getListenersForFlags(LISTEN_CALL_STATE)) { 368 listener.onCallStateChanged(callState, incomingPhoneNumber); 369 } 370 if (VERSION.SDK_INT >= S) { 371 for (CallStateListener listener : getCallbackForListener(CallStateListener.class)) { 372 listener.onCallStateChanged(callState); 373 } 374 } 375 } 376 377 /** 378 * Data state may be specified via {@link #setDataState(int)}. If no override is set, this 379 * defaults to {@link TelephonyManager#DATA_DISCONNECTED}. 380 */ 381 @Implementation getDataState()382 protected int getDataState() { 383 return dataState; 384 } 385 386 /** Sets the data state returned by {@link #getDataState()}. */ setDataState(int dataState)387 public void setDataState(int dataState) { 388 this.dataState = dataState; 389 } 390 391 /** 392 * Data activity may be specified via {@link #setDataActivity(int)}. If no override is set, this 393 * defaults to {@link TelephonyManager#DATA_ACTIVITY_NONE}. 394 */ 395 @Implementation getDataActivity()396 protected int getDataActivity() { 397 return dataActivity; 398 } 399 400 /** 401 * Sets the value to be returned by calls to {@link #getDataActivity()}. This <b>should</b> 402 * correspond to one of the {@code DATA_ACTIVITY_*} constants defined on {@link TelephonyManager}, 403 * but this is not enforced. 404 */ setDataActivity(int dataActivity)405 public void setDataActivity(int dataActivity) { 406 this.dataActivity = dataActivity; 407 } 408 409 @Implementation getDeviceId()410 protected String getDeviceId() { 411 checkReadPhoneStatePermission(); 412 return deviceId; 413 } 414 setDeviceId(String newDeviceId)415 public void setDeviceId(String newDeviceId) { 416 deviceId = newDeviceId; 417 } 418 419 @Implementation getDeviceSoftwareVersion()420 protected String getDeviceSoftwareVersion() { 421 checkReadPhoneStatePermission(); 422 return deviceSoftwareVersion; 423 } 424 setDeviceSoftwareVersion(String newDeviceSoftwareVersion)425 public void setDeviceSoftwareVersion(String newDeviceSoftwareVersion) { 426 deviceSoftwareVersion = newDeviceSoftwareVersion; 427 } 428 429 @Implementation(minSdk = LOLLIPOP_MR1, maxSdk = U.SDK_INT) setNetworkOperatorName(String networkOperatorName)430 public void setNetworkOperatorName(String networkOperatorName) { 431 this.networkOperatorName = networkOperatorName; 432 } 433 434 @Implementation(minSdk = V.SDK_INT) setNetworkOperatorNameForPhone( int phoneId, String networkOperatorName)435 public void setNetworkOperatorNameForPhone( 436 /* Ignored */ int phoneId, String networkOperatorName) { 437 setNetworkOperatorName(networkOperatorName); 438 } 439 440 @Implementation getImei()441 protected String getImei() { 442 checkReadPhoneStatePermission(); 443 return imei; 444 } 445 446 @Implementation(minSdk = O) getImei(int slotIndex)447 protected String getImei(int slotIndex) { 448 checkReadPhoneStatePermission(); 449 return slotIndexToImei.get(slotIndex); 450 } 451 452 /** Set the IMEI returned by getImei(). */ setImei(String imei)453 public void setImei(String imei) { 454 this.imei = imei; 455 } 456 457 /** Set the IMEI returned by {@link #getImei(int)}. */ setImei(int slotIndex, String imei)458 public void setImei(int slotIndex, String imei) { 459 slotIndexToImei.put(slotIndex, imei); 460 } 461 462 @Implementation(minSdk = O) getMeid()463 protected String getMeid() { 464 checkReadPhoneStatePermission(); 465 return meid; 466 } 467 468 @Implementation(minSdk = O) getMeid(int slotIndex)469 protected String getMeid(int slotIndex) { 470 checkReadPhoneStatePermission(); 471 return slotIndexToMeid.get(slotIndex); 472 } 473 474 /** Set the MEID returned by getMeid(). */ setMeid(String meid)475 public void setMeid(String meid) { 476 this.meid = meid; 477 } 478 479 /** Set the MEID returned by {@link #getMeid(int)}. */ setMeid(int slotIndex, String meid)480 public void setMeid(int slotIndex, String meid) { 481 slotIndexToMeid.put(slotIndex, meid); 482 } 483 484 @Implementation getNetworkOperatorName()485 protected String getNetworkOperatorName() { 486 return networkOperatorName; 487 } 488 489 @Implementation(minSdk = LOLLIPOP_MR1, maxSdk = P) setNetworkCountryIso(String networkCountryIso)490 public void setNetworkCountryIso(String networkCountryIso) { 491 this.networkCountryIso = networkCountryIso; 492 } 493 494 /** 495 * Returns the SIM country lowercase. This matches the API this shadows: 496 * https://developer.android.com/reference/android/telephony/TelephonyManager#getNetworkCountryIso(). 497 */ 498 @Implementation getNetworkCountryIso()499 protected String getNetworkCountryIso() { 500 return networkCountryIso == null ? null : Ascii.toLowerCase(networkCountryIso); 501 } 502 503 /** Sets the sim locale returned by {@link #getSimLocale()}. */ setSimLocale(Locale simLocale)504 public void setSimLocale(Locale simLocale) { 505 this.simLocale = simLocale; 506 } 507 508 /** Returns sim locale set by {@link #setSimLocale}. */ 509 @Implementation(minSdk = Q) getSimLocale()510 protected Locale getSimLocale() { 511 return simLocale; 512 } 513 setNetworkOperator(String networkOperator)514 public void setNetworkOperator(String networkOperator) { 515 this.networkOperator = networkOperator; 516 } 517 518 @Implementation getNetworkOperator()519 protected String getNetworkOperator() { 520 return networkOperator; 521 } 522 setNetworkSpecifier(String networkSpecifier)523 public void setNetworkSpecifier(String networkSpecifier) { 524 this.networkSpecifier = networkSpecifier; 525 } 526 527 @Implementation(minSdk = O) getNetworkSpecifier()528 protected String getNetworkSpecifier() { 529 return networkSpecifier; 530 } 531 532 @Implementation getSimOperator()533 protected String getSimOperator() { 534 return simOperator; 535 } 536 setSimOperator(String simOperator)537 public void setSimOperator(String simOperator) { 538 this.simOperator = simOperator; 539 } 540 541 @Implementation getSimOperatorName()542 protected String getSimOperatorName() { 543 return simOperatorName; 544 } 545 546 @Implementation(minSdk = LOLLIPOP_MR1, maxSdk = U.SDK_INT) setSimOperatorName(String simOperatorName)547 public void setSimOperatorName(String simOperatorName) { 548 this.simOperatorName = simOperatorName; 549 } 550 551 @Implementation(minSdk = V.SDK_INT) setSimOperatorNameForPhone( int phoneId, String name)552 public void setSimOperatorNameForPhone(/* Ignored */ int phoneId, String name) { 553 setSimOperatorName(name); 554 } 555 556 @Implementation getSimSerialNumber()557 protected String getSimSerialNumber() { 558 checkReadPhoneStatePermission(); 559 return this.simSerialNumber; 560 } 561 562 /** sets the serial number that will be returned by {@link #getSimSerialNumber}. */ setSimSerialNumber(String simSerialNumber)563 public void setSimSerialNumber(String simSerialNumber) { 564 this.simSerialNumber = simSerialNumber; 565 } 566 567 /** 568 * Returns the SIM country lowercase. This matches the API it shadows: 569 * https://developer.android.com/reference/android/telephony/TelephonyManager#getSimCountryIso(). 570 */ 571 @Implementation getSimCountryIso()572 protected String getSimCountryIso() { 573 String simCountryIso = simCountryIsoMap.get(/* subId= */ 0); 574 return simCountryIso == null ? simCountryIso : Ascii.toLowerCase(simCountryIso); 575 } 576 577 @Implementation(minSdk = N, maxSdk = Q) 578 @HiddenApi getSimCountryIso(int subId)579 protected String getSimCountryIso(int subId) { 580 return simCountryIsoMap.get(subId); 581 } 582 583 @Implementation(minSdk = LOLLIPOP_MR1) setSimCountryIso(String simCountryIso)584 public void setSimCountryIso(String simCountryIso) { 585 setSimCountryIso(/* subId= */ 0, simCountryIso); 586 } 587 588 /** Sets the {@code simCountryIso} for the given {@code subId}. */ setSimCountryIso(int subId, String simCountryIso)589 public void setSimCountryIso(int subId, String simCountryIso) { 590 simCountryIsoMap.put(subId, simCountryIso); 591 } 592 593 /** Clears {@code subId} to simCountryIso mapping and resets to default state. */ resetAllSimCountryIsos()594 public static void resetAllSimCountryIsos() { 595 simCountryIsoMap.clear(); 596 simCountryIsoMap.put(0, ""); 597 } 598 599 /** 600 * Clears {@code subId} to simCountryIso mapping and resets to default state. 601 * 602 * @deprecated for resetAllSimCountryIsos 603 */ 604 @Deprecated resetSimCountryIsos()605 public void resetSimCountryIsos() { 606 resetAllSimCountryIsos(); 607 } 608 609 @Implementation getSimState()610 protected int getSimState() { 611 return getSimState(/* slotIndex= */ 0); 612 } 613 614 /** Sets the sim state of slot 0. */ setSimState(int simState)615 public void setSimState(int simState) { 616 setSimState(/* slotIndex= */ 0, simState); 617 } 618 619 /** Set the sim state for the given {@code slotIndex}. */ setSimState(int slotIndex, int state)620 public void setSimState(int slotIndex, int state) { 621 simStates.put(slotIndex, state); 622 } 623 624 @Implementation(minSdk = O) getSimState(int slotIndex)625 protected int getSimState(int slotIndex) { 626 return simStates.getOrDefault(slotIndex, TelephonyManager.SIM_STATE_UNKNOWN); 627 } 628 629 /** Sets the UICC slots information returned by {@link #getUiccSlotsInfo()}. */ setUiccSlotsInfo( Object uiccSlotsInfos)630 public void setUiccSlotsInfo(/*UiccSlotInfo[]*/ Object uiccSlotsInfos) { 631 ShadowTelephonyManager.uiccSlotInfos = uiccSlotsInfos; 632 } 633 634 /** Returns the UICC slots information set by {@link #setUiccSlotsInfo}. */ 635 @Implementation(minSdk = P) 636 @HiddenApi getUiccSlotsInfo()637 protected /*UiccSlotInfo[]*/ Object getUiccSlotsInfo() { 638 return uiccSlotInfos; 639 } 640 641 /** Sets the UICC cards information returned by {@link #getUiccCardsInfo()}. */ setUiccCardsInfo( Object uiccCardsInfo)642 public void setUiccCardsInfo(/*List<UiccCardInfo>*/ Object uiccCardsInfo) { 643 ShadowTelephonyManager.uiccCardsInfo = uiccCardsInfo; 644 } 645 646 /** Returns the UICC cards information set by {@link #setUiccCardsInfo}. */ 647 @Implementation(minSdk = Q) 648 @HiddenApi getUiccCardsInfo()649 protected /*List<UiccCardInfo>*/ Object getUiccCardsInfo() { 650 return uiccCardsInfo; 651 } 652 653 /** Clears {@code slotIndex} to state mapping and resets to default state. */ resetAllSimStates()654 public static void resetAllSimStates() { 655 simStates.clear(); 656 simStates.put(0, TelephonyManager.SIM_STATE_READY); 657 } 658 659 /** 660 * Clears {@code slotIndex} to state mapping and resets to default state. 661 * 662 * @deprecated use resetAllSimStates() 663 */ 664 @Deprecated resetSimStates()665 public void resetSimStates() { 666 resetAllSimStates(); 667 } 668 setReadPhoneStatePermission(boolean readPhoneStatePermission)669 public void setReadPhoneStatePermission(boolean readPhoneStatePermission) { 670 ShadowTelephonyManager.readPhoneStatePermission = readPhoneStatePermission; 671 } 672 checkReadPhoneStatePermission()673 private void checkReadPhoneStatePermission() { 674 if (!readPhoneStatePermission) { 675 throw new SecurityException(); 676 } 677 } 678 checkReadPrivilegedPhoneStatePermission()679 private void checkReadPrivilegedPhoneStatePermission() { 680 if (!checkPermission(permission.READ_PRIVILEGED_PHONE_STATE)) { 681 throw new SecurityException(); 682 } 683 } 684 checkModifyPhoneStatePermission()685 private void checkModifyPhoneStatePermission() { 686 if (!checkPermission(permission.MODIFY_PHONE_STATE)) { 687 throw new SecurityException(); 688 } 689 } 690 getShadowInstrumentation()691 static ShadowInstrumentation getShadowInstrumentation() { 692 ActivityThread activityThread = (ActivityThread) RuntimeEnvironment.getActivityThread(); 693 return Shadow.extract(activityThread.getInstrumentation()); 694 } 695 checkPermission(String permission)696 static boolean checkPermission(String permission) { 697 return getShadowInstrumentation() 698 .checkPermission(permission, android.os.Process.myPid(), android.os.Process.myUid()) 699 == PERMISSION_GRANTED; 700 } 701 702 @Implementation getPhoneType()703 protected int getPhoneType() { 704 return phoneType; 705 } 706 707 @Implementation(minSdk = LOLLIPOP_MR1, maxSdk = U.SDK_INT) setPhoneType(int phoneType)708 public void setPhoneType(int phoneType) { 709 this.phoneType = phoneType; 710 } 711 712 @Implementation(minSdk = V.SDK_INT) setPhoneType( int phoneId, int type)713 public void setPhoneType(/* Ignored */ int phoneId, int type) { 714 setPhoneType(type); 715 } 716 717 @Implementation getLine1Number()718 protected String getLine1Number() { 719 checkReadPhoneStatePermission(); 720 return line1Number; 721 } 722 setLine1Number(String line1Number)723 public void setLine1Number(String line1Number) { 724 this.line1Number = line1Number; 725 } 726 727 @Implementation getNetworkType()728 protected int getNetworkType() { 729 checkReadPhoneStatePermission(); 730 return networkType; 731 } 732 733 /** 734 * @deprecated {@link TelephonyManager#getNetworkType()} was replaced with {@link 735 * TelephonyManager#getDataNetworkType()} in Android N, and has been deprecated in Android R. 736 * Use {@link #setDataNetworkType instead}. 737 */ 738 @Deprecated setNetworkType(int networkType)739 public void setNetworkType(int networkType) { 740 this.networkType = networkType; 741 } 742 743 /** 744 * Returns whatever value was set by the last call to {@link #setDataNetworkType}, defaulting to 745 * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if it was never called. 746 */ 747 @Implementation(minSdk = N) getDataNetworkType()748 protected int getDataNetworkType() { 749 checkReadPhoneStatePermission(); 750 return dataNetworkType; 751 } 752 753 /** 754 * Sets the value to be returned by calls to {@link #getDataNetworkType}. This <b>should</b> 755 * correspond to one of the {@code NETWORK_TYPE_*} constants defined on {@link TelephonyManager}, 756 * but this is not enforced. 757 */ 758 @Implementation(minSdk = LOLLIPOP_MR1) setDataNetworkType(int dataNetworkType)759 public void setDataNetworkType(int dataNetworkType) { 760 this.dataNetworkType = dataNetworkType; 761 } 762 763 /** 764 * Returns whatever value was set by the last call to {@link #setVoiceNetworkType}, defaulting to 765 * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if it was never called. 766 * 767 * <p>An exception will be thrown if the READ_PHONE_STATE permission has not been granted. 768 */ 769 @Implementation(minSdk = N) getVoiceNetworkType()770 protected int getVoiceNetworkType() { 771 checkReadPhoneStatePermission(); 772 return voiceNetworkType; 773 } 774 775 /** 776 * Sets the value to be returned by calls to {@link getVoiceNetworkType}. This <b>should</b> 777 * correspond to one of the {@code NETWORK_TYPE_*} constants defined on {@link TelephonyManager}, 778 * but this is not enforced. 779 */ setVoiceNetworkType(int voiceNetworkType)780 public void setVoiceNetworkType(int voiceNetworkType) { 781 this.voiceNetworkType = voiceNetworkType; 782 } 783 784 @Implementation getAllCellInfo()785 protected List<CellInfo> getAllCellInfo() { 786 return allCellInfo; 787 } 788 setAllCellInfo(List<CellInfo> allCellInfo)789 public void setAllCellInfo(List<CellInfo> allCellInfo) { 790 ShadowTelephonyManager.allCellInfo = allCellInfo; 791 792 for (PhoneStateListener listener : getListenersForFlags(LISTEN_CELL_INFO)) { 793 listener.onCellInfoChanged(allCellInfo); 794 } 795 if (VERSION.SDK_INT >= S) { 796 for (CellInfoListener listener : getCallbackForListener(CellInfoListener.class)) { 797 listener.onCellInfoChanged(allCellInfo); 798 } 799 } 800 } 801 802 /** 803 * Returns the value set by {@link #setCallbackCellInfos}, defaulting to calling the real {@link 804 * TelephonyManager#NETWORK_TYPE_UNKNOWN} if it was never called. 805 */ 806 @Implementation(minSdk = Q) requestCellInfoUpdate(Object cellInfoExecutor, Object cellInfoCallback)807 protected void requestCellInfoUpdate(Object cellInfoExecutor, Object cellInfoCallback) { 808 Executor executor = (Executor) cellInfoExecutor; 809 List<CellInfo> callbackCellInfos = ShadowTelephonyManager.callbackCellInfos; 810 if (callbackCellInfos == null) { 811 // ignore 812 } else if (requestCellInfoUpdateErrorCode != 0 || requestCellInfoUpdateDetail != null) { 813 // perform the "failure" callback operation via the specified executor 814 executor.execute( 815 () -> { 816 // Must cast 'callback' inside the anonymous class to avoid NoClassDefFoundError when 817 // referring to 'CellInfoCallback'. 818 CellInfoCallback callback = (CellInfoCallback) cellInfoCallback; 819 callback.onError(requestCellInfoUpdateErrorCode, requestCellInfoUpdateDetail); 820 }); 821 } else { 822 // perform the "success" callback operation via the specified executor 823 executor.execute( 824 () -> { 825 // Must cast 'callback' inside the anonymous class to avoid NoClassDefFoundError when 826 // referring to 'CellInfoCallback'. 827 CellInfoCallback callback = (CellInfoCallback) cellInfoCallback; 828 callback.onCellInfo(callbackCellInfos); 829 }); 830 } 831 } 832 833 /** 834 * Sets the value to be returned by calls to {@link requestCellInfoUpdate}. Note that it does not 835 * set the value to be returned by calls to {@link getAllCellInfo}; for that, see {@link 836 * setAllCellInfo}. 837 */ setCallbackCellInfos(List<CellInfo> callbackCellInfos)838 public void setCallbackCellInfos(List<CellInfo> callbackCellInfos) { 839 ShadowTelephonyManager.callbackCellInfos = callbackCellInfos; 840 } 841 842 /** 843 * Sets the values to be returned by a presumed error condition in {@link requestCellInfoUpdate}. 844 * These values will persist until cleared: to clear, set (0, null) using this method. 845 */ setRequestCellInfoUpdateErrorValues(int errorCode, Throwable detail)846 public void setRequestCellInfoUpdateErrorValues(int errorCode, Throwable detail) { 847 requestCellInfoUpdateErrorCode = errorCode; 848 requestCellInfoUpdateDetail = detail; 849 } 850 851 @Implementation getCellLocation()852 protected CellLocation getCellLocation() { 853 return ShadowTelephonyManager.cellLocation; 854 } 855 setCellLocation(CellLocation cellLocation)856 public void setCellLocation(CellLocation cellLocation) { 857 ShadowTelephonyManager.cellLocation = cellLocation; 858 for (PhoneStateListener listener : getListenersForFlags(LISTEN_CELL_LOCATION)) { 859 listener.onCellLocationChanged(cellLocation); 860 } 861 if (VERSION.SDK_INT >= S) { 862 for (CellLocationListener listener : getCallbackForListener(CellLocationListener.class)) { 863 listener.onCellLocationChanged(cellLocation); 864 } 865 } 866 } 867 868 @Implementation getGroupIdLevel1()869 protected String getGroupIdLevel1() { 870 checkReadPhoneStatePermission(); 871 return this.groupIdLevel1; 872 } 873 setGroupIdLevel1(String groupIdLevel1)874 public void setGroupIdLevel1(String groupIdLevel1) { 875 this.groupIdLevel1 = groupIdLevel1; 876 } 877 878 @CallSuper initListener(PhoneStateListener listener, int flags)879 protected void initListener(PhoneStateListener listener, int flags) { 880 // grab the state "atomically" before doing callbacks, in case they modify the state 881 String incomingPhoneNumber = this.incomingPhoneNumber; 882 List<CellInfo> allCellInfo = ShadowTelephonyManager.allCellInfo; 883 CellLocation cellLocation = ShadowTelephonyManager.cellLocation; 884 Object telephonyDisplayInfo = this.telephonyDisplayInfo; 885 ServiceState serviceState = this.serviceState; 886 887 if ((flags & LISTEN_CALL_STATE) != 0) { 888 listener.onCallStateChanged(callState, incomingPhoneNumber); 889 } 890 if ((flags & LISTEN_CELL_INFO) != 0) { 891 listener.onCellInfoChanged(allCellInfo); 892 } 893 if ((flags & LISTEN_CELL_LOCATION) != 0) { 894 listener.onCellLocationChanged(cellLocation); 895 } 896 897 if (telephonyDisplayInfo != null 898 && ((flags & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0)) { 899 listener.onDisplayInfoChanged((TelephonyDisplayInfo) telephonyDisplayInfo); 900 } 901 902 if (serviceState != null && ((flags & PhoneStateListener.LISTEN_SERVICE_STATE) != 0)) { 903 listener.onServiceStateChanged(serviceState); 904 } 905 } 906 907 @CallSuper initTelephonyCallback(Object callback)908 protected void initTelephonyCallback(Object callback) { 909 if (VERSION.SDK_INT < S) { 910 return; 911 } 912 // grab the state "atomically" before doing callbacks, in case they modify the state 913 int callState = this.callState; 914 List<CellInfo> allCellInfo = ShadowTelephonyManager.allCellInfo; 915 CellLocation cellLocation = ShadowTelephonyManager.cellLocation; 916 Object telephonyDisplayInfo = this.telephonyDisplayInfo; 917 ServiceState serviceState = this.serviceState; 918 919 if (callback instanceof CallStateListener) { 920 ((CallStateListener) callback).onCallStateChanged(callState); 921 } 922 if (callback instanceof CellInfoListener) { 923 ((CellInfoListener) callback).onCellInfoChanged(allCellInfo); 924 } 925 if (callback instanceof CellLocationListener) { 926 ((CellLocationListener) callback).onCellLocationChanged(cellLocation); 927 } 928 if (telephonyDisplayInfo != null && callback instanceof DisplayInfoListener) { 929 ((DisplayInfoListener) callback) 930 .onDisplayInfoChanged((TelephonyDisplayInfo) telephonyDisplayInfo); 931 } 932 if (serviceState != null && callback instanceof ServiceStateListener) { 933 ((ServiceStateListener) callback).onServiceStateChanged(serviceState); 934 } 935 } 936 getListenersForFlags(int flags)937 protected Iterable<PhoneStateListener> getListenersForFlags(int flags) { 938 return Iterables.filter( 939 ImmutableSet.copyOf(phoneStateRegistrations.keySet()), 940 new Predicate<PhoneStateListener>() { 941 @Override 942 public boolean apply(PhoneStateListener input) { 943 // only select PhoneStateListeners with matching flags 944 return (phoneStateRegistrations.get(input) & flags) != 0; 945 } 946 }); 947 } 948 949 /** 950 * Returns a view of {@code telephonyCallbackRegistrations} containing all elements that are of 951 * the type {@code clazz}. 952 */ 953 protected <T> Iterable<T> getCallbackForListener(Class<T> clazz) { 954 // Only selects TelephonyCallback with matching class. 955 return Iterables.filter(ImmutableList.copyOf(telephonyCallbackRegistrations), clazz); 956 } 957 958 /** 959 * @return true by default, or the value specified via {@link #setIsSmsCapable(boolean)} 960 */ 961 @Implementation 962 protected boolean isSmsCapable() { 963 return isSmsCapable; 964 } 965 966 /** Sets the value returned by {@link TelephonyManager#isSmsCapable()}. */ 967 public void setIsSmsCapable(boolean isSmsCapable) { 968 ShadowTelephonyManager.isSmsCapable = isSmsCapable; 969 } 970 971 /** 972 * Returns a new empty {@link PersistableBundle} by default, or the value specified via {@link 973 * #setCarrierConfig(PersistableBundle)}. 974 */ 975 @Implementation(minSdk = O) 976 protected PersistableBundle getCarrierConfig() { 977 checkReadPhoneStatePermission(); 978 return carrierConfig != null ? carrierConfig : new PersistableBundle(); 979 } 980 981 /** 982 * Sets the value returned by {@link TelephonyManager#getCarrierConfig()}. 983 * 984 * @param carrierConfig 985 */ 986 public void setCarrierConfig(PersistableBundle carrierConfig) { 987 this.carrierConfig = carrierConfig; 988 } 989 990 /** 991 * Returns {@code null} by default, or the value specified via {@link 992 * #setVoiceMailNumber(String)}. 993 */ 994 @Implementation 995 protected String getVoiceMailNumber() { 996 checkReadPhoneStatePermission(); 997 return voiceMailNumber; 998 } 999 1000 /** Sets the value returned by {@link TelephonyManager#getVoiceMailNumber()}. */ 1001 public void setVoiceMailNumber(String voiceMailNumber) { 1002 this.voiceMailNumber = voiceMailNumber; 1003 } 1004 1005 /** 1006 * Returns {@code null} by default or the value specified via {@link 1007 * #setVoiceMailAlphaTag(String)}. 1008 */ 1009 @Implementation 1010 protected String getVoiceMailAlphaTag() { 1011 checkReadPhoneStatePermission(); 1012 return voiceMailAlphaTag; 1013 } 1014 1015 /** Sets the value returned by {@link TelephonyManager#getVoiceMailAlphaTag()}. */ 1016 public void setVoiceMailAlphaTag(String voiceMailAlphaTag) { 1017 this.voiceMailAlphaTag = voiceMailAlphaTag; 1018 } 1019 1020 /** Returns 1 by default or the value specified via {@link #setPhoneCount(int)}. */ 1021 @Implementation(minSdk = M) 1022 protected int getPhoneCount() { 1023 return phoneCount; 1024 } 1025 1026 /** Sets the value returned by {@link TelephonyManager#getPhoneCount()}. */ 1027 public void setPhoneCount(int phoneCount) { 1028 ShadowTelephonyManager.phoneCount = phoneCount; 1029 } 1030 1031 /** Returns 1 by default or the value specified via {@link #setActiveModemCount(int)}. */ 1032 @Implementation(minSdk = R) 1033 protected int getActiveModemCount() { 1034 return activeModemCount; 1035 } 1036 1037 /** Sets the value returned by {@link TelephonyManager#getActiveModemCount()}. */ 1038 public void setActiveModemCount(int activeModemCount) { 1039 ShadowTelephonyManager.activeModemCount = activeModemCount; 1040 } 1041 1042 /** 1043 * Returns {@code null} by default or the value specified via {@link #setDeviceId(int, String)}. 1044 */ 1045 @Implementation(minSdk = M) 1046 protected String getDeviceId(int slot) { 1047 checkReadPhoneStatePermission(); 1048 return slotIndexToDeviceId.get(slot); 1049 } 1050 1051 /** Sets the value returned by {@link TelephonyManager#getDeviceId(int)}. */ 1052 public void setDeviceId(int slot, String deviceId) { 1053 slotIndexToDeviceId.put(slot, deviceId); 1054 } 1055 1056 /** 1057 * Returns {@code true} by default or the value specified via {@link #setVoiceCapable(boolean)}. 1058 */ 1059 @Implementation(minSdk = LOLLIPOP_MR1) 1060 protected boolean isVoiceCapable() { 1061 return voiceCapable; 1062 } 1063 1064 /** Sets the value returned by {@link #isVoiceCapable()}. */ 1065 public void setVoiceCapable(boolean voiceCapable) { 1066 ShadowTelephonyManager.voiceCapable = voiceCapable; 1067 } 1068 1069 /** 1070 * Returns {@code null} by default or the value specified via {@link 1071 * #setVoicemailVibrationEnabled(PhoneAccountHandle, boolean)}. 1072 */ 1073 @Implementation(minSdk = N) 1074 protected boolean isVoicemailVibrationEnabled(PhoneAccountHandle handle) { 1075 Boolean result = voicemailVibrationEnabledMap.get(handle); 1076 return result != null ? result : false; 1077 } 1078 1079 /** 1080 * Sets the value returned by {@link 1081 * TelephonyManager#isVoicemailVibrationEnabled(PhoneAccountHandle)}. 1082 */ 1083 @Implementation(minSdk = O) 1084 protected void setVoicemailVibrationEnabled(PhoneAccountHandle handle, boolean isEnabled) { 1085 voicemailVibrationEnabledMap.put(handle, isEnabled); 1086 } 1087 1088 /** 1089 * Returns {@code null} by default or the value specified via {@link 1090 * #setVoicemailRingtoneUri(PhoneAccountHandle, Uri)}. 1091 */ 1092 @Implementation(minSdk = N) 1093 protected Uri getVoicemailRingtoneUri(PhoneAccountHandle handle) { 1094 return voicemailRingtoneUriMap.get(handle); 1095 } 1096 1097 /** 1098 * Sets the value returned by {@link 1099 * TelephonyManager#getVoicemailRingtoneUri(PhoneAccountHandle)}. 1100 */ 1101 @Implementation(minSdk = O) 1102 protected void setVoicemailRingtoneUri(PhoneAccountHandle handle, Uri uri) { 1103 voicemailRingtoneUriMap.put(handle, uri); 1104 } 1105 1106 /** 1107 * Returns {@code null} by default or the value specified via {@link 1108 * #setTelephonyManagerForHandle(PhoneAccountHandle, TelephonyManager)}. 1109 */ 1110 @Implementation(minSdk = O) 1111 protected TelephonyManager createForPhoneAccountHandle(PhoneAccountHandle handle) { 1112 checkReadPhoneStatePermission(); 1113 return phoneAccountToTelephonyManagers.get(handle); 1114 } 1115 1116 /** 1117 * Sets the value returned by {@link 1118 * TelephonyManager#createForPhoneAccountHandle(PhoneAccountHandle)}. 1119 */ 1120 public void setTelephonyManagerForHandle( 1121 PhoneAccountHandle handle, TelephonyManager telephonyManager) { 1122 phoneAccountToTelephonyManagers.put(handle, telephonyManager); 1123 } 1124 1125 /** 1126 * Returns {@code null} by default or the value specified via {@link 1127 * #setTelephonyManagerForSubscriptionId(int, TelephonyManager)} 1128 */ 1129 @Implementation(minSdk = N) 1130 protected TelephonyManager createForSubscriptionId(int subId) { 1131 return subscriptionIdsToTelephonyManagers.get(subId); 1132 } 1133 1134 /** Sets the value returned by {@link TelephonyManager#createForSubscriptionId(int)}. */ 1135 public void setTelephonyManagerForSubscriptionId( 1136 int subscriptionId, TelephonyManager telephonyManager) { 1137 subscriptionIdsToTelephonyManagers.put(subscriptionId, telephonyManager); 1138 } 1139 1140 /** 1141 * Returns {@code null} by default or the value specified via {@link 1142 * #setServiceState(ServiceState)} 1143 */ 1144 @Implementation(minSdk = O) 1145 protected ServiceState getServiceState() { 1146 checkReadPhoneStatePermission(); 1147 return serviceState; 1148 } 1149 1150 /** 1151 * Returns {@code null} by default or the value specified via {@link 1152 * #setServiceState(ServiceState)} 1153 */ 1154 @Implementation(minSdk = TIRAMISU) 1155 protected ServiceState getServiceState(int includeLocationData) { 1156 return getServiceState(); 1157 } 1158 1159 /** Sets the value returned by {@link TelephonyManager#getServiceState()}. */ 1160 public void setServiceState(ServiceState serviceState) { 1161 this.serviceState = serviceState; 1162 1163 for (PhoneStateListener listener : getListenersForFlags(LISTEN_SERVICE_STATE)) { 1164 listener.onServiceStateChanged(serviceState); 1165 } 1166 if (VERSION.SDK_INT >= S) { 1167 for (ServiceStateListener listener : getCallbackForListener(ServiceStateListener.class)) { 1168 listener.onServiceStateChanged(serviceState); 1169 } 1170 } 1171 } 1172 1173 /** 1174 * Returns {@code false} by default or the value specified via {@link 1175 * #setIsNetworkRoaming(boolean)} 1176 */ 1177 @Implementation 1178 protected boolean isNetworkRoaming() { 1179 return isNetworkRoaming; 1180 } 1181 1182 /** Sets the value returned by {@link TelephonyManager#isNetworkRoaming()}. */ 1183 public void setIsNetworkRoaming(boolean isNetworkRoaming) { 1184 this.isNetworkRoaming = isNetworkRoaming; 1185 } 1186 1187 @Implementation(minSdk = M) 1188 @HiddenApi 1189 protected int getCurrentPhoneType(int subId) { 1190 return currentPhoneTypes.getOrDefault(subId, TelephonyManager.PHONE_TYPE_NONE); 1191 } 1192 1193 /** Sets the phone type for the given {@code subId}. */ 1194 public void setCurrentPhoneType(int subId, int phoneType) { 1195 currentPhoneTypes.put(subId, phoneType); 1196 } 1197 1198 /** Removes all {@code subId} to {@code phoneType} mappings. */ 1199 public static void clearPhoneTypes() { 1200 currentPhoneTypes.clear(); 1201 } 1202 1203 @Implementation(minSdk = M) 1204 @HiddenApi 1205 protected List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) { 1206 return carrierPackageNames.get(phoneId); 1207 } 1208 1209 @Implementation 1210 @HiddenApi 1211 protected List<String> getCarrierPackageNamesForIntent(Intent intent) { 1212 return carrierPackageNames.get(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 1213 } 1214 1215 /** Sets the {@code packages} for the given {@code phoneId}. */ 1216 public void setCarrierPackageNamesForPhone(int phoneId, List<String> packages) { 1217 carrierPackageNames.put(phoneId, packages); 1218 } 1219 1220 @Implementation(minSdk = Q) 1221 protected int getCarrierIdFromSimMccMnc() { 1222 return carrierIdFromSimMccMnc; 1223 } 1224 1225 /** Sets the value to be returned by {@link #getCarrierIdFromSimMccMnc()}. */ 1226 public void setCarrierIdFromSimMccMnc(int carrierIdFromSimMccMnc) { 1227 this.carrierIdFromSimMccMnc = carrierIdFromSimMccMnc; 1228 } 1229 1230 @Implementation(minSdk = P) 1231 protected int getSimCarrierId() { 1232 return simCarrierId; 1233 } 1234 1235 /** Sets the value to be returned by {@link #getSimCarrierId()}. */ 1236 public void setSimCarrierId(int simCarrierId) { 1237 this.simCarrierId = simCarrierId; 1238 } 1239 1240 @Implementation(minSdk = Q) 1241 protected int getSimSpecificCarrierId() { 1242 return simSpecificCarrierId; 1243 } 1244 1245 /** Sets the value to be returned by {@link #getSimSpecificCarrierId()}. */ 1246 public void setSimSpecificCarrierId(int simSpecificCarrierId) { 1247 this.simSpecificCarrierId = simSpecificCarrierId; 1248 } 1249 1250 @Implementation(minSdk = P) 1251 protected CharSequence getSimCarrierIdName() { 1252 return simCarrierIdName; 1253 } 1254 1255 /** Sets the value to be returned by {@link #getSimCarrierIdName()}. */ 1256 public void setSimCarrierIdName(CharSequence simCarrierIdName) { 1257 this.simCarrierIdName = simCarrierIdName; 1258 } 1259 1260 @Implementation 1261 protected String getSubscriberId() { 1262 checkReadPhoneStatePermission(); 1263 return subscriberId; 1264 } 1265 1266 /** Sets the value to be returned by {@link #getSubscriberId()}. */ 1267 public void setSubscriberId(String subscriberId) { 1268 this.subscriberId = subscriberId; 1269 } 1270 1271 @Implementation(minSdk = R) 1272 protected int getSubscriptionId(PhoneAccountHandle handle) { 1273 checkReadPhoneStatePermission(); 1274 return phoneAccountHandleSubscriptionId.get(handle); 1275 } 1276 1277 public void setPhoneAccountHandleSubscriptionId(PhoneAccountHandle handle, int subscriptionId) { 1278 phoneAccountHandleSubscriptionId.put(handle, subscriptionId); 1279 } 1280 1281 /** Returns the value set by {@link #setVisualVoicemailPackageName(String)}. */ 1282 @Implementation(minSdk = O) 1283 protected String getVisualVoicemailPackageName() { 1284 checkReadPhoneStatePermission(); 1285 return visualVoicemailPackageName; 1286 } 1287 1288 /** Sets the value to be returned by {@link #getVisualVoicemailPackageName()}. */ 1289 public void setVisualVoicemailPackageName(String visualVoicemailPackageName) { 1290 this.visualVoicemailPackageName = visualVoicemailPackageName; 1291 } 1292 1293 @Implementation(minSdk = P) 1294 protected SignalStrength getSignalStrength() { 1295 return signalStrength; 1296 } 1297 1298 /** Sets the value to be returned by {@link #getSignalStrength()} */ 1299 public void setSignalStrength(SignalStrength signalStrength) { 1300 this.signalStrength = signalStrength; 1301 for (PhoneStateListener listener : 1302 getListenersForFlags(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)) { 1303 listener.onSignalStrengthsChanged(signalStrength); 1304 } 1305 if (VERSION.SDK_INT >= S) { 1306 for (SignalStrengthsListener listener : 1307 getCallbackForListener(SignalStrengthsListener.class)) { 1308 listener.onSignalStrengthsChanged(signalStrength); 1309 } 1310 } 1311 } 1312 1313 /** 1314 * Cribbed from {@link android.telephony.PhoneNumberUtils#isEmergencyNumberInternal}. 1315 * 1316 * <p>TODO: need better implementation 1317 */ 1318 @Implementation(minSdk = Build.VERSION_CODES.Q) 1319 protected boolean isEmergencyNumber(String number) { 1320 if (ShadowServiceManager.getService(Context.TELEPHONY_SERVICE) == null) { 1321 throw new IllegalStateException("telephony service is null."); 1322 } 1323 1324 if (number == null) { 1325 return false; 1326 } 1327 1328 Context context = ReflectionHelpers.getField(realTelephonyManager, "mContext"); 1329 Locale locale = context == null ? null : context.getResources().getConfiguration().locale; 1330 String defaultCountryIso = locale == null ? null : locale.getCountry(); 1331 1332 int slotId = -1; 1333 boolean useExactMatch = true; 1334 1335 // retrieve the list of emergency numbers 1336 // check read-write ecclist property first 1337 String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId); 1338 1339 String emergencyNumbers = SystemProperties.get(ecclist, ""); 1340 1341 if (TextUtils.isEmpty(emergencyNumbers)) { 1342 // then read-only ecclist property since old RIL only uses this 1343 emergencyNumbers = SystemProperties.get("ro.ril.ecclist"); 1344 } 1345 1346 if (!TextUtils.isEmpty(emergencyNumbers)) { 1347 // searches through the comma-separated list for a match, 1348 // return true if one is found. 1349 for (String emergencyNum : emergencyNumbers.split(",")) { 1350 // It is not possible to append additional digits to an emergency number to dial 1351 // the number in Brazil - it won't connect. 1352 if (useExactMatch || "BR".equalsIgnoreCase(defaultCountryIso)) { 1353 if (number.equals(emergencyNum)) { 1354 return true; 1355 } 1356 } else { 1357 if (number.startsWith(emergencyNum)) { 1358 return true; 1359 } 1360 } 1361 } 1362 // no matches found against the list! 1363 return false; 1364 } 1365 1366 emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911"); 1367 for (String emergencyNum : emergencyNumbers.split(",")) { 1368 if (useExactMatch) { 1369 if (number.equals(emergencyNum)) { 1370 return true; 1371 } 1372 } else { 1373 if (number.startsWith(emergencyNum)) { 1374 return true; 1375 } 1376 } 1377 } 1378 1379 return false; 1380 } 1381 1382 /** 1383 * Emergency Callback Mode (ECBM) is typically set by the carrier, for a time window of 5 minutes 1384 * after the last outgoing emergency call. The user can exit ECBM via a system notification. 1385 * 1386 * @param emergencyCallbackMode whether the device is in ECBM or not. 1387 */ 1388 public void setEmergencyCallbackMode(boolean emergencyCallbackMode) { 1389 ShadowTelephonyManager.emergencyCallbackMode = emergencyCallbackMode; 1390 } 1391 1392 @Implementation(minSdk = Build.VERSION_CODES.O) 1393 protected boolean getEmergencyCallbackMode() { 1394 checkReadPrivilegedPhoneStatePermission(); 1395 return emergencyCallbackMode; 1396 } 1397 1398 @Implementation(minSdk = Build.VERSION_CODES.Q) 1399 protected boolean isPotentialEmergencyNumber(String number) { 1400 return isEmergencyNumber(number); 1401 } 1402 1403 /** 1404 * Implementation for {@link TelephonyManager#isDataEnabled}. 1405 * 1406 * @return False by default, unless set with {@link TelephonyManager#setDataEnabled}. 1407 */ 1408 @Implementation(minSdk = Build.VERSION_CODES.O) 1409 protected boolean isDataEnabled() { 1410 checkReadPhoneStatePermission(); 1411 return dataEnabled; 1412 } 1413 1414 /** 1415 * Implementation for {@link TelephonyManager#isDataEnabledForReason}. 1416 * 1417 * @return True by default, unless reason is set to false with {@link 1418 * TelephonyManager#setDataEnabledForReason}. 1419 */ 1420 @Implementation(minSdk = Build.VERSION_CODES.S) 1421 protected boolean isDataEnabledForReason(@TelephonyManager.DataEnabledReason int reason) { 1422 checkReadPhoneStatePermission(); 1423 return !dataDisabledReasons.contains(reason); 1424 } 1425 1426 /** 1427 * Implementation for {@link TelephonyManager#setDataEnabled}. Marked as public in order to allow 1428 * it to be used as a test API. 1429 */ 1430 @Implementation(minSdk = Build.VERSION_CODES.O) 1431 public void setDataEnabled(boolean enabled) { 1432 setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER, enabled); 1433 } 1434 1435 /** 1436 * Implementation for {@link TelephonyManager#setDataEnabledForReason}. Marked as public in order 1437 * to allow it to be used as a test API. 1438 */ 1439 @Implementation(minSdk = Build.VERSION_CODES.S) 1440 public void setDataEnabledForReason( 1441 @TelephonyManager.DataEnabledReason int reason, boolean enabled) { 1442 if (enabled) { 1443 dataDisabledReasons.remove(reason); 1444 } else { 1445 dataDisabledReasons.add(reason); 1446 } 1447 dataEnabled = dataDisabledReasons.isEmpty(); 1448 } 1449 1450 /** 1451 * Implementation for {@link TelephonyManager#isRttSupported}. 1452 * 1453 * @return False by default, unless set with {@link #setRttSupported(boolean)}. 1454 */ 1455 @Implementation(minSdk = Build.VERSION_CODES.Q) 1456 protected boolean isRttSupported() { 1457 return isRttSupported; 1458 } 1459 1460 /** Sets the value to be returned by {@link #isRttSupported()} */ 1461 public void setRttSupported(boolean isRttSupported) { 1462 this.isRttSupported = isRttSupported; 1463 } 1464 1465 /** 1466 * Implementation for {@link TelephonyManager#isTtyModeSupported}. 1467 * 1468 * @return False by default, unless set with {@link #setTtyModeSupported(boolean)}. 1469 */ 1470 @Implementation(minSdk = Build.VERSION_CODES.M) 1471 protected boolean isTtyModeSupported() { 1472 checkReadPhoneStatePermission(); 1473 return isTtyModeSupported; 1474 } 1475 1476 /** Sets the value to be returned by {@link #isTtyModeSupported()} */ 1477 public void setTtyModeSupported(boolean isTtyModeSupported) { 1478 ShadowTelephonyManager.isTtyModeSupported = isTtyModeSupported; 1479 } 1480 1481 /** 1482 * @return False by default, unless set with {@link #setHasCarrierPrivileges(int, boolean)}. 1483 */ 1484 @Implementation(minSdk = Build.VERSION_CODES.N) 1485 @HiddenApi 1486 protected boolean hasCarrierPrivileges(int subId) { 1487 return subIdToHasCarrierPrivileges.getOrDefault(subId, false); 1488 } 1489 1490 public void setHasCarrierPrivileges(boolean hasCarrierPrivileges) { 1491 int subId = ReflectionHelpers.callInstanceMethod(realTelephonyManager, "getSubId"); 1492 setHasCarrierPrivileges(subId, hasCarrierPrivileges); 1493 } 1494 1495 /** Sets the {@code hasCarrierPrivileges} for the given {@code subId}. */ 1496 public void setHasCarrierPrivileges(int subId, boolean hasCarrierPrivileges) { 1497 subIdToHasCarrierPrivileges.put(subId, hasCarrierPrivileges); 1498 } 1499 1500 /** 1501 * Implementation for {@link TelephonyManager#sendDialerSpecialCode(String)}. 1502 * 1503 * @param inputCode special code to be sent. 1504 */ 1505 @Implementation(minSdk = O) 1506 public void sendDialerSpecialCode(String inputCode) { 1507 sentDialerSpecialCodes.add(inputCode); 1508 } 1509 1510 /** 1511 * Returns immutable list of special codes sent using {@link 1512 * TelephonyManager#sendDialerSpecialCode(String)}. Special codes contained in the list are in the 1513 * order they were sent. 1514 */ 1515 public List<String> getSentDialerSpecialCodes() { 1516 return ImmutableList.copyOf(sentDialerSpecialCodes); 1517 } 1518 1519 /** Sets the value to be returned by {@link #isHearingAidCompatibilitySupported()}. */ 1520 public void setHearingAidCompatibilitySupported(boolean isSupported) { 1521 hearingAidCompatibilitySupported = isSupported; 1522 } 1523 1524 /** 1525 * Implementation for {@link TelephonyManager#isHearingAidCompatibilitySupported()}. 1526 * 1527 * @return False by default, unless set with {@link 1528 * #setHearingAidCompatibilitySupported(boolean)}. 1529 */ 1530 @Implementation(minSdk = M) 1531 protected boolean isHearingAidCompatibilitySupported() { 1532 return hearingAidCompatibilitySupported; 1533 } 1534 1535 /** 1536 * Creates a {@link TelephonyDisplayInfo}. 1537 * 1538 * @param networkType The packet-switching cellular network type (see {@link NetworkType}) 1539 * @param overrideNetworkType The override network type (see {@link OverrideNetworkType}) 1540 */ 1541 public static Object createTelephonyDisplayInfo( 1542 @NetworkType int networkType, @OverrideNetworkType int overrideNetworkType) { 1543 return new TelephonyDisplayInfo(networkType, overrideNetworkType); 1544 } 1545 1546 /** 1547 * Sets the current {@link TelephonyDisplayInfo}, and notifies all the {@link PhoneStateListener}s 1548 * that were registered with the {@link PhoneStateListener#LISTEN_DISPLAY_INFO_CHANGED} flag. 1549 * 1550 * @param telephonyDisplayInfo The {@link TelephonyDisplayInfo} to set. May not be null. 1551 * @throws NullPointerException if telephonyDisplayInfo is null. 1552 */ 1553 public void setTelephonyDisplayInfo(Object telephonyDisplayInfo) { 1554 Preconditions.checkNotNull(telephonyDisplayInfo); 1555 this.telephonyDisplayInfo = telephonyDisplayInfo; 1556 1557 for (PhoneStateListener listener : 1558 getListenersForFlags(PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)) { 1559 listener.onDisplayInfoChanged((TelephonyDisplayInfo) telephonyDisplayInfo); 1560 } 1561 if (VERSION.SDK_INT >= S) { 1562 for (DisplayInfoListener listener : getCallbackForListener(DisplayInfoListener.class)) { 1563 listener.onDisplayInfoChanged((TelephonyDisplayInfo) telephonyDisplayInfo); 1564 } 1565 } 1566 } 1567 1568 @Implementation(minSdk = R) 1569 @HiddenApi 1570 protected boolean isDataConnectionAllowed() { 1571 checkReadPhoneStatePermission(); 1572 return isDataConnectionAllowed; 1573 } 1574 1575 public void setIsDataConnectionAllowed(boolean isDataConnectionAllowed) { 1576 this.isDataConnectionAllowed = isDataConnectionAllowed; 1577 } 1578 1579 @Implementation(minSdk = O) 1580 public void sendVisualVoicemailSms( 1581 String number, int port, String text, PendingIntent sentIntent) { 1582 lastVisualVoicemailSmsParams = new VisualVoicemailSmsParams(number, port, text, sentIntent); 1583 } 1584 1585 public VisualVoicemailSmsParams getLastSentVisualVoicemailSmsParams() { 1586 return lastVisualVoicemailSmsParams; 1587 } 1588 1589 /** 1590 * Implementation for {@link 1591 * TelephonyManager#setVisualVoicemailSmsFilterSettings(VisualVoicemailSmsFilterSettings)}. 1592 * 1593 * @param settings The settings for the filter, or null to disable the filter. 1594 */ 1595 @Implementation(minSdk = O) 1596 public void setVisualVoicemailSmsFilterSettings(VisualVoicemailSmsFilterSettings settings) { 1597 visualVoicemailSmsFilterSettings = settings; 1598 } 1599 1600 /** Returns the last set {@link VisualVoicemailSmsFilterSettings}. */ 1601 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings() { 1602 return visualVoicemailSmsFilterSettings; 1603 } 1604 1605 /** Testable parameters from calls to {@link #sendVisualVoicemailSms}. */ 1606 public static class VisualVoicemailSmsParams { 1607 private final String destinationAddress; 1608 private final int port; 1609 private final String text; 1610 private final PendingIntent sentIntent; 1611 1612 public VisualVoicemailSmsParams( 1613 String destinationAddress, int port, String text, PendingIntent sentIntent) { 1614 this.destinationAddress = destinationAddress; 1615 this.port = port; 1616 this.text = text; 1617 this.sentIntent = sentIntent; 1618 } 1619 1620 public String getDestinationAddress() { 1621 return destinationAddress; 1622 } 1623 1624 public int getPort() { 1625 return port; 1626 } 1627 1628 public String getText() { 1629 return text; 1630 } 1631 1632 public PendingIntent getSentIntent() { 1633 return sentIntent; 1634 } 1635 } 1636 1637 /** 1638 * Sets the emergency numbers list returned by {@link TelephonyManager#getEmergencyNumberList}. 1639 */ 1640 public static void setEmergencyNumberList( 1641 Map<Integer, List<EmergencyNumber>> emergencyNumbersList) { 1642 ShadowTelephonyManager.emergencyNumbersList = emergencyNumbersList; 1643 } 1644 1645 /** 1646 * Implementation for {@link TelephonyManager#getEmergencyNumberList}. 1647 * 1648 * @return an immutable map by default, unless set with {@link #setEmergencyNumberList}. 1649 */ 1650 @Implementation(minSdk = R) 1651 protected Map<Integer, List<EmergencyNumber>> getEmergencyNumberList() { 1652 if (ShadowTelephonyManager.emergencyNumbersList != null) { 1653 return ShadowTelephonyManager.emergencyNumbersList; 1654 } 1655 return ImmutableMap.of(); 1656 } 1657 1658 /** 1659 * Implementation for {@link TelephonyManager#isDataRoamingEnabled}. 1660 * 1661 * @return False by default, unless set with {@link #setDataRoamingEnabled(boolean)}. 1662 */ 1663 @Implementation(minSdk = Q) 1664 protected boolean isDataRoamingEnabled() { 1665 checkReadPhoneStatePermission(); 1666 return isDataRoamingEnabled; 1667 } 1668 1669 /** Sets the value to be returned by {@link #isDataRoamingEnabled()} */ 1670 @Implementation(minSdk = Q) 1671 protected void setDataRoamingEnabled(boolean isDataRoamingEnabled) { 1672 ShadowTelephonyManager.isDataRoamingEnabled = isDataRoamingEnabled; 1673 } 1674 1675 /** 1676 * Sets the value to be returned by {@link #getCarrierRestrictionRules()}. Marked as public in 1677 * order to allow it to be used as a test API. 1678 * 1679 * @param carrierRestrictionRules An object of type {@link CarrierRestrictionRules} 1680 */ 1681 public void setCarrierRestrictionRules(Object carrierRestrictionRules) { 1682 Preconditions.checkState(carrierRestrictionRules instanceof CarrierRestrictionRules); 1683 this.carrierRestrictionRules = carrierRestrictionRules; 1684 } 1685 1686 /** 1687 * Implementation for {@link TelephonyManager#getCarrierRestrictionRules} that is set for tests by 1688 * {@link TelephonyManager#setCarrierRestrictionRules}. 1689 */ 1690 @Implementation(minSdk = Build.VERSION_CODES.Q) 1691 protected /*CarrierRestrictionRules*/ Object getCarrierRestrictionRules() { 1692 return carrierRestrictionRules; 1693 } 1694 1695 /** Implementation for {@link TelephonyManager#rebootModem} */ 1696 @Implementation(minSdk = Build.VERSION_CODES.TIRAMISU) 1697 protected void rebootModem() { 1698 checkModifyPhoneStatePermission(); 1699 modemRebootCount.incrementAndGet(); 1700 } 1701 1702 public int getModemRebootCount() { 1703 return modemRebootCount.get(); 1704 } 1705 } 1706