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