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