• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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