• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.BroadcastOptions;
22 import android.compat.annotation.UnsupportedAppUsage;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.SharedPreferences;
26 import android.net.LinkProperties;
27 import android.net.NetworkCapabilities;
28 import android.net.Uri;
29 import android.os.AsyncResult;
30 import android.os.Handler;
31 import android.os.Looper;
32 import android.os.Message;
33 import android.os.PersistableBundle;
34 import android.os.Registrant;
35 import android.os.RegistrantList;
36 import android.os.SystemClock;
37 import android.os.SystemProperties;
38 import android.os.WorkSource;
39 import android.preference.PreferenceManager;
40 import android.sysprop.TelephonyProperties;
41 import android.telecom.VideoProfile;
42 import android.telephony.AccessNetworkConstants;
43 import android.telephony.Annotation.ApnType;
44 import android.telephony.Annotation.DataFailureCause;
45 import android.telephony.CarrierConfigManager;
46 import android.telephony.CarrierRestrictionRules;
47 import android.telephony.CellIdentity;
48 import android.telephony.CellInfo;
49 import android.telephony.ClientRequestStats;
50 import android.telephony.ImsiEncryptionInfo;
51 import android.telephony.PhoneStateListener;
52 import android.telephony.PhysicalChannelConfig;
53 import android.telephony.PreciseDataConnectionState;
54 import android.telephony.RadioAccessFamily;
55 import android.telephony.RadioAccessSpecifier;
56 import android.telephony.ServiceState;
57 import android.telephony.SignalStrength;
58 import android.telephony.SubscriptionManager;
59 import android.telephony.TelephonyDisplayInfo;
60 import android.telephony.TelephonyManager;
61 import android.telephony.data.ApnSetting;
62 import android.telephony.emergency.EmergencyNumber;
63 import android.telephony.ims.RegistrationManager;
64 import android.telephony.ims.stub.ImsRegistrationImplBase;
65 import android.text.TextUtils;
66 import android.util.LocalLog;
67 import android.util.SparseArray;
68 
69 import com.android.ims.ImsCall;
70 import com.android.ims.ImsConfig;
71 import com.android.ims.ImsException;
72 import com.android.ims.ImsManager;
73 import com.android.internal.R;
74 import com.android.internal.annotations.VisibleForTesting;
75 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
76 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
77 import com.android.internal.telephony.dataconnection.DcTracker;
78 import com.android.internal.telephony.dataconnection.TransportManager;
79 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
80 import com.android.internal.telephony.imsphone.ImsPhoneCall;
81 import com.android.internal.telephony.metrics.VoiceCallSessionStats;
82 import com.android.internal.telephony.test.SimulatedRadioControl;
83 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
84 import com.android.internal.telephony.uicc.IccFileHandler;
85 import com.android.internal.telephony.uicc.IccRecords;
86 import com.android.internal.telephony.uicc.IsimRecords;
87 import com.android.internal.telephony.uicc.UiccCard;
88 import com.android.internal.telephony.uicc.UiccCardApplication;
89 import com.android.internal.telephony.uicc.UiccController;
90 import com.android.internal.telephony.uicc.UsimServiceTable;
91 import com.android.internal.telephony.util.TelephonyUtils;
92 import com.android.telephony.Rlog;
93 
94 import java.io.FileDescriptor;
95 import java.io.PrintWriter;
96 import java.util.ArrayList;
97 import java.util.Arrays;
98 import java.util.HashMap;
99 import java.util.HashSet;
100 import java.util.List;
101 import java.util.Locale;
102 import java.util.Map;
103 import java.util.Set;
104 import java.util.concurrent.atomic.AtomicReference;
105 import java.util.function.Consumer;
106 
107 /**
108  * (<em>Not for SDK use</em>)
109  * A base implementation for the com.android.internal.telephony.Phone interface.
110  *
111  * Note that implementations of Phone.java are expected to be used
112  * from a single application thread. This should be the same thread that
113  * originally called PhoneFactory to obtain the interface.
114  *
115  *  {@hide}
116  *
117  */
118 
119 public abstract class Phone extends Handler implements PhoneInternalInterface {
120     private static final String LOG_TAG = "Phone";
121 
122     protected final static Object lockForRadioTechnologyChange = new Object();
123 
124     protected final int USSD_MAX_QUEUE = 10;
125 
126     // Key used to read and write the saved network selection numeric value
127     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
128     // Key used to read and write the saved network selection operator name
129     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
130     // Key used to read and write the saved network selection operator short name
131     public static final String NETWORK_SELECTION_SHORT_KEY = "network_selection_short_key";
132 
133 
134     // Key used to read/write "disable data connection on boot" pref (used for testing)
135     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
136 
137     // Key used to read/write data_roaming_is_user_setting pref
138     public static final String DATA_ROAMING_IS_USER_SETTING_KEY = "data_roaming_is_user_setting_key";
139 
140     // Default value when there has been no last emergency SMS time recorded yet.
141     private static final int EMERGENCY_SMS_NO_TIME_RECORDED = -1;
142     // The max timer value that the platform can be in emergency SMS mode (5 minutes).
143     private static final int EMERGENCY_SMS_TIMER_MAX_MS = 300000;
144 
145     /* Event Constants */
146     protected static final int EVENT_RADIO_AVAILABLE             = 1;
147     /** Supplementary Service Notification received. */
148     protected static final int EVENT_SSN                         = 2;
149     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
150     private static final int EVENT_MMI_DONE                      = 4;
151     protected static final int EVENT_RADIO_ON                    = 5;
152     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
153     protected static final int EVENT_USSD                        = 7;
154     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
155     protected static final int EVENT_GET_IMEI_DONE               = 9;
156     protected static final int EVENT_GET_IMEISV_DONE             = 10;
157     private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
158     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
159     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
160     protected static final int EVENT_CALL_RING                   = 14;
161     private static final int EVENT_CALL_RING_CONTINUE            = 15;
162 
163     // Used to intercept the carrier selection calls so that
164     // we can save the values.
165     private static final int EVENT_SET_NETWORK_MANUAL_COMPLETE      = 16;
166     private static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE   = 17;
167     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
168     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
169     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
170     // Events for CDMA support
171     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
172     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
173     protected static final int EVENT_NV_READY                       = 23;
174     private static final int EVENT_SET_ENHANCED_VP                  = 24;
175     @VisibleForTesting
176     public static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
177     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
178     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
179     // other
180     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
181     protected static final int EVENT_ICC_RECORD_EVENTS              = 29;
182     @VisibleForTesting
183     protected static final int EVENT_ICC_CHANGED                    = 30;
184     // Single Radio Voice Call Continuity
185     @VisibleForTesting
186     protected static final int EVENT_SRVCC_STATE_CHANGED             = 31;
187     private static final int EVENT_INITIATE_SILENT_REDIAL           = 32;
188     private static final int EVENT_RADIO_NOT_AVAILABLE              = 33;
189     private static final int EVENT_UNSOL_OEM_HOOK_RAW               = 34;
190     protected static final int EVENT_GET_RADIO_CAPABILITY           = 35;
191     protected static final int EVENT_SS                             = 36;
192     private static final int EVENT_CONFIG_LCE                       = 37;
193     private static final int EVENT_CHECK_FOR_NETWORK_AUTOMATIC      = 38;
194     protected static final int EVENT_VOICE_RADIO_TECH_CHANGED       = 39;
195     protected static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE  = 40;
196     protected static final int EVENT_RIL_CONNECTED                  = 41;
197     protected static final int EVENT_UPDATE_PHONE_OBJECT            = 42;
198     protected static final int EVENT_CARRIER_CONFIG_CHANGED         = 43;
199     // Carrier's CDMA prefer mode setting
200     protected static final int EVENT_SET_ROAMING_PREFERENCE_DONE    = 44;
201     protected static final int EVENT_MODEM_RESET                    = 45;
202     protected static final int EVENT_VRS_OR_RAT_CHANGED             = 46;
203     // Radio state change
204     protected static final int EVENT_RADIO_STATE_CHANGED            = 47;
205     protected static final int EVENT_SET_CARRIER_DATA_ENABLED       = 48;
206     protected static final int EVENT_DEVICE_PROVISIONED_CHANGE      = 49;
207     protected static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = 50;
208     protected static final int EVENT_GET_AVAILABLE_NETWORKS_DONE    = 51;
209 
210     private static final int EVENT_ALL_DATA_DISCONNECTED                  = 52;
211     protected static final int EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED  = 53;
212     protected static final int EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED = 54;
213     protected static final int EVENT_GET_UICC_APPS_ENABLEMENT_DONE        = 55;
214     protected static final int EVENT_REAPPLY_UICC_APPS_ENABLEMENT_DONE    = 56;
215     protected static final int EVENT_REGISTRATION_FAILED = 57;
216     protected static final int EVENT_BARRING_INFO_CHANGED = 58;
217 
218     protected static final int EVENT_LAST = EVENT_BARRING_INFO_CHANGED;
219 
220     // For shared prefs.
221     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
222     private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_";
223     private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_";
224     private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_";
225 
226     // Key used to read/write current CLIR setting
227     public static final String CLIR_KEY = "clir_sub_key";
228 
229     // Key used for storing voice mail count
230     private static final String VM_COUNT = "vm_count_key";
231     // Key used to read/write the ID for storing the voice mail
232     private static final String VM_ID = "vm_id_key";
233 
234     // Key used for storing call forwarding status
235     public static final String CF_STATUS = "cf_status_key";
236     // Key used to read/write the ID for storing the call forwarding status
237     public static final String CF_ID = "cf_id_key";
238 
239     // Key used to read/write "disable DNS server check" pref (used for testing)
240     private static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
241 
242     // Integer used to let the calling application know that the we are ignoring auto mode switch.
243     private static final int ALREADY_IN_AUTO_SELECTION = 1;
244 
245     /**
246      * This method is invoked when the Phone exits Emergency Callback Mode.
247      */
handleExitEmergencyCallbackMode()248     protected void handleExitEmergencyCallbackMode() {
249     }
250 
251     /**
252      * Small container class used to hold information relevant to
253      * the carrier selection process. operatorNumeric can be ""
254      * if we are looking for automatic selection. operatorAlphaLong is the
255      * corresponding operator name.
256      */
257     protected static class NetworkSelectMessage {
258         public Message message;
259         public String operatorNumeric;
260         public String operatorAlphaLong;
261         public String operatorAlphaShort;
262     }
263 
264     public static class SilentRedialParam {
265         public String dialString;
266         public int causeCode;
267         public DialArgs dialArgs;
268 
SilentRedialParam(String dialString, int causeCode, DialArgs dialArgs)269         public SilentRedialParam(String dialString, int causeCode, DialArgs dialArgs) {
270             this.dialString = dialString;
271             this.causeCode = causeCode;
272             this.dialArgs = dialArgs;
273         }
274     }
275 
276     /* Instance Variables */
277     @UnsupportedAppUsage
278     public CommandsInterface mCi;
279     protected int mVmCount = 0;
280     private boolean mDnsCheckDisabled;
281     // Data connection trackers. For each transport type (e.g. WWAN, WLAN), there will be a
282     // corresponding DcTracker. The WWAN DcTracker is for cellular data connections while
283     // WLAN DcTracker is for IWLAN data connection. For IWLAN legacy mode, only one (WWAN) DcTracker
284     // will be created.
285     protected final SparseArray<DcTracker> mDcTrackers = new SparseArray<>();
286     /* Used for dispatching signals to configured carrier apps */
287     protected CarrierSignalAgent mCarrierSignalAgent;
288     /* Used for dispatching carrier action from carrier apps */
289     protected CarrierActionAgent mCarrierActionAgent;
290     private boolean mDoesRilSendMultipleCallRing;
291     private int mCallRingContinueToken;
292     private int mCallRingDelay;
293     private boolean mIsVoiceCapable = true;
294     private final AppSmsManager mAppSmsManager;
295     private SimActivationTracker mSimActivationTracker;
296     // Keep track of whether or not the phone is in Emergency Callback Mode for Phone and
297     // subclasses
298     protected boolean mIsPhoneInEcmState = false;
299     // Keep track of the case where ECM was cancelled to place another outgoing emergency call.
300     // We will need to restart it after the emergency call ends.
301     protected boolean mEcmCanceledForEmergency = false;
302     private volatile long mTimeLastEmergencySmsSentMs = EMERGENCY_SMS_NO_TIME_RECORDED;
303 
304     // Variable to cache the video capability. When RAT changes, we lose this info and are unable
305     // to recover from the state. We cache it and notify listeners when they register.
306     protected boolean mIsVideoCapable = false;
307     @UnsupportedAppUsage
308     protected UiccController mUiccController = null;
309     @UnsupportedAppUsage
310     protected final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
311     @UnsupportedAppUsage
312     public SmsStorageMonitor mSmsStorageMonitor;
313     public SmsUsageMonitor mSmsUsageMonitor;
314     @UnsupportedAppUsage
315     protected AtomicReference<UiccCardApplication> mUiccApplication =
316             new AtomicReference<UiccCardApplication>();
317     TelephonyTester mTelephonyTester;
318     private String mName;
319     private final String mActionDetached;
320     private final String mActionAttached;
321     protected DeviceStateMonitor mDeviceStateMonitor;
322     protected DisplayInfoController mDisplayInfoController;
323     protected TransportManager mTransportManager;
324     protected DataEnabledSettings mDataEnabledSettings;
325     // Used for identify the carrier of current subscription
326     protected CarrierResolver mCarrierResolver;
327 
328     @UnsupportedAppUsage
329     protected int mPhoneId;
330 
331     @UnsupportedAppUsage
332     protected Phone mImsPhone = null;
333 
334     private final AtomicReference<RadioCapability> mRadioCapability =
335             new AtomicReference<RadioCapability>();
336 
337     private static final int DEFAULT_REPORT_INTERVAL_MS = 200;
338     private static final boolean LCE_PULL_MODE = true;
339     private int mLceStatus = RILConstants.LCE_NOT_AVAILABLE;
340     protected TelephonyComponentFactory mTelephonyComponentFactory;
341 
342     //IMS
343     /**
344      * {@link CallStateException} message text used to indicate that an IMS call has failed because
345      * it needs to be retried using GSM or CDMA (e.g. CS fallback).
346      * TODO: Replace this with a proper exception; {@link CallStateException} doesn't make sense.
347      */
348     public static final String CS_FALLBACK = "cs_fallback";
349     /**
350      * @deprecated Use {@link android.telephony.ims.ImsManager#EXTRA_WFC_REGISTRATION_FAILURE_TITLE}
351      * instead.
352      */
353     @Deprecated
354     public static final String EXTRA_KEY_ALERT_TITLE =
355             android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_TITLE;
356     /**
357      * @deprecated Use
358      * {@link android.telephony.ims.ImsManager#EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE} instead.
359      */
360     @Deprecated
361     public static final String EXTRA_KEY_ALERT_MESSAGE =
362             android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE;
363     public static final String EXTRA_KEY_ALERT_SHOW = "alertShow";
364     public static final String EXTRA_KEY_NOTIFICATION_MESSAGE = "notificationMessage";
365 
366     private final RegistrantList mPreciseCallStateRegistrants = new RegistrantList();
367 
368     private final RegistrantList mHandoverRegistrants = new RegistrantList();
369 
370     private final RegistrantList mNewRingingConnectionRegistrants = new RegistrantList();
371 
372     private final RegistrantList mIncomingRingRegistrants = new RegistrantList();
373 
374     protected final RegistrantList mDisconnectRegistrants = new RegistrantList();
375 
376     private final RegistrantList mServiceStateRegistrants = new RegistrantList();
377 
378     protected final RegistrantList mMmiCompleteRegistrants = new RegistrantList();
379 
380     @UnsupportedAppUsage
381     protected final RegistrantList mMmiRegistrants = new RegistrantList();
382 
383     protected final RegistrantList mUnknownConnectionRegistrants = new RegistrantList();
384 
385     protected final RegistrantList mSuppServiceFailedRegistrants = new RegistrantList();
386 
387     protected final RegistrantList mRadioOffOrNotAvailableRegistrants = new RegistrantList();
388 
389     protected final RegistrantList mSimRecordsLoadedRegistrants = new RegistrantList();
390 
391     private final RegistrantList mVideoCapabilityChangedRegistrants = new RegistrantList();
392 
393     protected final RegistrantList mEmergencyCallToggledRegistrants = new RegistrantList();
394 
395     private final RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
396 
397     private final RegistrantList mCellInfoRegistrants = new RegistrantList();
398 
399     private final RegistrantList mRedialRegistrants = new RegistrantList();
400 
401     private final RegistrantList mPhysicalChannelConfigRegistrants = new RegistrantList();
402 
403     private final RegistrantList mOtaspRegistrants = new RegistrantList();
404 
405     private final RegistrantList mPreferredNetworkTypeRegistrants = new RegistrantList();
406 
407     protected Registrant mPostDialHandler;
408 
409     protected final LocalLog mLocalLog;
410 
411     private Looper mLooper; /* to insure registrants are in correct thread*/
412 
413     @UnsupportedAppUsage
414     protected final Context mContext;
415 
416     /**
417      * PhoneNotifier is an abstraction for all system-wide
418      * state change notification. DefaultPhoneNotifier is
419      * used here unless running we're inside a unit test.
420      */
421     @UnsupportedAppUsage
422     protected PhoneNotifier mNotifier;
423 
424     protected SimulatedRadioControl mSimulatedRadioControl;
425 
426     private boolean mUnitTestMode;
427     private Map<Integer, Long> mAllowedNetworkTypesForReasons = new HashMap<>();
428     private final CarrierPrivilegesTracker mCarrierPrivilegesTracker;
429 
430     protected VoiceCallSessionStats mVoiceCallSessionStats;
431 
getIccRecords()432     public IccRecords getIccRecords() {
433         return mIccRecords.get();
434     }
435 
436     /**
437      * Returns a string identifier for this phone interface for parties
438      *  outside the phone app process.
439      *  @return The string name.
440      */
441     @UnsupportedAppUsage
getPhoneName()442     public String getPhoneName() {
443         return mName;
444     }
445 
setPhoneName(String name)446     protected void setPhoneName(String name) {
447         mName = name;
448     }
449 
450     /**
451      * Retrieves Nai for phones. Returns null if Nai is not set.
452      */
453     @UnsupportedAppUsage
getNai()454     public String getNai(){
455          return null;
456     }
457 
458     /**
459      * Return the ActionDetached string. When this action is received by components
460      * they are to simulate detaching from the network.
461      *
462      * @return com.android.internal.telephony.{mName}.action_detached
463      *          {mName} is GSM, CDMA ...
464      */
getActionDetached()465     public String getActionDetached() {
466         return mActionDetached;
467     }
468 
469     /**
470      * Return the ActionAttached string. When this action is received by components
471      * they are to simulate attaching to the network.
472      *
473      * @return com.android.internal.telephony.{mName}.action_detached
474      *          {mName} is GSM, CDMA ...
475      */
getActionAttached()476     public String getActionAttached() {
477         return mActionAttached;
478     }
479 
480     /**
481      * Set a system property, unless we're in unit test mode
482      */
483     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
484     @UnsupportedAppUsage
getSystemProperty(String property, String defValue)485     public String getSystemProperty(String property, String defValue) {
486         if(getUnitTestMode()) {
487             return null;
488         }
489         return SystemProperties.get(property, defValue);
490     }
491 
492     /**
493      * Constructs a Phone in normal (non-unit test) mode.
494      *
495      * @param notifier An instance of DefaultPhoneNotifier,
496      * @param context Context object from hosting application
497      * unless unit testing.
498      * @param ci is CommandsInterface
499      * @param unitTestMode when true, prevents notifications
500      * of state change events
501      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode)502     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
503                     boolean unitTestMode) {
504         this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX,
505                 TelephonyComponentFactory.getInstance());
506     }
507 
508     /**
509      * Constructs a Phone in normal (non-unit test) mode.
510      *
511      * @param notifier An instance of DefaultPhoneNotifier,
512      * @param context Context object from hosting application
513      * unless unit testing.
514      * @param ci is CommandsInterface
515      * @param unitTestMode when true, prevents notifications
516      * of state change events
517      * @param phoneId the phone-id of this phone.
518      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode, int phoneId, TelephonyComponentFactory telephonyComponentFactory)519     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
520                     boolean unitTestMode, int phoneId,
521                     TelephonyComponentFactory telephonyComponentFactory) {
522         mPhoneId = phoneId;
523         mName = name;
524         mNotifier = notifier;
525         mContext = context;
526         mLooper = Looper.myLooper();
527         mCi = ci;
528         mActionDetached = this.getClass().getPackage().getName() + ".action_detached";
529         mActionAttached = this.getClass().getPackage().getName() + ".action_attached";
530         mAppSmsManager = telephonyComponentFactory.inject(AppSmsManager.class.getName())
531                 .makeAppSmsManager(context);
532         mLocalLog = new LocalLog(64);
533 
534         if (TelephonyUtils.IS_DEBUGGABLE) {
535             mTelephonyTester = new TelephonyTester(this);
536         }
537 
538         setUnitTestMode(unitTestMode);
539 
540         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
541         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
542         mCi.setOnCallRing(this, EVENT_CALL_RING, null);
543 
544         /* "Voice capable" means that this device supports circuit-switched
545         * (i.e. voice) phone calls over the telephony network, and is allowed
546         * to display the in-call UI while a cellular voice call is active.
547         * This will be false on "data only" devices which can't make voice
548         * calls and don't support any in-call UI.
549         */
550         mIsVoiceCapable = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
551                 .isVoiceCapable();
552 
553         mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(mLooper, this, mContext);
554 
555         /**
556          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
557          *  to be generated locally. Ideally all ring tones should be loops
558          * and this wouldn't be necessary. But to minimize changes to upper
559          * layers it is requested that it be generated by lower layers.
560          *
561          * By default old phones won't have the property set but do generate
562          * the RIL_UNSOL_CALL_RING so the default if there is no property is
563          * true.
564          */
565         mDoesRilSendMultipleCallRing = TelephonyProperties.ril_sends_multiple_call_ring()
566                 .orElse(true);
567         Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
568 
569         mCallRingDelay = TelephonyProperties.call_ring_delay().orElse(3000);
570         Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
571 
572         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
573             return;
574         }
575 
576         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
577         mTelephonyComponentFactory = telephonyComponentFactory;
578         mSmsStorageMonitor = mTelephonyComponentFactory.inject(SmsStorageMonitor.class.getName())
579                 .makeSmsStorageMonitor(this);
580         mSmsUsageMonitor = mTelephonyComponentFactory.inject(SmsUsageMonitor.class.getName())
581                 .makeSmsUsageMonitor(context);
582         mUiccController = UiccController.getInstance();
583         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
584         mSimActivationTracker = mTelephonyComponentFactory
585                 .inject(SimActivationTracker.class.getName())
586                 .makeSimActivationTracker(this);
587         if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
588             mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
589         }
590         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
591                 obtainMessage(EVENT_CONFIG_LCE));
592     }
593 
594     /**
595      * Start setup of ImsPhone, which will start trying to connect to the ImsResolver. Will not be
596      * called if this device does not support FEATURE_IMS_TELEPHONY.
597      */
createImsPhone()598     public void createImsPhone() {
599         if (getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
600             return;
601         }
602 
603         synchronized(Phone.lockForRadioTechnologyChange) {
604             if (mImsPhone == null) {
605                 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
606                 CallManager.getInstance().registerPhone(mImsPhone);
607                 mImsPhone.registerForSilentRedial(
608                         this, EVENT_INITIATE_SILENT_REDIAL, null);
609             }
610         }
611     }
612 
613     /**
614      * Checks if device should convert CDMA Caller ID restriction related MMI codes to
615      * equivalent 3GPP MMI Codes that provide same functionality when device is roaming.
616      * This method should only return true on multi-mode devices when carrier requires this
617      * conversion to be done on the device.
618      *
619      * @return true when carrier config
620      * "KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL" is set to true
621      */
supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming()622     public boolean supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming() {
623         CarrierConfigManager configManager = (CarrierConfigManager)
624                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
625         PersistableBundle b = configManager.getConfigForSubId(getSubId());
626         if (b != null) {
627             return b.getBoolean(
628                     CarrierConfigManager
629                             .KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL,
630                     false);
631         } else {
632             // Default value set in CarrierConfigManager
633             return false;
634         }
635     }
636 
637     /**
638      * Check if sending CLIR activation("*31#") and deactivation("#31#") code only without dialing
639      * number is prevented.
640      *
641      * @return {@code true} when carrier config
642      * "KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL" is set to {@code true}
643      */
isClirActivationAndDeactivationPrevented()644     public boolean isClirActivationAndDeactivationPrevented() {
645         CarrierConfigManager configManager = (CarrierConfigManager)
646                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
647         PersistableBundle b = configManager.getConfigForSubId(getSubId());
648         if (b == null) {
649             b = CarrierConfigManager.getDefaultConfig();
650         }
651         return b.getBoolean(
652                 CarrierConfigManager.KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL);
653     }
654 
655     /**
656      * When overridden the derived class needs to call
657      * super.handleMessage(msg) so this method has a
658      * a chance to process the message.
659      *
660      * @param msg
661      */
662     @Override
handleMessage(Message msg)663     public void handleMessage(Message msg) {
664         AsyncResult ar;
665 
666         // messages to be handled whether or not the phone is being destroyed
667         // should only include messages which are being re-directed and do not use
668         // resources of the phone being destroyed
669         switch (msg.what) {
670             // handle the select network completion callbacks.
671             case EVENT_SET_NETWORK_MANUAL_COMPLETE:
672             case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
673                 handleSetSelectNetwork((AsyncResult) msg.obj);
674                 return;
675         }
676 
677         switch(msg.what) {
678             case EVENT_CALL_RING:
679                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
680                 ar = (AsyncResult)msg.obj;
681                 if (ar.exception == null) {
682                     PhoneConstants.State state = getState();
683                     if ((!mDoesRilSendMultipleCallRing)
684                             && ((state == PhoneConstants.State.RINGING) ||
685                                     (state == PhoneConstants.State.IDLE))) {
686                         mCallRingContinueToken += 1;
687                         sendIncomingCallRingNotification(mCallRingContinueToken);
688                     } else {
689                         notifyIncomingRing();
690                     }
691                 }
692                 break;
693 
694             case EVENT_CALL_RING_CONTINUE:
695                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received state=" + getState());
696                 if (getState() == PhoneConstants.State.RINGING) {
697                     sendIncomingCallRingNotification(msg.arg1);
698                 }
699                 break;
700 
701             case EVENT_ICC_CHANGED:
702                 onUpdateIccAvailability();
703                 break;
704 
705             case EVENT_INITIATE_SILENT_REDIAL:
706                 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
707                 ar = (AsyncResult) msg.obj;
708                 if ((ar.exception == null) && (ar.result != null)) {
709                     String dialString = (String) ar.result;
710                     if (TextUtils.isEmpty(dialString)) return;
711                     try {
712                         Connection cn = dialInternal(dialString, new DialArgs.Builder().build());
713                         Rlog.d(LOG_TAG, "Notify redial connection changed cn: " + cn);
714                         if (mImsPhone != null) {
715                             // Don't care it is null or not.
716                             mImsPhone.notifyRedialConnectionChanged(cn);
717                         }
718                     } catch (CallStateException e) {
719                         Rlog.e(LOG_TAG, "silent redial failed: " + e);
720                         if (mImsPhone != null) {
721                             mImsPhone.notifyRedialConnectionChanged(null);
722                         }
723                     }
724                 }
725                 break;
726 
727             case EVENT_SRVCC_STATE_CHANGED:
728                 ar = (AsyncResult)msg.obj;
729                 if (ar.exception == null) {
730                     handleSrvccStateChanged((int[]) ar.result);
731                 } else {
732                     Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception);
733                 }
734                 break;
735 
736             case EVENT_UNSOL_OEM_HOOK_RAW:
737                 // deprecated, ignore
738                 break;
739 
740             case EVENT_CONFIG_LCE:
741                 ar = (AsyncResult) msg.obj;
742                 if (ar.exception != null) {
743                     Rlog.d(LOG_TAG, "config LCE service failed: " + ar.exception);
744                 } else {
745                     final ArrayList<Integer> statusInfo = (ArrayList<Integer>)ar.result;
746                     mLceStatus = statusInfo.get(0);
747                 }
748                 break;
749 
750             case EVENT_CHECK_FOR_NETWORK_AUTOMATIC: {
751                 onCheckForNetworkSelectionModeAutomatic(msg);
752                 break;
753             }
754 
755             case EVENT_ALL_DATA_DISCONNECTED:
756                 if (areAllDataDisconnected()) {
757                     mAllDataDisconnectedRegistrants.notifyRegistrants();
758                 }
759                 break;
760             default:
761                 throw new RuntimeException("unexpected event not handled");
762         }
763     }
764 
getHandoverConnection()765     public ArrayList<Connection> getHandoverConnection() {
766         return null;
767     }
768 
notifySrvccState(Call.SrvccState state)769     public void notifySrvccState(Call.SrvccState state) {
770     }
771 
registerForSilentRedial(Handler h, int what, Object obj)772     public void registerForSilentRedial(Handler h, int what, Object obj) {
773     }
774 
unregisterForSilentRedial(Handler h)775     public void unregisterForSilentRedial(Handler h) {
776     }
777 
registerForVolteSilentRedial(Handler h, int what, Object obj)778     public void registerForVolteSilentRedial(Handler h, int what, Object obj) {
779     }
780 
unregisterForVolteSilentRedial(Handler h)781     public void unregisterForVolteSilentRedial(Handler h) {
782     }
783 
handleSrvccStateChanged(int[] ret)784     private void handleSrvccStateChanged(int[] ret) {
785         Rlog.d(LOG_TAG, "handleSrvccStateChanged");
786 
787         ArrayList<Connection> conn = null;
788         Phone imsPhone = mImsPhone;
789         Call.SrvccState srvccState = Call.SrvccState.NONE;
790         if (ret != null && ret.length != 0) {
791             int state = ret[0];
792             switch(state) {
793                 case TelephonyManager.SRVCC_STATE_HANDOVER_STARTED:
794                     srvccState = Call.SrvccState.STARTED;
795                     if (imsPhone != null) {
796                         conn = imsPhone.getHandoverConnection();
797                         migrateFrom(imsPhone);
798                     } else {
799                         Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null");
800                     }
801                     break;
802                 case TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED:
803                     srvccState = Call.SrvccState.COMPLETED;
804                     if (imsPhone != null) {
805                         imsPhone.notifySrvccState(srvccState);
806                     } else {
807                         Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null");
808                     }
809                     break;
810                 case TelephonyManager.SRVCC_STATE_HANDOVER_FAILED:
811                 case TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED:
812                     srvccState = Call.SrvccState.FAILED;
813                     break;
814 
815                 default:
816                     //ignore invalid state
817                     return;
818             }
819 
820             getCallTracker().notifySrvccState(srvccState, conn);
821 
822             notifySrvccStateChanged(state);
823         }
824     }
825 
826     /**
827      * Gets the context for the phone, as set at initialization time.
828      */
829     @UnsupportedAppUsage
getContext()830     public Context getContext() {
831         return mContext;
832     }
833 
834     // Will be called when icc changed
onUpdateIccAvailability()835     protected abstract void onUpdateIccAvailability();
836 
837     /**
838      * Disables the DNS check (i.e., allows "0.0.0.0").
839      * Useful for lab testing environment.
840      * @param b true disables the check, false enables.
841      */
disableDnsCheck(boolean b)842     public void disableDnsCheck(boolean b) {
843         mDnsCheckDisabled = b;
844         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
845         SharedPreferences.Editor editor = sp.edit();
846         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
847         editor.apply();
848     }
849 
850     /**
851      * Returns true if the DNS check is currently disabled.
852      */
isDnsCheckDisabled()853     public boolean isDnsCheckDisabled() {
854         return mDnsCheckDisabled;
855     }
856 
857     /**
858      * Register for getting notifications for change in the Call State {@link Call.State}
859      * This is called PreciseCallState because the call state is more precise than the
860      * {@link PhoneConstants.State} which can be obtained using the {@link PhoneStateListener}
861      *
862      * Resulting events will have an AsyncResult in <code>Message.obj</code>.
863      * AsyncResult.userData will be set to the obj argument here.
864      * The <em>h</em> parameter is held only by a weak reference.
865      */
866     @UnsupportedAppUsage
registerForPreciseCallStateChanged(Handler h, int what, Object obj)867     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
868         checkCorrectThread(h);
869 
870         mPreciseCallStateRegistrants.addUnique(h, what, obj);
871     }
872 
873     /**
874      * Unregisters for voice call state change notifications.
875      * Extraneous calls are tolerated silently.
876      */
877     @UnsupportedAppUsage
unregisterForPreciseCallStateChanged(Handler h)878     public void unregisterForPreciseCallStateChanged(Handler h) {
879         mPreciseCallStateRegistrants.remove(h);
880     }
881 
882     /**
883      * Subclasses of Phone probably want to replace this with a
884      * version scoped to their packages
885      */
notifyPreciseCallStateChangedP()886     protected void notifyPreciseCallStateChangedP() {
887         AsyncResult ar = new AsyncResult(null, this, null);
888         mPreciseCallStateRegistrants.notifyRegistrants(ar);
889 
890         mNotifier.notifyPreciseCallState(this);
891     }
892 
893     /**
894      * Notifies when a Handover happens due to SRVCC or Silent Redial
895      */
registerForHandoverStateChanged(Handler h, int what, Object obj)896     public void registerForHandoverStateChanged(Handler h, int what, Object obj) {
897         checkCorrectThread(h);
898         mHandoverRegistrants.addUnique(h, what, obj);
899     }
900 
901     /**
902      * Unregisters for handover state notifications
903      */
unregisterForHandoverStateChanged(Handler h)904     public void unregisterForHandoverStateChanged(Handler h) {
905         mHandoverRegistrants.remove(h);
906     }
907 
908     /**
909      * Subclasses of Phone probably want to replace this with a
910      * version scoped to their packages
911      */
notifyHandoverStateChanged(Connection cn)912     public void notifyHandoverStateChanged(Connection cn) {
913        AsyncResult ar = new AsyncResult(null, cn, null);
914        mHandoverRegistrants.notifyRegistrants(ar);
915     }
916 
917     /**
918      * Notifies when a Handover happens due to Silent Redial
919      */
registerForRedialConnectionChanged(Handler h, int what, Object obj)920     public void registerForRedialConnectionChanged(Handler h, int what, Object obj) {
921         checkCorrectThread(h);
922         mRedialRegistrants.addUnique(h, what, obj);
923     }
924 
925     /**
926      * Unregisters for redial connection notifications
927      */
unregisterForRedialConnectionChanged(Handler h)928     public void unregisterForRedialConnectionChanged(Handler h) {
929         mRedialRegistrants.remove(h);
930     }
931 
932     /**
933      * Subclasses of Phone probably want to replace this with a
934      * version scoped to their packages
935      */
notifyRedialConnectionChanged(Connection cn)936     public void notifyRedialConnectionChanged(Connection cn) {
937         AsyncResult ar = new AsyncResult(null, cn, null);
938         mRedialRegistrants.notifyRegistrants(ar);
939     }
940 
setIsInEmergencyCall()941     protected void setIsInEmergencyCall() {
942     }
943 
944     /**
945      * Notify the phone that an SMS has been sent. This will be used determine if the SMS was sent
946      * to an emergency address.
947      * @param destinationAddress the address that the SMS was sent to.
948      */
notifySmsSent(String destinationAddress)949     public void notifySmsSent(String destinationAddress) {
950         TelephonyManager m = (TelephonyManager) getContext().getSystemService(
951                 Context.TELEPHONY_SERVICE);
952         if (m != null && m.isEmergencyNumber(destinationAddress)) {
953             mLocalLog.log("Emergency SMS detected, recording time.");
954             mTimeLastEmergencySmsSentMs = SystemClock.elapsedRealtime();
955         }
956     }
957 
958     /**
959      * Determine if the Phone has recently sent an emergency SMS and is still in the interval of
960      * time defined by a carrier that we may need to do perform special actions, for example
961      * override user setting for location so the carrier can find the user's location for emergency
962      * services.
963      *
964      * @return true if the device is in emergency SMS mode, false otherwise.
965      */
isInEmergencySmsMode()966     public boolean isInEmergencySmsMode() {
967         long lastSmsTimeMs = mTimeLastEmergencySmsSentMs;
968         if (lastSmsTimeMs == EMERGENCY_SMS_NO_TIME_RECORDED) {
969             // an emergency SMS hasn't been sent since the last check.
970             return false;
971         }
972         CarrierConfigManager configManager = (CarrierConfigManager)
973                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
974         PersistableBundle b = configManager.getConfigForSubId(getSubId());
975         if (b == null) {
976             // default for KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT is 0 and CarrierConfig isn't
977             // available, so return false.
978             return false;
979         }
980         int eSmsTimerMs = b.getInt(CarrierConfigManager.KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0);
981         if (eSmsTimerMs == 0) {
982             // We do not support this feature for this carrier.
983             return false;
984         }
985         if (eSmsTimerMs > EMERGENCY_SMS_TIMER_MAX_MS) {
986             eSmsTimerMs = EMERGENCY_SMS_TIMER_MAX_MS;
987         }
988         boolean isInEmergencySmsMode = SystemClock.elapsedRealtime()
989                 <= (lastSmsTimeMs + eSmsTimerMs);
990         if (!isInEmergencySmsMode) {
991             // Shortcut this next time so we do not have to waste time if another emergency SMS
992             // hasn't been sent since the last query.
993             mTimeLastEmergencySmsSentMs = EMERGENCY_SMS_NO_TIME_RECORDED;
994         } else {
995             mLocalLog.log("isInEmergencySmsMode: queried while eSMS mode is active.");
996         }
997         return isInEmergencySmsMode;
998     }
999 
migrateFrom(Phone from)1000     protected void migrateFrom(Phone from) {
1001         migrate(mHandoverRegistrants, from.mHandoverRegistrants);
1002         migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
1003         migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
1004         migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
1005         migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
1006         migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
1007         migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
1008         migrate(mMmiRegistrants, from.mMmiRegistrants);
1009         migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
1010         migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
1011         migrate(mCellInfoRegistrants, from.mCellInfoRegistrants);
1012         migrate(mRedialRegistrants, from.mRedialRegistrants);
1013         // The emergency state of IMS phone will be cleared in ImsPhone#notifySrvccState after
1014         // receive SRVCC completed
1015         if (from.isInEmergencyCall()) {
1016             setIsInEmergencyCall();
1017         }
1018         setEcmCanceledForEmergency(from.isEcmCanceledForEmergency());
1019     }
1020 
migrate(RegistrantList to, RegistrantList from)1021     protected void migrate(RegistrantList to, RegistrantList from) {
1022         if (from == null) {
1023             // May be null in some cases, such as testing.
1024             return;
1025         }
1026         from.removeCleared();
1027         for (int i = 0, n = from.size(); i < n; i++) {
1028             Registrant r = (Registrant) from.get(i);
1029             Message msg = r.messageForRegistrant();
1030             // Since CallManager has already registered with both CS and IMS phones,
1031             // the migrate should happen only for those registrants which are not
1032             // registered with CallManager.Hence the below check is needed to add
1033             // only those registrants to the registrant list which are not
1034             // coming from the CallManager.
1035             if (msg != null) {
1036                 if (msg.obj == CallManager.getInstance().getRegistrantIdentifier()) {
1037                     continue;
1038                 } else {
1039                     to.add((Registrant) from.get(i));
1040                 }
1041             } else {
1042                 Rlog.d(LOG_TAG, "msg is null");
1043             }
1044         }
1045     }
1046 
1047     /**
1048      * Notifies when a previously untracked non-ringing/waiting connection has appeared.
1049      * This is likely due to some other entity (eg, SIM card application) initiating a call.
1050      */
1051     @UnsupportedAppUsage
registerForUnknownConnection(Handler h, int what, Object obj)1052     public void registerForUnknownConnection(Handler h, int what, Object obj) {
1053         checkCorrectThread(h);
1054 
1055         mUnknownConnectionRegistrants.addUnique(h, what, obj);
1056     }
1057 
1058     /**
1059      * Unregisters for unknown connection notifications.
1060      */
1061     @UnsupportedAppUsage
unregisterForUnknownConnection(Handler h)1062     public void unregisterForUnknownConnection(Handler h) {
1063         mUnknownConnectionRegistrants.remove(h);
1064     }
1065 
1066     /**
1067      * Notifies when a new ringing or waiting connection has appeared.<p>
1068      *
1069      *  Messages received from this:
1070      *  Message.obj will be an AsyncResult
1071      *  AsyncResult.userObj = obj
1072      *  AsyncResult.result = a Connection. <p>
1073      *  Please check Connection.isRinging() to make sure the Connection
1074      *  has not dropped since this message was posted.
1075      *  If Connection.isRinging() is true, then
1076      *   Connection.getCall() == Phone.getRingingCall()
1077      */
1078     @UnsupportedAppUsage
registerForNewRingingConnection( Handler h, int what, Object obj)1079     public void registerForNewRingingConnection(
1080             Handler h, int what, Object obj) {
1081         checkCorrectThread(h);
1082 
1083         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
1084     }
1085 
1086     /**
1087      * Unregisters for new ringing connection notification.
1088      * Extraneous calls are tolerated silently
1089      */
1090     @UnsupportedAppUsage
unregisterForNewRingingConnection(Handler h)1091     public void unregisterForNewRingingConnection(Handler h) {
1092         mNewRingingConnectionRegistrants.remove(h);
1093     }
1094 
1095     /**
1096      * Notifies when phone's video capabilities changes <p>
1097      *
1098      *  Messages received from this:
1099      *  Message.obj will be an AsyncResult
1100      *  AsyncResult.userObj = obj
1101      *  AsyncResult.result = true if phone supports video calling <p>
1102      */
registerForVideoCapabilityChanged( Handler h, int what, Object obj)1103     public void registerForVideoCapabilityChanged(
1104             Handler h, int what, Object obj) {
1105         checkCorrectThread(h);
1106 
1107         mVideoCapabilityChangedRegistrants.addUnique(h, what, obj);
1108 
1109         // Notify any registrants of the cached video capability as soon as they register.
1110         notifyForVideoCapabilityChanged(mIsVideoCapable);
1111     }
1112 
1113     /**
1114      * Unregisters for video capability changed notification.
1115      * Extraneous calls are tolerated silently
1116      */
unregisterForVideoCapabilityChanged(Handler h)1117     public void unregisterForVideoCapabilityChanged(Handler h) {
1118         mVideoCapabilityChangedRegistrants.remove(h);
1119     }
1120 
1121     /**
1122      * Register for notifications when a sInCall VoicePrivacy is enabled
1123      *
1124      * @param h Handler that receives the notification message.
1125      * @param what User-defined message code.
1126      * @param obj User object.
1127      */
registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)1128     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
1129         mCi.registerForInCallVoicePrivacyOn(h, what, obj);
1130     }
1131 
1132     /**
1133      * Unegister for notifications when a sInCall VoicePrivacy is enabled
1134      *
1135      * @param h Handler to be removed from the registrant list.
1136      */
unregisterForInCallVoicePrivacyOn(Handler h)1137     public void unregisterForInCallVoicePrivacyOn(Handler h){
1138         mCi.unregisterForInCallVoicePrivacyOn(h);
1139     }
1140 
1141     /**
1142      * Register for notifications when a sInCall VoicePrivacy is disabled
1143      *
1144      * @param h Handler that receives the notification message.
1145      * @param what User-defined message code.
1146      * @param obj User object.
1147      */
registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)1148     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
1149         mCi.registerForInCallVoicePrivacyOff(h, what, obj);
1150     }
1151 
1152     /**
1153      * Unregister for notifications when a sInCall VoicePrivacy is disabled
1154      *
1155      * @param h Handler to be removed from the registrant list.
1156      */
unregisterForInCallVoicePrivacyOff(Handler h)1157     public void unregisterForInCallVoicePrivacyOff(Handler h){
1158         mCi.unregisterForInCallVoicePrivacyOff(h);
1159     }
1160 
1161     /**
1162      * Notifies when an incoming call rings.<p>
1163      *
1164      *  Messages received from this:
1165      *  Message.obj will be an AsyncResult
1166      *  AsyncResult.userObj = obj
1167      *  AsyncResult.result = a Connection. <p>
1168      */
1169     @UnsupportedAppUsage
registerForIncomingRing( Handler h, int what, Object obj)1170     public void registerForIncomingRing(
1171             Handler h, int what, Object obj) {
1172         checkCorrectThread(h);
1173 
1174         mIncomingRingRegistrants.addUnique(h, what, obj);
1175     }
1176 
1177     /**
1178      * Unregisters for ring notification.
1179      * Extraneous calls are tolerated silently
1180      */
1181     @UnsupportedAppUsage
unregisterForIncomingRing(Handler h)1182     public void unregisterForIncomingRing(Handler h) {
1183         mIncomingRingRegistrants.remove(h);
1184     }
1185 
1186     /**
1187      * Notifies when a voice connection has disconnected, either due to local
1188      * or remote hangup or error.
1189      *
1190      *  Messages received from this will have the following members:<p>
1191      *  <ul><li>Message.obj will be an AsyncResult</li>
1192      *  <li>AsyncResult.userObj = obj</li>
1193      *  <li>AsyncResult.result = a Connection object that is
1194      *  no longer connected.</li></ul>
1195      */
1196     @UnsupportedAppUsage
registerForDisconnect(Handler h, int what, Object obj)1197     public void registerForDisconnect(Handler h, int what, Object obj) {
1198         checkCorrectThread(h);
1199 
1200         mDisconnectRegistrants.addUnique(h, what, obj);
1201     }
1202 
1203     /**
1204      * Unregisters for voice disconnection notification.
1205      * Extraneous calls are tolerated silently
1206      */
1207     @UnsupportedAppUsage
unregisterForDisconnect(Handler h)1208     public void unregisterForDisconnect(Handler h) {
1209         mDisconnectRegistrants.remove(h);
1210     }
1211 
1212     /**
1213      * Register for notifications when a supplementary service attempt fails.
1214      * Message.obj will contain an AsyncResult.
1215      *
1216      * @param h Handler that receives the notification message.
1217      * @param what User-defined message code.
1218      * @param obj User object.
1219      */
registerForSuppServiceFailed(Handler h, int what, Object obj)1220     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
1221         checkCorrectThread(h);
1222 
1223         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
1224     }
1225 
1226     /**
1227      * Unregister for notifications when a supplementary service attempt fails.
1228      * Extraneous calls are tolerated silently
1229      *
1230      * @param h Handler to be removed from the registrant list.
1231      */
unregisterForSuppServiceFailed(Handler h)1232     public void unregisterForSuppServiceFailed(Handler h) {
1233         mSuppServiceFailedRegistrants.remove(h);
1234     }
1235 
1236     /**
1237      * Register for notifications of initiation of a new MMI code request.
1238      * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
1239      *
1240      * Example: If Phone.dial is called with "*#31#", then the app will
1241      * be notified here.<p>
1242      *
1243      * The returned <code>Message.obj</code> will contain an AsyncResult.
1244      *
1245      * <code>obj.result</code> will be an "MmiCode" object.
1246      */
1247     @UnsupportedAppUsage
registerForMmiInitiate(Handler h, int what, Object obj)1248     public void registerForMmiInitiate(Handler h, int what, Object obj) {
1249         checkCorrectThread(h);
1250 
1251         mMmiRegistrants.addUnique(h, what, obj);
1252     }
1253 
1254     /**
1255      * Unregisters for new MMI initiate notification.
1256      * Extraneous calls are tolerated silently
1257      */
1258     @UnsupportedAppUsage
unregisterForMmiInitiate(Handler h)1259     public void unregisterForMmiInitiate(Handler h) {
1260         mMmiRegistrants.remove(h);
1261     }
1262 
1263     /**
1264      * Register for notifications that an MMI request has completed
1265      * its network activity and is in its final state. This may mean a state
1266      * of COMPLETE, FAILED, or CANCELLED.
1267      *
1268      * <code>Message.obj</code> will contain an AsyncResult.
1269      * <code>obj.result</code> will be an "MmiCode" object
1270      */
1271     @UnsupportedAppUsage
registerForMmiComplete(Handler h, int what, Object obj)1272     public void registerForMmiComplete(Handler h, int what, Object obj) {
1273         checkCorrectThread(h);
1274 
1275         mMmiCompleteRegistrants.addUnique(h, what, obj);
1276     }
1277 
1278     /**
1279      * Unregisters for MMI complete notification.
1280      * Extraneous calls are tolerated silently
1281      */
1282     @UnsupportedAppUsage
unregisterForMmiComplete(Handler h)1283     public void unregisterForMmiComplete(Handler h) {
1284         checkCorrectThread(h);
1285 
1286         mMmiCompleteRegistrants.remove(h);
1287     }
1288 
1289     /**
1290      * Registration point for Sim records loaded
1291      * @param h handler to notify
1292      * @param what what code of message when delivered
1293      * @param obj placed in Message.obj
1294      */
1295     @UnsupportedAppUsage
registerForSimRecordsLoaded(Handler h, int what, Object obj)1296     public void registerForSimRecordsLoaded(Handler h, int what, Object obj) {
1297     }
1298 
1299     /**
1300      * Unregister for notifications for Sim records loaded
1301      * @param h Handler to be removed from the registrant list.
1302      */
1303     @UnsupportedAppUsage
unregisterForSimRecordsLoaded(Handler h)1304     public void unregisterForSimRecordsLoaded(Handler h) {
1305     }
1306 
1307     /**
1308      * Register for TTY mode change notifications from the network.
1309      * Message.obj will contain an AsyncResult.
1310      * AsyncResult.result will be an Integer containing new mode.
1311      *
1312      * @param h Handler that receives the notification message.
1313      * @param what User-defined message code.
1314      * @param obj User object.
1315      */
registerForTtyModeReceived(Handler h, int what, Object obj)1316     public void registerForTtyModeReceived(Handler h, int what, Object obj) {
1317     }
1318 
1319     /**
1320      * Unregisters for TTY mode change notifications.
1321      * Extraneous calls are tolerated silently
1322      *
1323      * @param h Handler to be removed from the registrant list.
1324      */
unregisterForTtyModeReceived(Handler h)1325     public void unregisterForTtyModeReceived(Handler h) {
1326     }
1327 
1328     /**
1329      * Switches network selection mode to "automatic", re-scanning and
1330      * re-selecting a network if appropriate.
1331      *
1332      * @param response The message to dispatch when the network selection
1333      * is complete.
1334      *
1335      * @see #selectNetworkManually(OperatorInfo, boolean, android.os.Message)
1336      */
1337     @UnsupportedAppUsage
setNetworkSelectionModeAutomatic(Message response)1338     public void setNetworkSelectionModeAutomatic(Message response) {
1339         Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode");
1340         // we don't want to do this unecesarily - it acutally causes
1341         // the radio to repeate network selection and is costly
1342         // first check if we're already in automatic mode
1343         Message msg = obtainMessage(EVENT_CHECK_FOR_NETWORK_AUTOMATIC);
1344         msg.obj = response;
1345         mCi.getNetworkSelectionMode(msg);
1346     }
1347 
onCheckForNetworkSelectionModeAutomatic(Message fromRil)1348     private void onCheckForNetworkSelectionModeAutomatic(Message fromRil) {
1349         AsyncResult ar = (AsyncResult)fromRil.obj;
1350         Message response = (Message)ar.userObj;
1351         boolean doAutomatic = true;
1352         if (ar.exception == null && ar.result != null) {
1353             try {
1354                 int[] modes = (int[])ar.result;
1355                 if (modes[0] == 0) {
1356                     // already confirmed to be in automatic mode - don't resend
1357                     doAutomatic = false;
1358                 }
1359             } catch (Exception e) {
1360                 // send the setting on error
1361             }
1362         }
1363 
1364         // wrap the response message in our own message along with
1365         // an empty string (to indicate automatic selection) for the
1366         // operator's id.
1367         NetworkSelectMessage nsm = new NetworkSelectMessage();
1368         nsm.message = response;
1369         nsm.operatorNumeric = "";
1370         nsm.operatorAlphaLong = "";
1371         nsm.operatorAlphaShort = "";
1372 
1373         if (doAutomatic) {
1374             Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
1375             mCi.setNetworkSelectionModeAutomatic(msg);
1376         } else {
1377             Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - already auto, ignoring");
1378             // let the calling application know that the we are ignoring automatic mode switch.
1379             if (nsm.message != null) {
1380                 nsm.message.arg1 = ALREADY_IN_AUTO_SELECTION;
1381             }
1382 
1383             ar.userObj = nsm;
1384             handleSetSelectNetwork(ar);
1385         }
1386 
1387         updateSavedNetworkOperator(nsm);
1388     }
1389 
1390     /**
1391      * Query the radio for the current network selection mode.
1392      *
1393      * Return values:
1394      *     0 - automatic.
1395      *     1 - manual.
1396      */
getNetworkSelectionMode(Message message)1397     public void getNetworkSelectionMode(Message message) {
1398         mCi.getNetworkSelectionMode(message);
1399     }
1400 
getClientRequestStats()1401     public List<ClientRequestStats> getClientRequestStats() {
1402         return mCi.getClientRequestStats();
1403     }
1404 
1405     /**
1406      * Manually selects a network. <code>response</code> is
1407      * dispatched when this is complete.  <code>response.obj</code> will be
1408      * an AsyncResult, and <code>response.obj.exception</code> will be non-null
1409      * on failure.
1410      *
1411      * @see #setNetworkSelectionModeAutomatic(Message)
1412      */
1413     @UnsupportedAppUsage
selectNetworkManually(OperatorInfo network, boolean persistSelection, Message response)1414     public void selectNetworkManually(OperatorInfo network, boolean persistSelection,
1415             Message response) {
1416         // wrap the response message in our own message along with
1417         // the operator's id.
1418         NetworkSelectMessage nsm = new NetworkSelectMessage();
1419         nsm.message = response;
1420         nsm.operatorNumeric = network.getOperatorNumeric();
1421         nsm.operatorAlphaLong = network.getOperatorAlphaLong();
1422         nsm.operatorAlphaShort = network.getOperatorAlphaShort();
1423 
1424         Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
1425         mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), network.getRan(), msg);
1426 
1427         if (persistSelection) {
1428             updateSavedNetworkOperator(nsm);
1429         } else {
1430             clearSavedNetworkSelection();
1431             updateManualNetworkSelection(nsm);
1432         }
1433     }
1434 
1435     /**
1436      * Registration point for emergency call/callback mode start. Message.obj is AsyncResult and
1437      * Message.obj.result will be Integer indicating start of call by value 1 or end of call by
1438      * value 0
1439      * @param h handler to notify
1440      * @param what what code of message when delivered
1441      * @param obj placed in Message.obj.userObj
1442      */
registerForEmergencyCallToggle(Handler h, int what, Object obj)1443     public void registerForEmergencyCallToggle(Handler h, int what, Object obj) {
1444         Registrant r = new Registrant(h, what, obj);
1445         mEmergencyCallToggledRegistrants.add(r);
1446     }
1447 
unregisterForEmergencyCallToggle(Handler h)1448     public void unregisterForEmergencyCallToggle(Handler h) {
1449         mEmergencyCallToggledRegistrants.remove(h);
1450     }
1451 
updateSavedNetworkOperator(NetworkSelectMessage nsm)1452     private void updateSavedNetworkOperator(NetworkSelectMessage nsm) {
1453         int subId = getSubId();
1454         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1455             // open the shared preferences editor, and write the value.
1456             // nsm.operatorNumeric is "" if we're in automatic.selection.
1457             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1458             SharedPreferences.Editor editor = sp.edit();
1459             editor.putString(NETWORK_SELECTION_KEY + subId, nsm.operatorNumeric);
1460             editor.putString(NETWORK_SELECTION_NAME_KEY + subId, nsm.operatorAlphaLong);
1461             editor.putString(NETWORK_SELECTION_SHORT_KEY + subId, nsm.operatorAlphaShort);
1462 
1463             // commit and log the result.
1464             if (!editor.commit()) {
1465                 Rlog.e(LOG_TAG, "failed to commit network selection preference");
1466             }
1467         } else {
1468             Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " +
1469                     subId);
1470         }
1471     }
1472 
1473     /**
1474      * Update non-perisited manual network selection.
1475      *
1476      * @param nsm PLMN info of the selected network
1477      */
updateManualNetworkSelection(NetworkSelectMessage nsm)1478     protected void updateManualNetworkSelection(NetworkSelectMessage nsm)  {
1479         Rlog.e(LOG_TAG, "updateManualNetworkSelection() should be overridden");
1480     }
1481 
1482     /**
1483      * Used to track the settings upon completion of the network change.
1484      */
handleSetSelectNetwork(AsyncResult ar)1485     private void handleSetSelectNetwork(AsyncResult ar) {
1486         // look for our wrapper within the asyncresult, skip the rest if it
1487         // is null.
1488         if (!(ar.userObj instanceof NetworkSelectMessage)) {
1489             Rlog.e(LOG_TAG, "unexpected result from user object.");
1490             return;
1491         }
1492 
1493         NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
1494 
1495         // found the object, now we send off the message we had originally
1496         // attached to the request.
1497         if (nsm.message != null) {
1498             AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
1499             nsm.message.sendToTarget();
1500         }
1501     }
1502 
1503     /**
1504      * Method to retrieve the saved operator from the Shared Preferences
1505      */
1506     @NonNull
getSavedNetworkSelection()1507     public OperatorInfo getSavedNetworkSelection() {
1508         // open the shared preferences and search with our key.
1509         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1510         String numeric = sp.getString(NETWORK_SELECTION_KEY + getSubId(), "");
1511         String name = sp.getString(NETWORK_SELECTION_NAME_KEY + getSubId(), "");
1512         String shrt = sp.getString(NETWORK_SELECTION_SHORT_KEY + getSubId(), "");
1513         return new OperatorInfo(name, shrt, numeric);
1514     }
1515 
1516     /**
1517      * Clears the saved network selection.
1518      */
clearSavedNetworkSelection()1519     private void clearSavedNetworkSelection() {
1520         // open the shared preferences and search with our key.
1521         PreferenceManager.getDefaultSharedPreferences(getContext()).edit().
1522                 remove(NETWORK_SELECTION_KEY + getSubId()).
1523                 remove(NETWORK_SELECTION_NAME_KEY + getSubId()).
1524                 remove(NETWORK_SELECTION_SHORT_KEY + getSubId()).commit();
1525     }
1526 
1527     /**
1528      * Method to restore the previously saved operator id, or reset to
1529      * automatic selection, all depending upon the value in the shared
1530      * preferences.
1531      */
restoreSavedNetworkSelection(Message response)1532     private void restoreSavedNetworkSelection(Message response) {
1533         // retrieve the operator
1534         OperatorInfo networkSelection = getSavedNetworkSelection();
1535 
1536         // set to auto if the id is empty, otherwise select the network.
1537         if (networkSelection == null || TextUtils.isEmpty(networkSelection.getOperatorNumeric())) {
1538             setNetworkSelectionModeAutomatic(response);
1539         } else {
1540             selectNetworkManually(networkSelection, true, response);
1541         }
1542     }
1543 
1544     /**
1545      * Saves CLIR setting so that we can re-apply it as necessary
1546      * (in case the RIL resets it across reboots).
1547      */
saveClirSetting(int commandInterfaceCLIRMode)1548     public void saveClirSetting(int commandInterfaceCLIRMode) {
1549         // Open the shared preferences editor, and write the value.
1550         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1551         SharedPreferences.Editor editor = sp.edit();
1552         editor.putInt(CLIR_KEY + getSubId(), commandInterfaceCLIRMode);
1553         Rlog.i(LOG_TAG, "saveClirSetting: " + CLIR_KEY + getSubId() + "="
1554                 + commandInterfaceCLIRMode);
1555 
1556         // Commit and log the result.
1557         if (!editor.commit()) {
1558             Rlog.e(LOG_TAG, "Failed to commit CLIR preference");
1559         }
1560     }
1561 
1562     /**
1563      * For unit tests; don't send notifications to "Phone"
1564      * mailbox registrants if true.
1565      */
setUnitTestMode(boolean f)1566     private void setUnitTestMode(boolean f) {
1567         mUnitTestMode = f;
1568     }
1569 
1570     /**
1571      * @return true If unit test mode is enabled
1572      */
getUnitTestMode()1573     public boolean getUnitTestMode() {
1574         return mUnitTestMode;
1575     }
1576 
1577     /**
1578      * To be invoked when a voice call Connection disconnects.
1579      *
1580      * Subclasses of Phone probably want to replace this with a
1581      * version scoped to their packages
1582      */
notifyDisconnectP(Connection cn)1583     protected void notifyDisconnectP(Connection cn) {
1584         AsyncResult ar = new AsyncResult(null, cn, null);
1585         mDisconnectRegistrants.notifyRegistrants(ar);
1586     }
1587 
1588     /**
1589      * Register for ServiceState changed.
1590      * Message.obj will contain an AsyncResult.
1591      * AsyncResult.result will be a ServiceState instance
1592      */
1593     @UnsupportedAppUsage
registerForServiceStateChanged( Handler h, int what, Object obj)1594     public void registerForServiceStateChanged(
1595             Handler h, int what, Object obj) {
1596         mServiceStateRegistrants.add(h, what, obj);
1597     }
1598 
1599     /**
1600      * Unregisters for ServiceStateChange notification.
1601      * Extraneous calls are tolerated silently
1602      */
1603     @UnsupportedAppUsage
unregisterForServiceStateChanged(Handler h)1604     public void unregisterForServiceStateChanged(Handler h) {
1605         mServiceStateRegistrants.remove(h);
1606     }
1607 
1608     /**
1609      * Notifies when out-band ringback tone is needed.<p>
1610      *
1611      *  Messages received from this:
1612      *  Message.obj will be an AsyncResult
1613      *  AsyncResult.userObj = obj
1614      *  AsyncResult.result = boolean, true to start play ringback tone
1615      *                       and false to stop. <p>
1616      */
1617     @UnsupportedAppUsage
registerForRingbackTone(Handler h, int what, Object obj)1618     public void registerForRingbackTone(Handler h, int what, Object obj) {
1619         mCi.registerForRingbackTone(h, what, obj);
1620     }
1621 
1622     /**
1623      * Unregisters for ringback tone notification.
1624      */
1625     @UnsupportedAppUsage
unregisterForRingbackTone(Handler h)1626     public void unregisterForRingbackTone(Handler h) {
1627         mCi.unregisterForRingbackTone(h);
1628     }
1629 
1630     /**
1631      * Notifies when out-band on-hold tone is needed.<p>
1632      *
1633      *  Messages received from this:
1634      *  Message.obj will be an AsyncResult
1635      *  AsyncResult.userObj = obj
1636      *  AsyncResult.result = boolean, true to start play on-hold tone
1637      *                       and false to stop. <p>
1638      */
registerForOnHoldTone(Handler h, int what, Object obj)1639     public void registerForOnHoldTone(Handler h, int what, Object obj) {
1640     }
1641 
1642     /**
1643      * Unregisters for on-hold tone notification.
1644      */
unregisterForOnHoldTone(Handler h)1645     public void unregisterForOnHoldTone(Handler h) {
1646     }
1647 
1648     /**
1649      * Registers the handler to reset the uplink mute state to get
1650      * uplink audio.
1651      */
registerForResendIncallMute(Handler h, int what, Object obj)1652     public void registerForResendIncallMute(Handler h, int what, Object obj) {
1653         mCi.registerForResendIncallMute(h, what, obj);
1654     }
1655 
1656     /**
1657      * Unregisters for resend incall mute notifications.
1658      */
unregisterForResendIncallMute(Handler h)1659     public void unregisterForResendIncallMute(Handler h) {
1660         mCi.unregisterForResendIncallMute(h);
1661     }
1662 
1663     /**
1664      * Registers for CellInfo changed.
1665      * Message.obj will contain an AsyncResult.
1666      * AsyncResult.result will be a List<CellInfo> instance
1667      */
registerForCellInfo( Handler h, int what, Object obj)1668     public void registerForCellInfo(
1669             Handler h, int what, Object obj) {
1670         mCellInfoRegistrants.add(h, what, obj);
1671     }
1672 
1673     /**
1674      * Unregisters for CellInfo notification.
1675      * Extraneous calls are tolerated silently
1676      */
unregisterForCellInfo(Handler h)1677     public void unregisterForCellInfo(Handler h) {
1678         mCellInfoRegistrants.remove(h);
1679     }
1680 
1681     /**
1682      * Enables or disables echo suppression.
1683      */
setEchoSuppressionEnabled()1684     public void setEchoSuppressionEnabled() {
1685         // no need for regular phone
1686     }
1687 
1688     /**
1689      * Subclasses of Phone probably want to replace this with a
1690      * version scoped to their packages
1691      */
notifyServiceStateChangedP(ServiceState ss)1692     protected void notifyServiceStateChangedP(ServiceState ss) {
1693         AsyncResult ar = new AsyncResult(null, ss, null);
1694         mServiceStateRegistrants.notifyRegistrants(ar);
1695 
1696         mNotifier.notifyServiceState(this);
1697     }
1698 
1699     /**
1700      * Version of notifyServiceStateChangedP which allows us to specify the subId. This is used when
1701      * we send out a final ServiceState update when a phone's subId becomes invalid.
1702      */
notifyServiceStateChangedPForSubId(ServiceState ss, int subId)1703     protected void notifyServiceStateChangedPForSubId(ServiceState ss, int subId) {
1704         AsyncResult ar = new AsyncResult(null, ss, null);
1705         mServiceStateRegistrants.notifyRegistrants(ar);
1706 
1707         mNotifier.notifyServiceStateForSubId(this, ss, subId);
1708     }
1709 
1710     /**
1711      * If this is a simulated phone interface, returns a SimulatedRadioControl.
1712      * @return SimulatedRadioControl if this is a simulated interface;
1713      * otherwise, null.
1714      */
getSimulatedRadioControl()1715     public SimulatedRadioControl getSimulatedRadioControl() {
1716         return mSimulatedRadioControl;
1717     }
1718 
1719     /**
1720      * Verifies the current thread is the same as the thread originally
1721      * used in the initialization of this instance. Throws RuntimeException
1722      * if not.
1723      *
1724      * @exception RuntimeException if the current thread is not
1725      * the thread that originally obtained this Phone instance.
1726      */
checkCorrectThread(Handler h)1727     private void checkCorrectThread(Handler h) {
1728         if (h.getLooper() != mLooper) {
1729             throw new RuntimeException(
1730                     "com.android.internal.telephony.Phone must be used from within one thread");
1731         }
1732     }
1733 
getAllowedNetworkTypes()1734     private @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypes() {
1735         long allowedNetworkTypes = TelephonyManager.getAllNetworkTypesBitmask();
1736         if (SubscriptionController.getInstance() != null) {
1737             String result = SubscriptionController.getInstance().getSubscriptionProperty(
1738                     getSubId(),
1739                     SubscriptionManager.ALLOWED_NETWORK_TYPES);
1740 
1741             if (result != null) {
1742                 try {
1743                     allowedNetworkTypes = Long.parseLong(result);
1744                 } catch (NumberFormatException err) {
1745                     Rlog.e(LOG_TAG, "allowedNetworkTypes NumberFormat exception");
1746                 }
1747             }
1748         }
1749         return allowedNetworkTypes;
1750     }
1751     /**
1752      * Set the properties by matching the carrier string in
1753      * a string-array resource
1754      */
getLocaleFromCarrierProperties()1755     @Nullable Locale getLocaleFromCarrierProperties() {
1756         String carrier = SystemProperties.get("ro.carrier");
1757 
1758         if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
1759             return null;
1760         }
1761 
1762         CharSequence[] carrierLocales = mContext.getResources().getTextArray(
1763                 R.array.carrier_properties);
1764 
1765         for (int i = 0; i < carrierLocales.length; i+=3) {
1766             String c = carrierLocales[i].toString();
1767             if (carrier.equals(c)) {
1768                 return Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-'));
1769             }
1770         }
1771 
1772         return null;
1773     }
1774 
1775     /**
1776      * Get current coarse-grained voice call state.
1777      * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object)
1778      * registerForPreciseCallStateChanged()} for change notification. <p>
1779      * If the phone has an active call and call waiting occurs,
1780      * then the phone state is RINGING not OFFHOOK
1781      * <strong>Note:</strong>
1782      * This registration point provides notification of finer-grained
1783      * changes.<p>
1784      */
1785     @UnsupportedAppUsage
getState()1786     public abstract PhoneConstants.State getState();
1787 
1788     /**
1789      * Retrieves the IccFileHandler of the Phone instance
1790      */
1791     @UnsupportedAppUsage
getIccFileHandler()1792     public IccFileHandler getIccFileHandler(){
1793         UiccCardApplication uiccApplication = mUiccApplication.get();
1794         IccFileHandler fh;
1795 
1796         if (uiccApplication == null) {
1797             Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null");
1798             fh = null;
1799         } else {
1800             fh = uiccApplication.getIccFileHandler();
1801         }
1802 
1803         Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh);
1804         return fh;
1805     }
1806 
1807     /*
1808      * Retrieves the Handler of the Phone instance
1809      */
getHandler()1810     public Handler getHandler() {
1811         return this;
1812     }
1813 
1814     /**
1815      * Update the phone object if the voice radio technology has changed
1816      *
1817      * @param voiceRadioTech The new voice radio technology
1818      */
updatePhoneObject(int voiceRadioTech)1819     public void updatePhoneObject(int voiceRadioTech) {
1820     }
1821 
1822     /**
1823     * Retrieves the ServiceStateTracker of the phone instance.
1824     */
1825     @UnsupportedAppUsage
getServiceStateTracker()1826     public ServiceStateTracker getServiceStateTracker() {
1827         return null;
1828     }
1829 
1830     /**
1831      * Retrieves the EmergencyNumberTracker of the phone instance.
1832      */
getEmergencyNumberTracker()1833     public EmergencyNumberTracker getEmergencyNumberTracker() {
1834         return null;
1835     }
1836 
1837     /**
1838     * Get call tracker
1839     */
1840     @UnsupportedAppUsage
getCallTracker()1841     public CallTracker getCallTracker() {
1842         return null;
1843     }
1844 
1845     /**
1846      * @return The instance of transport manager
1847      */
getTransportManager()1848     public TransportManager getTransportManager() {
1849         return null;
1850     }
1851 
1852     /**
1853      * Retrieves the DeviceStateMonitor of the phone instance.
1854      */
getDeviceStateMonitor()1855     public DeviceStateMonitor getDeviceStateMonitor() {
1856         return null;
1857     }
1858 
1859     /**
1860      * Retrieves the DisplayInfoController of the phone instance.
1861      */
getDisplayInfoController()1862     public DisplayInfoController getDisplayInfoController() {
1863         return null;
1864     }
1865 
1866     /**
1867      * Update voice activation state
1868      */
setVoiceActivationState(int state)1869     public void setVoiceActivationState(int state) {
1870         mSimActivationTracker.setVoiceActivationState(state);
1871     }
1872     /**
1873      * Update data activation state
1874      */
setDataActivationState(int state)1875     public void setDataActivationState(int state) {
1876         mSimActivationTracker.setDataActivationState(state);
1877     }
1878 
1879     /**
1880      * Returns voice activation state
1881      */
getVoiceActivationState()1882     public int getVoiceActivationState() {
1883         return mSimActivationTracker.getVoiceActivationState();
1884     }
1885     /**
1886      * Returns data activation state
1887      */
getDataActivationState()1888     public int getDataActivationState() {
1889         return mSimActivationTracker.getDataActivationState();
1890     }
1891 
1892     /**
1893      * Update voice mail count related fields and notify listeners
1894      */
updateVoiceMail()1895     public void updateVoiceMail() {
1896         Rlog.e(LOG_TAG, "updateVoiceMail() should be overridden");
1897     }
1898 
getCurrentUiccAppType()1899     public AppType getCurrentUiccAppType() {
1900         UiccCardApplication currentApp = mUiccApplication.get();
1901         if (currentApp != null) {
1902             return currentApp.getType();
1903         }
1904         return AppType.APPTYPE_UNKNOWN;
1905     }
1906 
1907     /**
1908      * Returns the ICC card interface for this phone, or null
1909      * if not applicable to underlying technology.
1910      */
1911     @UnsupportedAppUsage
getIccCard()1912     public IccCard getIccCard() {
1913         return null;
1914         //throw new Exception("getIccCard Shouldn't be called from Phone");
1915     }
1916 
1917     /**
1918      * Retrieves the serial number of the ICC, if applicable. Returns only the decimal digits before
1919      * the first hex digit in the ICC ID.
1920      */
1921     @UnsupportedAppUsage
getIccSerialNumber()1922     public String getIccSerialNumber() {
1923         IccRecords r = mIccRecords.get();
1924         return (r != null) ? r.getIccId() : null;
1925     }
1926 
1927     /**
1928      * Retrieves the full serial number of the ICC (including hex digits), if applicable.
1929      */
getFullIccSerialNumber()1930     public String getFullIccSerialNumber() {
1931         IccRecords r = mIccRecords.get();
1932         return (r != null) ? r.getFullIccId() : null;
1933     }
1934 
1935     /**
1936      * Returns SIM record load state. Use
1937      * <code>getSimCard().registerForReady()</code> for change notification.
1938      *
1939      * @return true if records from the SIM have been loaded and are
1940      * available (if applicable). If not applicable to the underlying
1941      * technology, returns true as well.
1942      */
getIccRecordsLoaded()1943     public boolean getIccRecordsLoaded() {
1944         IccRecords r = mIccRecords.get();
1945         return (r != null) ? r.getRecordsLoaded() : false;
1946     }
1947 
1948     /** Set the minimum interval for CellInfo requests to the modem */
setCellInfoMinInterval(int interval)1949     public void setCellInfoMinInterval(int interval) {
1950         getServiceStateTracker().setCellInfoMinInterval(interval);
1951     }
1952 
1953     /**
1954      * @return the last known CellInfo
1955      */
getAllCellInfo()1956     public List<CellInfo> getAllCellInfo() {
1957         return getServiceStateTracker().getAllCellInfo();
1958     }
1959 
1960     /**
1961      * @param workSource calling WorkSource
1962      * @param rspMsg the response message containing the cell info
1963      */
requestCellInfoUpdate(WorkSource workSource, Message rspMsg)1964     public void requestCellInfoUpdate(WorkSource workSource, Message rspMsg) {
1965         getServiceStateTracker().requestAllCellInfo(workSource, rspMsg);
1966     }
1967 
1968     /**
1969      * @return the current cell location if known
1970      */
getCellIdentity()1971     public CellIdentity getCellIdentity() {
1972         return getServiceStateTracker().getCellIdentity();
1973     }
1974 
1975     /**
1976      * @param workSource calling WorkSource
1977      * @param rspMsg the response message containing the cell location
1978      */
getCellIdentity(WorkSource workSource, Message rspMsg)1979     public void getCellIdentity(WorkSource workSource, Message rspMsg) {
1980         getServiceStateTracker().requestCellIdentity(workSource, rspMsg);
1981     }
1982 
1983     /**
1984      * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
1985      * PhoneStateListener.onCellInfoChanged} will be invoked.
1986      *
1987      * The default, 0, means invoke onCellInfoChanged when any of the reported
1988      * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
1989      * A onCellInfoChanged.
1990      *
1991      * @param rateInMillis the rate
1992      * @param workSource calling WorkSource
1993      */
setCellInfoListRate(int rateInMillis, WorkSource workSource)1994     public void setCellInfoListRate(int rateInMillis, WorkSource workSource) {
1995         mCi.setCellInfoListRate(rateInMillis, null, workSource);
1996     }
1997 
1998     /**
1999      * Get voice message waiting indicator status. No change notification
2000      * available on this interface. Use PhoneStateNotifier or similar instead.
2001      *
2002      * @return true if there is a voice message waiting
2003      */
getMessageWaitingIndicator()2004     public boolean getMessageWaitingIndicator() {
2005         return mVmCount != 0;
2006     }
2007 
2008     /**
2009      *  Retrieves manually selected network info.
2010      */
getManualNetworkSelectionPlmn()2011     public String getManualNetworkSelectionPlmn() {
2012         return "";
2013     }
2014 
2015 
getCallForwardingIndicatorFromSharedPref()2016     private int getCallForwardingIndicatorFromSharedPref() {
2017         int status = IccRecords.CALL_FORWARDING_STATUS_DISABLED;
2018         int subId = getSubId();
2019         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2020             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2021             status = sp.getInt(CF_STATUS + subId, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN);
2022             Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " +
2023                     status);
2024             // Check for old preference if status is UNKNOWN for current subId. This part of the
2025             // code is needed only when upgrading from M to N.
2026             if (status == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
2027                 String subscriberId = sp.getString(CF_ID, null);
2028                 if (subscriberId != null) {
2029                     String currentSubscriberId = getSubscriberId();
2030 
2031                     if (subscriberId.equals(currentSubscriberId)) {
2032                         // get call forwarding status from preferences
2033                         status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED);
2034                         setCallForwardingIndicatorInSharedPref(
2035                                 status == IccRecords.CALL_FORWARDING_STATUS_ENABLED ? true : false);
2036                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: " + status);
2037                     } else {
2038                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: returning " +
2039                                 "DISABLED as status for matching subscriberId not found");
2040                     }
2041 
2042                     // get rid of old preferences.
2043                     SharedPreferences.Editor editor = sp.edit();
2044                     editor.remove(CF_ID);
2045                     editor.remove(CF_STATUS);
2046                     editor.apply();
2047                 }
2048             }
2049         } else {
2050             Rlog.e(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId);
2051         }
2052         return status;
2053     }
2054 
setCallForwardingIndicatorInSharedPref(boolean enable)2055     private void setCallForwardingIndicatorInSharedPref(boolean enable) {
2056         int status = enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED :
2057                 IccRecords.CALL_FORWARDING_STATUS_DISABLED;
2058         int subId = getSubId();
2059         Rlog.i(LOG_TAG, "setCallForwardingIndicatorInSharedPref: Storing status = " + status +
2060                 " in pref " + CF_STATUS + subId);
2061 
2062         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2063         SharedPreferences.Editor editor = sp.edit();
2064         editor.putInt(CF_STATUS + subId, status);
2065         editor.apply();
2066     }
2067 
getAllowedNetworkTypesForAllReasons()2068     private @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypesForAllReasons() {
2069         long allowedNetworkTypes = TelephonyManager.getAllNetworkTypesBitmask();
2070         synchronized (mAllowedNetworkTypesForReasons) {
2071             for (long networkTypes: mAllowedNetworkTypesForReasons.values()) {
2072                 allowedNetworkTypes = allowedNetworkTypes & networkTypes;
2073             }
2074         }
2075         return allowedNetworkTypes;
2076     }
2077 
setVoiceCallForwardingFlag(int line, boolean enable, String number)2078     public void setVoiceCallForwardingFlag(int line, boolean enable, String number) {
2079         setCallForwardingIndicatorInSharedPref(enable);
2080         IccRecords r = getIccRecords();
2081         if (r != null) {
2082             r.setVoiceCallForwardingFlag(line, enable, number);
2083         }
2084         notifyCallForwardingIndicator();
2085     }
2086 
2087     /**
2088      * Set the voice call forwarding flag for GSM/UMTS and the like SIMs
2089      *
2090      * @param r to enable/disable
2091      * @param line to enable/disable
2092      * @param enable
2093      * @param number to which CFU is enabled
2094      */
setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, String number)2095     public void setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable,
2096                                               String number) {
2097         setCallForwardingIndicatorInSharedPref(enable);
2098         if (r != null) {
2099             r.setVoiceCallForwardingFlag(line, enable, number);
2100         }
2101         notifyCallForwardingIndicator();
2102     }
2103 
2104     /**
2105      * Get voice call forwarding indicator status. No change notification
2106      * available on this interface. Use PhoneStateNotifier or similar instead.
2107      *
2108      * @return true if there is a voice call forwarding
2109      */
getCallForwardingIndicator()2110     public boolean getCallForwardingIndicator() {
2111         if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2112             Rlog.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
2113             return false;
2114         }
2115         IccRecords r = getIccRecords();
2116         int callForwardingIndicator = IccRecords.CALL_FORWARDING_STATUS_UNKNOWN;
2117         if (r != null) {
2118             callForwardingIndicator = r.getVoiceCallForwardingFlag();
2119         }
2120         if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
2121             callForwardingIndicator = getCallForwardingIndicatorFromSharedPref();
2122         }
2123         Rlog.v(LOG_TAG, "getCallForwardingIndicator: iccForwardingFlag=" + (r != null
2124                     ? r.getVoiceCallForwardingFlag() : "null") + ", sharedPrefFlag="
2125                     + getCallForwardingIndicatorFromSharedPref());
2126         return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED);
2127     }
2128 
getCarrierSignalAgent()2129     public CarrierSignalAgent getCarrierSignalAgent() {
2130         return mCarrierSignalAgent;
2131     }
2132 
getCarrierActionAgent()2133     public CarrierActionAgent getCarrierActionAgent() {
2134         return mCarrierActionAgent;
2135     }
2136 
2137     /**
2138      *  Query the CDMA roaming preference setting
2139      *
2140      * @param response is callback message to report one of  CDMA_RM_*
2141      */
queryCdmaRoamingPreference(Message response)2142     public void queryCdmaRoamingPreference(Message response) {
2143         mCi.queryCdmaRoamingPreference(response);
2144     }
2145 
2146     /**
2147      * Get current signal strength. No change notification available on this
2148      * interface. Use <code>PhoneStateNotifier</code> or an equivalent.
2149      * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
2150      * The following special values are defined:</p>
2151      * <ul><li>0 means "-113 dBm or less".</li>
2152      * <li>31 means "-51 dBm or greater".</li></ul>
2153      *
2154      * @return Current signal strength as SignalStrength
2155      */
getSignalStrength()2156     public SignalStrength getSignalStrength() {
2157         ServiceStateTracker sst = getServiceStateTracker();
2158         if (sst == null) {
2159             return new SignalStrength();
2160         } else {
2161             return sst.getSignalStrength();
2162         }
2163     }
2164 
2165     /**
2166      * @return true, if the device is in a state where both voice and data
2167      * are supported simultaneously. This can change based on location or network condition.
2168      */
isConcurrentVoiceAndDataAllowed()2169     public boolean isConcurrentVoiceAndDataAllowed() {
2170         ServiceStateTracker sst = getServiceStateTracker();
2171         return sst == null ? false : sst.isConcurrentVoiceAndDataAllowed();
2172     }
2173 
2174     /**
2175      *  Requests to set the CDMA roaming preference
2176      * @param cdmaRoamingType one of  CDMA_RM_*
2177      * @param response is callback message
2178      */
setCdmaRoamingPreference(int cdmaRoamingType, Message response)2179     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
2180         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
2181     }
2182 
2183     /**
2184      *  Requests to set the CDMA subscription mode
2185      * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
2186      * @param response is callback message
2187      */
setCdmaSubscription(int cdmaSubscriptionType, Message response)2188     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
2189         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
2190     }
2191 
2192     /**
2193      * Get the effective allowed network types on the device.
2194      * @return effective network type
2195      */
getEffectiveAllowedNetworkTypes()2196     public @TelephonyManager.NetworkTypeBitMask long getEffectiveAllowedNetworkTypes() {
2197         long allowedNetworkTypes = getAllowedNetworkTypes();
2198         return allowedNetworkTypes & getAllowedNetworkTypesForAllReasons();
2199     }
2200 
2201     /**
2202      * Get the allowed network types for a certain reason.
2203      * @param reason reason to configure allowed network types
2204      * @return the allowed network types.
2205      */
getAllowedNetworkTypes( @elephonyManager.AllowedNetworkTypesReason int reason)2206     public @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypes(
2207             @TelephonyManager.AllowedNetworkTypesReason int reason) {
2208         synchronized (mAllowedNetworkTypesForReasons) {
2209             switch (reason) {
2210                 case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER:
2211                     return mAllowedNetworkTypesForReasons.getOrDefault(
2212                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER,
2213                             TelephonyManager.getAllNetworkTypesBitmask());
2214                 default:
2215                     Rlog.e(LOG_TAG, "Invalid allowed network type reason: " + reason);
2216                     return TelephonyManager.getAllNetworkTypesBitmask();
2217             }
2218         }
2219     }
2220 
2221     /**
2222      * Requests to set the allowed network types for a specific reason
2223      * @param reason reason to configure allowed network type
2224      * @param networkTypes one of the network types
2225      */
setAllowedNetworkTypes(@elephonyManager.AllowedNetworkTypesReason int reason, @TelephonyManager.NetworkTypeBitMask long networkTypes)2226     public void setAllowedNetworkTypes(@TelephonyManager.AllowedNetworkTypesReason int reason,
2227             @TelephonyManager.NetworkTypeBitMask long networkTypes) {
2228         synchronized (mAllowedNetworkTypesForReasons) {
2229             switch (reason) {
2230                 case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER:
2231                     mAllowedNetworkTypesForReasons.put(
2232                             TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER, networkTypes);
2233                     break;
2234                 default:
2235                     Rlog.e(LOG_TAG, "Invalid allowed network type reason: " + reason);
2236                     break;
2237             }
2238         }
2239     }
2240 
2241     /**
2242      *  Requests to set the preferred network type for searching and registering
2243      * (CS/PS domain, RAT, and operation mode)
2244      * @param networkType one of  NT_*_TYPE
2245      * @param response is callback message
2246      */
2247     @UnsupportedAppUsage
setPreferredNetworkType(int networkType, Message response)2248     public void setPreferredNetworkType(int networkType, Message response) {
2249         // Only set preferred network types to that which the modem supports
2250         int modemRaf = getRadioAccessFamily();
2251         int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType);
2252 
2253         long allowedNetworkTypes = getAllowedNetworkTypes();
2254         if (modemRaf == RadioAccessFamily.RAF_UNKNOWN
2255                 || rafFromType == RadioAccessFamily.RAF_UNKNOWN) {
2256             Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: "
2257                     + modemRaf + " " + rafFromType);
2258             if (response != null) {
2259                 CommandException ex;
2260 
2261                 ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
2262                 AsyncResult.forMessage(response, null, ex);
2263                 response.sendToTarget();
2264             }
2265             return;
2266         }
2267 
2268         int filteredRaf = (int) (rafFromType & modemRaf & allowedNetworkTypes
2269                 & getAllowedNetworkTypesForAllReasons());
2270         int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf);
2271         long powerAllowedNetworkTypes = getAllowedNetworkTypes(
2272                 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER);
2273         Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType
2274                 + " modemRaf = " + modemRaf
2275                 + " rafFromType = " + rafFromType
2276                 + " allowedNetworkTypes = " + allowedNetworkTypes
2277                 + " power allowedNetworkTypes = " + powerAllowedNetworkTypes
2278                 + " filteredType = " + filteredType);
2279 
2280         mCi.setPreferredNetworkType(filteredType, response);
2281         mPreferredNetworkTypeRegistrants.notifyRegistrants();
2282     }
2283 
2284     /**
2285      * Query the preferred network type setting
2286      *
2287      * @param response is callback message to report one of  NT_*_TYPE
2288      */
getPreferredNetworkType(Message response)2289     public void getPreferredNetworkType(Message response) {
2290         mCi.getPreferredNetworkType(response);
2291     }
2292 
2293     /**
2294      * Register for preferred network type changes
2295      *
2296      * @param h Handler that receives the notification message.
2297      * @param what User-defined message code.
2298      * @param obj User object.
2299      */
registerForPreferredNetworkTypeChanged(Handler h, int what, Object obj)2300     public void registerForPreferredNetworkTypeChanged(Handler h, int what, Object obj) {
2301         checkCorrectThread(h);
2302         mPreferredNetworkTypeRegistrants.addUnique(h, what, obj);
2303     }
2304 
2305     /**
2306      * Unregister for preferred network type changes.
2307      *
2308      * @param h Handler that should be unregistered.
2309      */
unregisterForPreferredNetworkTypeChanged(Handler h)2310     public void unregisterForPreferredNetworkTypeChanged(Handler h) {
2311         mPreferredNetworkTypeRegistrants.remove(h);
2312     }
2313 
2314     /**
2315      * Get the cached value of the preferred network type setting
2316      */
getCachedPreferredNetworkType()2317     public int getCachedPreferredNetworkType() {
2318         if (mCi != null && mCi instanceof BaseCommands) {
2319             return ((BaseCommands) mCi).mPreferredNetworkType;
2320         } else {
2321             return RILConstants.PREFERRED_NETWORK_MODE;
2322         }
2323     }
2324 
2325     /**
2326      * Gets the default SMSC address.
2327      *
2328      * @param result Callback message contains the SMSC address.
2329      */
2330     @UnsupportedAppUsage
getSmscAddress(Message result)2331     public void getSmscAddress(Message result) {
2332         mCi.getSmscAddress(result);
2333     }
2334 
2335     /**
2336      * Sets the default SMSC address.
2337      *
2338      * @param address new SMSC address
2339      * @param result Callback message is empty on completion
2340      */
2341     @UnsupportedAppUsage
setSmscAddress(String address, Message result)2342     public void setSmscAddress(String address, Message result) {
2343         mCi.setSmscAddress(address, result);
2344     }
2345 
2346     /**
2347      * setTTYMode
2348      * sets a TTY mode option.
2349      * @param ttyMode is a one of the following:
2350      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
2351      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
2352      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
2353      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
2354      * @param onComplete a callback message when the action is completed
2355      */
setTTYMode(int ttyMode, Message onComplete)2356     public void setTTYMode(int ttyMode, Message onComplete) {
2357         mCi.setTTYMode(ttyMode, onComplete);
2358     }
2359 
2360     /**
2361      * setUiTTYMode
2362      * sets a TTY mode option.
2363      * @param ttyMode is a one of the following:
2364      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
2365      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
2366      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
2367      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
2368      * @param onComplete a callback message when the action is completed
2369      */
setUiTTYMode(int uiTtyMode, Message onComplete)2370     public void setUiTTYMode(int uiTtyMode, Message onComplete) {
2371         Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call");
2372     }
2373 
2374     /**
2375      * queryTTYMode
2376      * query the status of the TTY mode
2377      *
2378      * @param onComplete a callback message when the action is completed.
2379      */
queryTTYMode(Message onComplete)2380     public void queryTTYMode(Message onComplete) {
2381         mCi.queryTTYMode(onComplete);
2382     }
2383 
2384     /**
2385      * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is
2386      * disabled, normal VP is enabled.
2387      *
2388      * @param enable whether true or false to enable or disable.
2389      * @param onComplete a callback message when the action is completed.
2390      */
enableEnhancedVoicePrivacy(boolean enable, Message onComplete)2391     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
2392     }
2393 
2394     /**
2395      * Get the currently set Voice Privacy (VP) mode.
2396      *
2397      * @param onComplete a callback message when the action is completed.
2398      */
getEnhancedVoicePrivacy(Message onComplete)2399     public void getEnhancedVoicePrivacy(Message onComplete) {
2400     }
2401 
2402     /**
2403      * Assign a specified band for RF configuration.
2404      *
2405      * @param bandMode one of BM_*_BAND
2406      * @param response is callback message
2407      */
setBandMode(int bandMode, Message response)2408     public void setBandMode(int bandMode, Message response) {
2409         mCi.setBandMode(bandMode, response);
2410     }
2411 
2412     /**
2413      * Query the list of band mode supported by RF.
2414      *
2415      * @param response is callback message
2416      *        ((AsyncResult)response.obj).result  is an int[] where int[0] is
2417      *        the size of the array and the rest of each element representing
2418      *        one available BM_*_BAND
2419      */
queryAvailableBandMode(Message response)2420     public void queryAvailableBandMode(Message response) {
2421         mCi.queryAvailableBandMode(response);
2422     }
2423 
2424     /**
2425      * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
2426      *
2427      * @param data The data for the request.
2428      * @param response <strong>On success</strong>,
2429      * (byte[])(((AsyncResult)response.obj).result)
2430      * <strong>On failure</strong>,
2431      * (((AsyncResult)response.obj).result) == null and
2432      * (((AsyncResult)response.obj).exception) being an instance of
2433      * com.android.internal.telephony.gsm.CommandException
2434      *
2435      * @see #invokeOemRilRequestRaw(byte[], android.os.Message)
2436      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
2437      */
2438     @UnsupportedAppUsage
2439     @Deprecated
invokeOemRilRequestRaw(byte[] data, Message response)2440     public void invokeOemRilRequestRaw(byte[] data, Message response) {
2441         mCi.invokeOemRilRequestRaw(data, response);
2442     }
2443 
2444     /**
2445      * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation.
2446      *
2447      * @param strings The strings to make available as the request data.
2448      * @param response <strong>On success</strong>, "response" bytes is
2449      * made available as:
2450      * (String[])(((AsyncResult)response.obj).result).
2451      * <strong>On failure</strong>,
2452      * (((AsyncResult)response.obj).result) == null and
2453      * (((AsyncResult)response.obj).exception) being an instance of
2454      * com.android.internal.telephony.gsm.CommandException
2455      *
2456      * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message)
2457      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
2458      */
2459     @UnsupportedAppUsage
2460     @Deprecated
invokeOemRilRequestStrings(String[] strings, Message response)2461     public void invokeOemRilRequestStrings(String[] strings, Message response) {
2462         mCi.invokeOemRilRequestStrings(strings, response);
2463     }
2464 
2465     /**
2466      * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
2467      * Used for device configuration by some CDMA operators.
2468      *
2469      * @param itemID the ID of the item to read
2470      * @param response callback message with the String response in the obj field
2471      * @param workSource calling WorkSource
2472      */
nvReadItem(int itemID, Message response, WorkSource workSource)2473     public void nvReadItem(int itemID, Message response, WorkSource workSource) {
2474         mCi.nvReadItem(itemID, response, workSource);
2475     }
2476 
2477     /**
2478      * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
2479      * Used for device configuration by some CDMA operators.
2480      *
2481      * @param itemID the ID of the item to read
2482      * @param itemValue the value to write, as a String
2483      * @param response Callback message.
2484      * @param workSource calling WorkSource
2485      */
nvWriteItem(int itemID, String itemValue, Message response, WorkSource workSource)2486     public void nvWriteItem(int itemID, String itemValue, Message response,
2487             WorkSource workSource) {
2488         mCi.nvWriteItem(itemID, itemValue, response, workSource);
2489     }
2490 
2491     /**
2492      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
2493      * Used for device configuration by some CDMA operators.
2494      *
2495      * @param preferredRoamingList byte array containing the new PRL
2496      * @param response Callback message.
2497      */
nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)2498     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
2499         mCi.nvWriteCdmaPrl(preferredRoamingList, response);
2500     }
2501 
2502     /**
2503      * Perform the radio modem reboot. The radio will be taken offline. Used for device
2504      * configuration by some CDMA operators.
2505      * TODO: reuse nvResetConfig for now, should move to separate HAL API.
2506      *
2507      * @param response Callback message.
2508      */
rebootModem(Message response)2509     public void rebootModem(Message response) {
2510         mCi.nvResetConfig(1 /* 1: reload NV reset, trigger a modem reboot */, response);
2511     }
2512 
2513     /**
2514      * Perform the modem configuration reset. Used for device configuration by some CDMA operators.
2515      * TODO: reuse nvResetConfig for now, should move to separate HAL API.
2516      *
2517      * @param response Callback message.
2518      */
resetModemConfig(Message response)2519     public void resetModemConfig(Message response) {
2520         mCi.nvResetConfig(3 /* factory NV reset */, response);
2521     }
2522 
2523     /**
2524      * Perform modem configuration erase. Used for network reset
2525      *
2526      * @param response Callback message.
2527      */
eraseModemConfig(Message response)2528     public void eraseModemConfig(Message response) {
2529         mCi.nvResetConfig(2 /* erase NV */, response);
2530     }
2531 
setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers, Message response)2532     public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
2533             Message response) {
2534         mCi.setSystemSelectionChannels(specifiers, response);
2535     }
2536 
notifyDataActivity()2537     public void notifyDataActivity() {
2538         mNotifier.notifyDataActivity(this);
2539     }
2540 
notifyMessageWaitingIndicator()2541     private void notifyMessageWaitingIndicator() {
2542         // Do not notify voice mail waiting if device doesn't support voice
2543         if (!mIsVoiceCapable)
2544             return;
2545 
2546         // This function is added to send the notification to DefaultPhoneNotifier.
2547         mNotifier.notifyMessageWaitingChanged(this);
2548     }
2549 
2550     /** Send notification with an updated PreciseDataConnectionState to a single data connection */
notifyDataConnection(String apnType)2551     public void notifyDataConnection(String apnType) {
2552         mNotifier.notifyDataConnection(this, apnType, getPreciseDataConnectionState(apnType));
2553     }
2554 
2555     /** Send notification with an updated PreciseDataConnectionState to all data connections */
notifyAllActiveDataConnections()2556     public void notifyAllActiveDataConnections() {
2557         if (mTransportManager != null) {
2558             for (int transportType : mTransportManager.getAvailableTransports()) {
2559                 DcTracker dct = getDcTracker(transportType);
2560                 if (dct != null) {
2561                     for (String apnType : dct.getConnectedApnTypes()) {
2562                         mNotifier.notifyDataConnection(
2563                                 this, apnType, getPreciseDataConnectionState(apnType));
2564                     }
2565                 }
2566             }
2567         }
2568     }
2569 
2570     @UnsupportedAppUsage
notifyOtaspChanged(int otaspMode)2571     public void notifyOtaspChanged(int otaspMode) {
2572         mOtaspRegistrants.notifyRegistrants(new AsyncResult(null, otaspMode, null));
2573     }
2574 
notifyVoiceActivationStateChanged(int state)2575     public void notifyVoiceActivationStateChanged(int state) {
2576         mNotifier.notifyVoiceActivationStateChanged(this, state);
2577     }
2578 
notifyDataActivationStateChanged(int state)2579     public void notifyDataActivationStateChanged(int state) {
2580         mNotifier.notifyDataActivationStateChanged(this, state);
2581     }
2582 
notifyUserMobileDataStateChanged(boolean state)2583     public void notifyUserMobileDataStateChanged(boolean state) {
2584         mNotifier.notifyUserMobileDataStateChanged(this, state);
2585     }
2586 
2587     /** Send notification that display info has changed. */
notifyDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo)2588     public void notifyDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) {
2589         mNotifier.notifyDisplayInfoChanged(this, telephonyDisplayInfo);
2590     }
2591 
notifySignalStrength()2592     public void notifySignalStrength() {
2593         mNotifier.notifySignalStrength(this);
2594     }
2595 
getDataConnectionState(String apnType)2596     public PhoneConstants.DataState getDataConnectionState(String apnType) {
2597         return PhoneConstants.DataState.DISCONNECTED;
2598     }
2599 
2600     /** Default implementation to get the PreciseDataConnectionState */
getPreciseDataConnectionState(String apnType)2601     public @Nullable PreciseDataConnectionState getPreciseDataConnectionState(String apnType) {
2602         return null;
2603     }
2604 
notifyCellInfo(List<CellInfo> cellInfo)2605     public void notifyCellInfo(List<CellInfo> cellInfo) {
2606         AsyncResult ar = new AsyncResult(null, cellInfo, null);
2607         mCellInfoRegistrants.notifyRegistrants(ar);
2608 
2609         mNotifier.notifyCellInfo(this, cellInfo);
2610     }
2611 
2612     /**
2613      * Registration point for PhysicalChannelConfig change.
2614      * @param h handler to notify
2615      * @param what what code of message when delivered
2616      * @param obj placed in Message.obj.userObj
2617      */
registerForPhysicalChannelConfig(Handler h, int what, Object obj)2618     public void registerForPhysicalChannelConfig(Handler h, int what, Object obj) {
2619         checkCorrectThread(h);
2620         Registrant registrant = new Registrant(h, what, obj);
2621         mPhysicalChannelConfigRegistrants.add(registrant);
2622         // notify first
2623         List<PhysicalChannelConfig> physicalChannelConfigs = getPhysicalChannelConfigList();
2624         if (physicalChannelConfigs != null) {
2625             registrant.notifyRegistrant(new AsyncResult(null, physicalChannelConfigs, null));
2626         }
2627     }
2628 
unregisterForPhysicalChannelConfig(Handler h)2629     public void unregisterForPhysicalChannelConfig(Handler h) {
2630         mPhysicalChannelConfigRegistrants.remove(h);
2631     }
2632 
2633     /** Notify {@link PhysicalChannelConfig} changes. */
notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs)2634     public void notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
2635         mPhysicalChannelConfigRegistrants.notifyRegistrants(new AsyncResult(null, configs, null));
2636     }
2637 
getPhysicalChannelConfigList()2638     public List<PhysicalChannelConfig> getPhysicalChannelConfigList() {
2639         return null;
2640     }
2641 
2642     /**
2643      * Notify listeners that SRVCC state has changed.
2644      */
notifySrvccStateChanged(int state)2645     public void notifySrvccStateChanged(int state) {
2646         mNotifier.notifySrvccStateChanged(this, state);
2647     }
2648 
2649     /** Notify the {@link EmergencyNumber} changes. */
notifyEmergencyNumberList()2650     public void notifyEmergencyNumberList() {
2651         mNotifier.notifyEmergencyNumberList(this);
2652     }
2653 
2654     /** Notify the outgoing call {@link EmergencyNumber} changes. */
notifyOutgoingEmergencyCall(EmergencyNumber emergencyNumber)2655     public void notifyOutgoingEmergencyCall(EmergencyNumber emergencyNumber) {
2656         mNotifier.notifyOutgoingEmergencyCall(this, emergencyNumber);
2657     }
2658 
2659     /** Notify the outgoing Sms {@link EmergencyNumber} changes. */
notifyOutgoingEmergencySms(EmergencyNumber emergencyNumber)2660     public void notifyOutgoingEmergencySms(EmergencyNumber emergencyNumber) {
2661         mNotifier.notifyOutgoingEmergencySms(this, emergencyNumber);
2662     }
2663 
2664     /**
2665      * @return true if a mobile originating emergency call is active
2666      */
isInEmergencyCall()2667     public boolean isInEmergencyCall() {
2668         return false;
2669     }
2670 
2671     // This property is used to handle phone process crashes, and is the same for CDMA and IMS
2672     // phones
getInEcmMode()2673     protected static boolean getInEcmMode() {
2674         return TelephonyProperties.in_ecm_mode().orElse(false);
2675     }
2676 
2677     /**
2678      * @return {@code true} if we are in emergency call back mode. This is a period where the phone
2679      * should be using as little power as possible and be ready to receive an incoming call from the
2680      * emergency operator.
2681      */
isInEcm()2682     public boolean isInEcm() {
2683         return mIsPhoneInEcmState;
2684     }
2685 
isInImsEcm()2686     public boolean isInImsEcm() {
2687         return false;
2688     }
2689 
setIsInEcm(boolean isInEcm)2690     public void setIsInEcm(boolean isInEcm) {
2691         if (!getUnitTestMode()) {
2692             TelephonyProperties.in_ecm_mode(isInEcm);
2693         }
2694         mIsPhoneInEcmState = isInEcm;
2695     }
2696 
2697     /**
2698      * @return true if this Phone is in an emergency call that caused emergency callback mode to be
2699      * canceled, false if not.
2700      */
isEcmCanceledForEmergency()2701     public boolean isEcmCanceledForEmergency() {
2702         return mEcmCanceledForEmergency;
2703     }
2704 
2705     /**
2706      * Set whether or not this Phone has an active emergency call that was placed during emergency
2707      * callback mode and caused it to be temporarily canceled.
2708      * @param isCanceled true if an emergency call was placed that caused ECM to be canceled, false
2709      *                   if it is not in this state.
2710      */
setEcmCanceledForEmergency(boolean isCanceled)2711     public void setEcmCanceledForEmergency(boolean isCanceled) {
2712         mEcmCanceledForEmergency = isCanceled;
2713     }
2714 
2715     @UnsupportedAppUsage
getVideoState(Call call)2716     private static int getVideoState(Call call) {
2717         int videoState = VideoProfile.STATE_AUDIO_ONLY;
2718         Connection conn = call.getEarliestConnection();
2719         if (conn != null) {
2720             videoState = conn.getVideoState();
2721         }
2722         return videoState;
2723     }
2724 
2725     /**
2726      * Determines if the specified call currently is or was at some point a video call, or if it is
2727      * a conference call.
2728      * @param call The call.
2729      * @return {@code true} if the call is or was a video call or is a conference call,
2730      *      {@code false} otherwise.
2731      */
isVideoCallOrConference(Call call)2732     private boolean isVideoCallOrConference(Call call) {
2733         if (call.isMultiparty()) {
2734             return true;
2735         }
2736 
2737         boolean isDowngradedVideoCall = false;
2738         if (call instanceof ImsPhoneCall) {
2739             ImsPhoneCall imsPhoneCall = (ImsPhoneCall) call;
2740             ImsCall imsCall = imsPhoneCall.getImsCall();
2741             return imsCall != null && (imsCall.isVideoCall() ||
2742                     imsCall.wasVideoCall());
2743         }
2744         return isDowngradedVideoCall;
2745     }
2746 
2747     /**
2748      * @return {@code true} if an IMS video call or IMS conference is present, false otherwise.
2749      */
isImsVideoCallOrConferencePresent()2750     public boolean isImsVideoCallOrConferencePresent() {
2751         boolean isPresent = false;
2752         if (mImsPhone != null) {
2753             isPresent = isVideoCallOrConference(mImsPhone.getForegroundCall()) ||
2754                     isVideoCallOrConference(mImsPhone.getBackgroundCall()) ||
2755                     isVideoCallOrConference(mImsPhone.getRingingCall());
2756         }
2757         Rlog.d(LOG_TAG, "isImsVideoCallOrConferencePresent: " + isPresent);
2758         return isPresent;
2759     }
2760 
2761     /**
2762      * Return a numerical identifier for the phone radio interface.
2763      * @return PHONE_TYPE_XXX as defined above.
2764      */
2765     @UnsupportedAppUsage
getPhoneType()2766     public abstract int getPhoneType();
2767 
2768     /**
2769      * Returns unread voicemail count. This count is shown when the  voicemail
2770      * notification is expanded.<p>
2771      */
getVoiceMessageCount()2772     public int getVoiceMessageCount(){
2773         return mVmCount;
2774     }
2775 
2776     /** sets the voice mail count of the phone and notifies listeners. */
setVoiceMessageCount(int countWaiting)2777     public void setVoiceMessageCount(int countWaiting) {
2778         mVmCount = countWaiting;
2779         int subId = getSubId();
2780         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2781 
2782             Rlog.d(LOG_TAG, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting +
2783                     " for mVmCountKey = " + VM_COUNT + subId + " in preferences.");
2784 
2785             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2786             SharedPreferences.Editor editor = sp.edit();
2787             editor.putInt(VM_COUNT + subId, countWaiting);
2788             editor.apply();
2789         } else {
2790             Rlog.e(LOG_TAG, "setVoiceMessageCount in sharedPreference: invalid subId " + subId);
2791         }
2792         // store voice mail count in SIM
2793         IccRecords records = UiccController.getInstance().getIccRecords(
2794                 mPhoneId, UiccController.APP_FAM_3GPP);
2795         if (records != null) {
2796             Rlog.d(LOG_TAG, "setVoiceMessageCount: updating SIM Records");
2797             records.setVoiceMessageWaiting(1, countWaiting);
2798         } else {
2799             Rlog.d(LOG_TAG, "setVoiceMessageCount: SIM Records not found");
2800         }
2801         // notify listeners of voice mail
2802         notifyMessageWaitingIndicator();
2803     }
2804 
2805     /** gets the voice mail count from preferences */
getStoredVoiceMessageCount()2806     protected int getStoredVoiceMessageCount() {
2807         int countVoiceMessages = 0;
2808         int subId = getSubId();
2809         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2810             int invalidCount = -2;  //-1 is not really invalid. It is used for unknown number of vm
2811             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2812             int countFromSP = sp.getInt(VM_COUNT + subId, invalidCount);
2813             if (countFromSP != invalidCount) {
2814                 countVoiceMessages = countFromSP;
2815                 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference for subId " + subId +
2816                         "= " + countVoiceMessages);
2817             } else {
2818                 // Check for old preference if count not found for current subId. This part of the
2819                 // code is needed only when upgrading from M to N.
2820                 String subscriberId = sp.getString(VM_ID, null);
2821                 if (subscriberId != null) {
2822                     String currentSubscriberId = getSubscriberId();
2823 
2824                     if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) {
2825                         // get voice mail count from preferences
2826                         countVoiceMessages = sp.getInt(VM_COUNT, 0);
2827                         setVoiceMessageCount(countVoiceMessages);
2828                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference = " +
2829                                 countVoiceMessages);
2830                     } else {
2831                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: returning 0 as count for " +
2832                                 "matching subscriberId not found");
2833 
2834                     }
2835                     // get rid of old preferences.
2836                     SharedPreferences.Editor editor = sp.edit();
2837                     editor.remove(VM_ID);
2838                     editor.remove(VM_COUNT);
2839                     editor.apply();
2840                 }
2841             }
2842         } else {
2843             Rlog.e(LOG_TAG, "getStoredVoiceMessageCount: invalid subId " + subId);
2844         }
2845         return countVoiceMessages;
2846     }
2847 
2848     /**
2849      * send secret dialer codes to launch arbitrary activities.
2850      * an Intent is started with the android_secret_code://<code> URI.
2851      *
2852      * @param code stripped version of secret code without *#*# prefix and #*#* suffix
2853      */
sendDialerSpecialCode(String code)2854     public void sendDialerSpecialCode(String code) {
2855         if (!TextUtils.isEmpty(code)) {
2856             final BroadcastOptions options = BroadcastOptions.makeBasic();
2857             options.setBackgroundActivityStartsAllowed(true);
2858             Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION,
2859                     Uri.parse("android_secret_code://" + code));
2860             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2861             mContext.sendBroadcast(intent, null, options.toBundle());
2862 
2863             // {@link TelephonyManager.ACTION_SECRET_CODE} will replace {@link
2864             // TelephonyIntents#SECRET_CODE_ACTION} in the next Android version. Before
2865             // that both of these two actions will be broadcast.
2866             Intent secrectCodeIntent = new Intent(TelephonyManager.ACTION_SECRET_CODE,
2867                     Uri.parse("android_secret_code://" + code));
2868             secrectCodeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2869             mContext.sendBroadcast(secrectCodeIntent, null, options.toBundle());
2870         }
2871     }
2872 
2873     /**
2874      * Returns the CDMA ERI icon index to display
2875      */
getCdmaEriIconIndex()2876     public int getCdmaEriIconIndex() {
2877         return -1;
2878     }
2879 
2880     /**
2881      * Returns the CDMA ERI icon mode,
2882      * 0 - ON
2883      * 1 - FLASHING
2884      */
getCdmaEriIconMode()2885     public int getCdmaEriIconMode() {
2886         return -1;
2887     }
2888 
2889     /**
2890      * Returns the CDMA ERI text,
2891      */
getCdmaEriText()2892     public String getCdmaEriText() {
2893         return "GSM nw, no ERI";
2894     }
2895 
2896     /**
2897      * Retrieves the MIN for CDMA phones.
2898      */
getCdmaMin()2899     public String getCdmaMin() {
2900         return null;
2901     }
2902 
2903     /**
2904      * Check if subscription data has been assigned to mMin
2905      *
2906      * return true if MIN info is ready; false otherwise.
2907      */
isMinInfoReady()2908     public boolean isMinInfoReady() {
2909         return false;
2910     }
2911 
2912     /**
2913      *  Retrieves PRL Version for CDMA phones
2914      */
getCdmaPrlVersion()2915     public String getCdmaPrlVersion(){
2916         return null;
2917     }
2918 
2919     /**
2920      * send burst DTMF tone, it can send the string as single character or multiple character
2921      * ignore if there is no active call or not valid digits string.
2922      * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
2923      * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
2924      * this api can send single character and multiple character, also, this api has response
2925      * back to caller.
2926      *
2927      * @param dtmfString is string representing the dialing digit(s) in the active call
2928      * @param on the DTMF ON length in milliseconds, or 0 for default
2929      * @param off the DTMF OFF length in milliseconds, or 0 for default
2930      * @param onComplete is the callback message when the action is processed by BP
2931      *
2932      */
sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)2933     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
2934     }
2935 
2936     /**
2937      * Sets an event to be fired when the telephony system processes
2938      * a post-dial character on an outgoing call.<p>
2939      *
2940      * Messages of type <code>what</code> will be sent to <code>h</code>.
2941      * The <code>obj</code> field of these Message's will be instances of
2942      * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
2943      * a Connection object.<p>
2944      *
2945      * Message.arg1 will be the post dial character being processed,
2946      * or 0 ('\0') if end of string.<p>
2947      *
2948      * If Connection.getPostDialState() == WAIT,
2949      * the application must call
2950      * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
2951      * Connection.proceedAfterWaitChar()} or
2952      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2953      * Connection.cancelPostDial()}
2954      * for the telephony system to continue playing the post-dial
2955      * DTMF sequence.<p>
2956      *
2957      * If Connection.getPostDialState() == WILD,
2958      * the application must call
2959      * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
2960      * Connection.proceedAfterWildChar()}
2961      * or
2962      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2963      * Connection.cancelPostDial()}
2964      * for the telephony system to continue playing the
2965      * post-dial DTMF sequence.<p>
2966      *
2967      * Only one post dial character handler may be set. <p>
2968      * Calling this method with "h" equal to null unsets this handler.<p>
2969      */
2970     @UnsupportedAppUsage
setOnPostDialCharacter(Handler h, int what, Object obj)2971     public void setOnPostDialCharacter(Handler h, int what, Object obj) {
2972         mPostDialHandler = new Registrant(h, what, obj);
2973     }
2974 
getPostDialHandler()2975     public Registrant getPostDialHandler() {
2976         return mPostDialHandler;
2977     }
2978 
2979     /**
2980      * request to exit emergency call back mode
2981      * the caller should use setOnECMModeExitResponse
2982      * to receive the emergency callback mode exit response
2983      */
2984     @UnsupportedAppUsage
exitEmergencyCallbackMode()2985     public void exitEmergencyCallbackMode() {
2986     }
2987 
2988     /**
2989      * Register for notifications when CDMA OTA Provision status change
2990      *
2991      * @param h Handler that receives the notification message.
2992      * @param what User-defined message code.
2993      * @param obj User object.
2994      */
registerForCdmaOtaStatusChange(Handler h, int what, Object obj)2995     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
2996     }
2997 
2998     /**
2999      * Unregister for notifications when CDMA OTA Provision status change
3000      * @param h Handler to be removed from the registrant list.
3001      */
unregisterForCdmaOtaStatusChange(Handler h)3002     public void unregisterForCdmaOtaStatusChange(Handler h) {
3003     }
3004 
3005     /**
3006      * Registration point for subscription info ready
3007      * @param h handler to notify
3008      * @param what what code of message when delivered
3009      * @param obj placed in Message.obj
3010      */
registerForSubscriptionInfoReady(Handler h, int what, Object obj)3011     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
3012     }
3013 
3014     /**
3015      * Unregister for notifications for subscription info
3016      * @param h Handler to be removed from the registrant list.
3017      */
unregisterForSubscriptionInfoReady(Handler h)3018     public void unregisterForSubscriptionInfoReady(Handler h) {
3019     }
3020 
3021     /**
3022      * Returns true if OTA Service Provisioning needs to be performed.
3023      */
3024     @UnsupportedAppUsage
needsOtaServiceProvisioning()3025     public boolean needsOtaServiceProvisioning() {
3026         return false;
3027     }
3028 
3029     /**
3030      * this decides if the dial number is OTA(Over the air provision) number or not
3031      * @param dialStr is string representing the dialing digit(s)
3032      * @return  true means the dialStr is OTA number, and false means the dialStr is not OTA number
3033      */
isOtaSpNumber(String dialStr)3034     public  boolean isOtaSpNumber(String dialStr) {
3035         return false;
3036     }
3037 
3038     /**
3039      * Register for notifications when OTA Service Provisioning mode has changed.
3040      *
3041      * <p>The mode is integer. {@link TelephonyManager#OTASP_UNKNOWN}
3042      * means the value is currently unknown and the system should wait until
3043      * {@link TelephonyManager#OTASP_NEEDED} or {@link TelephonyManager#OTASP_NOT_NEEDED} is
3044      * received before making the decision to perform OTASP or not.
3045      *
3046      * @param h Handler that receives the notification message.
3047      * @param what User-defined message code.
3048      * @param obj User object.
3049      */
registerForOtaspChange(Handler h, int what, Object obj)3050     public void registerForOtaspChange(Handler h, int what, Object obj) {
3051         checkCorrectThread(h);
3052         mOtaspRegistrants.addUnique(h, what, obj);
3053         // notify first
3054         new Registrant(h, what, obj).notifyRegistrant(new AsyncResult(null, getOtasp(), null));
3055     }
3056 
3057     /**
3058      * Unegister for notifications when OTA Service Provisioning mode has changed.
3059      * @param h Handler to be removed from the registrant list.
3060      */
unregisterForOtaspChange(Handler h)3061     public void unregisterForOtaspChange(Handler h) {
3062         mOtaspRegistrants.remove(h);
3063     }
3064 
3065     /**
3066      * Returns the current OTA Service Provisioning mode.
3067      *
3068      * @see registerForOtaspChange
3069      */
getOtasp()3070     public int getOtasp() {
3071         return TelephonyManager.OTASP_UNKNOWN;
3072     }
3073 
3074     /**
3075      * Register for notifications when CDMA call waiting comes
3076      *
3077      * @param h Handler that receives the notification message.
3078      * @param what User-defined message code.
3079      * @param obj User object.
3080      */
registerForCallWaiting(Handler h, int what, Object obj)3081     public void registerForCallWaiting(Handler h, int what, Object obj){
3082     }
3083 
3084     /**
3085      * Unegister for notifications when CDMA Call waiting comes
3086      * @param h Handler to be removed from the registrant list.
3087      */
unregisterForCallWaiting(Handler h)3088     public void unregisterForCallWaiting(Handler h){
3089     }
3090 
3091     /**
3092      * Registration point for Ecm timer reset
3093      * @param h handler to notify
3094      * @param what user-defined message code
3095      * @param obj placed in Message.obj
3096      */
3097     @UnsupportedAppUsage
registerForEcmTimerReset(Handler h, int what, Object obj)3098     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
3099     }
3100 
3101     /**
3102      * Unregister for notification for Ecm timer reset
3103      * @param h Handler to be removed from the registrant list.
3104      */
3105     @UnsupportedAppUsage
unregisterForEcmTimerReset(Handler h)3106     public void unregisterForEcmTimerReset(Handler h) {
3107     }
3108 
3109     /**
3110      * Register for signal information notifications from the network.
3111      * Message.obj will contain an AsyncResult.
3112      * AsyncResult.result will be a SuppServiceNotification instance.
3113      *
3114      * @param h Handler that receives the notification message.
3115      * @param what User-defined message code.
3116      * @param obj User object.
3117      */
registerForSignalInfo(Handler h, int what, Object obj)3118     public void registerForSignalInfo(Handler h, int what, Object obj) {
3119         mCi.registerForSignalInfo(h, what, obj);
3120     }
3121 
3122     /**
3123      * Unregisters for signal information notifications.
3124      * Extraneous calls are tolerated silently
3125      *
3126      * @param h Handler to be removed from the registrant list.
3127      */
unregisterForSignalInfo(Handler h)3128     public void unregisterForSignalInfo(Handler h) {
3129         mCi.unregisterForSignalInfo(h);
3130     }
3131 
3132     /**
3133      * Register for display information notifications from the network.
3134      * Message.obj will contain an AsyncResult.
3135      * AsyncResult.result will be a SuppServiceNotification instance.
3136      *
3137      * @param h Handler that receives the notification message.
3138      * @param what User-defined message code.
3139      * @param obj User object.
3140      */
registerForDisplayInfo(Handler h, int what, Object obj)3141     public void registerForDisplayInfo(Handler h, int what, Object obj) {
3142         mCi.registerForDisplayInfo(h, what, obj);
3143     }
3144 
3145     /**
3146      * Unregisters for display information notifications.
3147      * Extraneous calls are tolerated silently
3148      *
3149      * @param h Handler to be removed from the registrant list.
3150      */
unregisterForDisplayInfo(Handler h)3151     public void unregisterForDisplayInfo(Handler h) {
3152          mCi.unregisterForDisplayInfo(h);
3153     }
3154 
3155     /**
3156      * Register for CDMA number information record notification from the network.
3157      * Message.obj will contain an AsyncResult.
3158      * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
3159      * instance.
3160      *
3161      * @param h Handler that receives the notification message.
3162      * @param what User-defined message code.
3163      * @param obj User object.
3164      */
registerForNumberInfo(Handler h, int what, Object obj)3165     public void registerForNumberInfo(Handler h, int what, Object obj) {
3166         mCi.registerForNumberInfo(h, what, obj);
3167     }
3168 
3169     /**
3170      * Unregisters for number information record notifications.
3171      * Extraneous calls are tolerated silently
3172      *
3173      * @param h Handler to be removed from the registrant list.
3174      */
unregisterForNumberInfo(Handler h)3175     public void unregisterForNumberInfo(Handler h) {
3176         mCi.unregisterForNumberInfo(h);
3177     }
3178 
3179     /**
3180      * Register for CDMA redirected number information record notification
3181      * from the network.
3182      * Message.obj will contain an AsyncResult.
3183      * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
3184      * instance.
3185      *
3186      * @param h Handler that receives the notification message.
3187      * @param what User-defined message code.
3188      * @param obj User object.
3189      */
registerForRedirectedNumberInfo(Handler h, int what, Object obj)3190     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
3191         mCi.registerForRedirectedNumberInfo(h, what, obj);
3192     }
3193 
3194     /**
3195      * Unregisters for redirected number information record notification.
3196      * Extraneous calls are tolerated silently
3197      *
3198      * @param h Handler to be removed from the registrant list.
3199      */
unregisterForRedirectedNumberInfo(Handler h)3200     public void unregisterForRedirectedNumberInfo(Handler h) {
3201         mCi.unregisterForRedirectedNumberInfo(h);
3202     }
3203 
3204     /**
3205      * Register for CDMA line control information record notification
3206      * from the network.
3207      * Message.obj will contain an AsyncResult.
3208      * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
3209      * instance.
3210      *
3211      * @param h Handler that receives the notification message.
3212      * @param what User-defined message code.
3213      * @param obj User object.
3214      */
registerForLineControlInfo(Handler h, int what, Object obj)3215     public void registerForLineControlInfo(Handler h, int what, Object obj) {
3216         mCi.registerForLineControlInfo(h, what, obj);
3217     }
3218 
3219     /**
3220      * Unregisters for line control information notifications.
3221      * Extraneous calls are tolerated silently
3222      *
3223      * @param h Handler to be removed from the registrant list.
3224      */
unregisterForLineControlInfo(Handler h)3225     public void unregisterForLineControlInfo(Handler h) {
3226         mCi.unregisterForLineControlInfo(h);
3227     }
3228 
3229     /**
3230      * Register for CDMA T53 CLIR information record notifications
3231      * from the network.
3232      * Message.obj will contain an AsyncResult.
3233      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
3234      * instance.
3235      *
3236      * @param h Handler that receives the notification message.
3237      * @param what User-defined message code.
3238      * @param obj User object.
3239      */
registerFoT53ClirlInfo(Handler h, int what, Object obj)3240     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
3241         mCi.registerFoT53ClirlInfo(h, what, obj);
3242     }
3243 
3244     /**
3245      * Unregisters for T53 CLIR information record notification
3246      * Extraneous calls are tolerated silently
3247      *
3248      * @param h Handler to be removed from the registrant list.
3249      */
unregisterForT53ClirInfo(Handler h)3250     public void unregisterForT53ClirInfo(Handler h) {
3251         mCi.unregisterForT53ClirInfo(h);
3252     }
3253 
3254     /**
3255      * Register for CDMA T53 audio control information record notifications
3256      * from the network.
3257      * Message.obj will contain an AsyncResult.
3258      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
3259      * instance.
3260      *
3261      * @param h Handler that receives the notification message.
3262      * @param what User-defined message code.
3263      * @param obj User object.
3264      */
registerForT53AudioControlInfo(Handler h, int what, Object obj)3265     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
3266         mCi.registerForT53AudioControlInfo(h, what, obj);
3267     }
3268 
3269     /**
3270      * Unregisters for T53 audio control information record notifications.
3271      * Extraneous calls are tolerated silently
3272      *
3273      * @param h Handler to be removed from the registrant list.
3274      */
unregisterForT53AudioControlInfo(Handler h)3275     public void unregisterForT53AudioControlInfo(Handler h) {
3276         mCi.unregisterForT53AudioControlInfo(h);
3277     }
3278 
3279     /**
3280      * registers for exit emergency call back mode request response
3281      *
3282      * @param h Handler that receives the notification message.
3283      * @param what User-defined message code.
3284      * @param obj User object.
3285      */
3286     @UnsupportedAppUsage
setOnEcbModeExitResponse(Handler h, int what, Object obj)3287     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
3288     }
3289 
3290     /**
3291      * Unregisters for exit emergency call back mode request response
3292      *
3293      * @param h Handler to be removed from the registrant list.
3294      */
3295     @UnsupportedAppUsage
unsetOnEcbModeExitResponse(Handler h)3296     public void unsetOnEcbModeExitResponse(Handler h){
3297     }
3298 
3299     /**
3300      * Register for radio off or not available
3301      *
3302      * @param h Handler that receives the notification message.
3303      * @param what User-defined message code.
3304      * @param obj User object.
3305      */
registerForRadioOffOrNotAvailable(Handler h, int what, Object obj)3306     public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) {
3307         mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj);
3308     }
3309 
3310     /**
3311      * Unregisters for radio off or not available
3312      *
3313      * @param h Handler to be removed from the registrant list.
3314      */
unregisterForRadioOffOrNotAvailable(Handler h)3315     public void unregisterForRadioOffOrNotAvailable(Handler h) {
3316         mRadioOffOrNotAvailableRegistrants.remove(h);
3317     }
3318 
3319     /**
3320      * Returns an array of string identifiers for the APN types serviced by the
3321      * currently active subscription.
3322      *
3323      * @return The string array of APN types. Return null if no active APN types.
3324      */
3325     @UnsupportedAppUsage
3326     @NonNull
getActiveApnTypes()3327     public String[] getActiveApnTypes() {
3328         if (mTransportManager == null || mDcTrackers == null)  {
3329             Rlog.e(LOG_TAG, "Invalid state for Transport/DcTrackers");
3330             return new String[0];
3331         }
3332 
3333         Set<String> activeApnTypes = new HashSet<String>();
3334         for (int transportType : mTransportManager.getAvailableTransports()) {
3335             DcTracker dct = getDcTracker(transportType);
3336             if (dct == null) continue; // TODO: should this ever happen?
3337             activeApnTypes.addAll(Arrays.asList(dct.getActiveApnTypes()));
3338         }
3339 
3340         return activeApnTypes.toArray(new String[activeApnTypes.size()]);
3341     }
3342 
3343     /**
3344      * Check if there are matching tethering (i.e DUN) for the carrier.
3345      * @return true if there is a matching DUN APN.
3346      */
hasMatchedTetherApnSetting()3347     public boolean hasMatchedTetherApnSetting() {
3348         if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
3349             return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
3350                     .hasMatchedTetherApnSetting();
3351         }
3352         return false;
3353     }
3354 
3355     /**
3356      * Returns string for the active APN host.
3357      *  @return type as a string or null if none.
3358      */
getActiveApnHost(String apnType)3359     public String getActiveApnHost(String apnType) {
3360         if (mTransportManager != null) {
3361             int transportType = mTransportManager.getCurrentTransport(
3362                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3363             if (getDcTracker(transportType) != null) {
3364                 return getDcTracker(transportType).getActiveApnString(apnType);
3365             }
3366         }
3367 
3368         return null;
3369     }
3370 
3371     /**
3372      * Return the LinkProperties for the named apn or null if not available
3373      */
getLinkProperties(String apnType)3374     public LinkProperties getLinkProperties(String apnType) {
3375         if (mTransportManager != null) {
3376             int transport = mTransportManager.getCurrentTransport(
3377                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3378             if (getDcTracker(transport) != null) {
3379                 return getDcTracker(transport).getLinkProperties(apnType);
3380             }
3381         }
3382         return null;
3383     }
3384 
3385     /**
3386      * Return the NetworkCapabilities
3387      */
getNetworkCapabilities(String apnType)3388     public NetworkCapabilities getNetworkCapabilities(String apnType) {
3389         if (mTransportManager != null) {
3390             int transportType = mTransportManager.getCurrentTransport(
3391                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3392             if (getDcTracker(transportType) != null) {
3393                 return getDcTracker(transportType).getNetworkCapabilities(apnType);
3394             }
3395         }
3396         return null;
3397     }
3398 
3399     /**
3400      * Report on whether data connectivity is allowed for given APN type.
3401      *
3402      * @param apnType APN type
3403      *
3404      * @return True if data is allowed to be established.
3405      */
isDataAllowed(@pnType int apnType)3406     public boolean isDataAllowed(@ApnType int apnType) {
3407         return isDataAllowed(apnType, null);
3408     }
3409 
3410     /**
3411      * Report on whether data connectivity is allowed.
3412      *
3413      * @param apnType APN type
3414      * @param reasons The reasons that data can/can't be established. This is an output param.
3415      * @return True if data is allowed to be established
3416      */
isDataAllowed(@pnType int apnType, DataConnectionReasons reasons)3417     public boolean isDataAllowed(@ApnType int apnType, DataConnectionReasons reasons) {
3418         if (mTransportManager != null) {
3419             int transport = mTransportManager.getCurrentTransport(apnType);
3420             if (getDcTracker(transport) != null) {
3421                 return getDcTracker(transport).isDataAllowed(reasons);
3422             }
3423         }
3424         return false;
3425     }
3426 
3427 
3428     /**
3429      * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
3430      */
carrierActionSetMeteredApnsEnabled(boolean enabled)3431     public void carrierActionSetMeteredApnsEnabled(boolean enabled) {
3432         mCarrierActionAgent.carrierActionSetMeteredApnsEnabled(enabled);
3433     }
3434 
3435     /**
3436      * Action set from carrier signalling broadcast receivers to enable/disable radio
3437      */
carrierActionSetRadioEnabled(boolean enabled)3438     public void carrierActionSetRadioEnabled(boolean enabled) {
3439         mCarrierActionAgent.carrierActionSetRadioEnabled(enabled);
3440     }
3441 
3442     /**
3443      * Action set from carrier app to start/stop reporting default network condition.
3444      */
carrierActionReportDefaultNetworkStatus(boolean report)3445     public void carrierActionReportDefaultNetworkStatus(boolean report) {
3446         mCarrierActionAgent.carrierActionReportDefaultNetworkStatus(report);
3447     }
3448 
3449     /**
3450      * Action set from carrier signalling broadcast receivers to reset all carrier actions
3451      */
carrierActionResetAll()3452     public void carrierActionResetAll() {
3453         mCarrierActionAgent.carrierActionReset();
3454     }
3455 
3456     /**
3457      * Notify registrants of a new ringing Connection.
3458      * Subclasses of Phone probably want to replace this with a
3459      * version scoped to their packages
3460      */
notifyNewRingingConnectionP(Connection cn)3461     public void notifyNewRingingConnectionP(Connection cn) {
3462         if (!mIsVoiceCapable)
3463             return;
3464         AsyncResult ar = new AsyncResult(null, cn, null);
3465         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
3466     }
3467 
3468     /**
3469      * Notify registrants of a new unknown connection.
3470      */
notifyUnknownConnectionP(Connection cn)3471     public void notifyUnknownConnectionP(Connection cn) {
3472         mUnknownConnectionRegistrants.notifyResult(cn);
3473     }
3474 
3475     /**
3476      * Notify registrants if phone is video capable.
3477      */
notifyForVideoCapabilityChanged(boolean isVideoCallCapable)3478     public void notifyForVideoCapabilityChanged(boolean isVideoCallCapable) {
3479         // Cache the current video capability so that we don't lose the information.
3480         mIsVideoCapable = isVideoCallCapable;
3481 
3482         AsyncResult ar = new AsyncResult(null, isVideoCallCapable, null);
3483         mVideoCapabilityChangedRegistrants.notifyRegistrants(ar);
3484     }
3485 
3486     /**
3487      * Notify registrants of a RING event.
3488      */
notifyIncomingRing()3489     private void notifyIncomingRing() {
3490         if (!mIsVoiceCapable)
3491             return;
3492         AsyncResult ar = new AsyncResult(null, this, null);
3493         mIncomingRingRegistrants.notifyRegistrants(ar);
3494     }
3495 
3496     /**
3497      * Send the incoming call Ring notification if conditions are right.
3498      */
sendIncomingCallRingNotification(int token)3499     private void sendIncomingCallRingNotification(int token) {
3500         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
3501                 (token == mCallRingContinueToken)) {
3502             Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
3503             notifyIncomingRing();
3504             sendMessageDelayed(
3505                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
3506         } else {
3507             Rlog.d(LOG_TAG, "Ignoring ring notification request,"
3508                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
3509                     + " token=" + token
3510                     + " mCallRingContinueToken=" + mCallRingContinueToken
3511                     + " mIsVoiceCapable=" + mIsVoiceCapable);
3512         }
3513     }
3514 
3515     /**
3516      * Enable or disable always reporting signal strength changes from radio.
3517      *
3518      * @param isEnable {@code true} for enabling; {@code false} for disabling.
3519      */
setAlwaysReportSignalStrength(boolean isEnable)3520     public void setAlwaysReportSignalStrength(boolean isEnable) {
3521         if (mDeviceStateMonitor != null) {
3522             mDeviceStateMonitor.setAlwaysReportSignalStrength(isEnable);
3523         }
3524     }
3525 
3526     /**
3527      * TODO: Adding a function for each property is not good.
3528      * A fucntion of type getPhoneProp(propType) where propType is an
3529      * enum of GSM+CDMA+LTE props would be a better approach.
3530      *
3531      * Get "Restriction of menu options for manual PLMN selection" bit
3532      * status from EF_CSP data, this belongs to "Value Added Services Group".
3533      * @return true if this bit is set or EF_CSP data is unavailable,
3534      * false otherwise
3535      */
3536     @UnsupportedAppUsage
isCspPlmnEnabled()3537     public boolean isCspPlmnEnabled() {
3538         return false;
3539     }
3540 
3541     /**
3542      * Return an interface to retrieve the ISIM records for IMS, if available.
3543      * @return the interface to retrieve the ISIM records, or null if not supported
3544      */
3545     @UnsupportedAppUsage
getIsimRecords()3546     public IsimRecords getIsimRecords() {
3547         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
3548         return null;
3549     }
3550 
3551     /**
3552      * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to
3553      * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns
3554      * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones.
3555      */
3556     @UnsupportedAppUsage
getMsisdn()3557     public String getMsisdn() {
3558         return null;
3559     }
3560 
3561     /**
3562      * Retrieves the EF_PNN from the UICC For GSM/UMTS phones.
3563      */
getPlmn()3564     public String getPlmn() {
3565         return null;
3566     }
3567 
3568     /**
3569      * Get the current for the default apn DataState. No change notification
3570      * exists at this interface -- use
3571      * {@link android.telephony.PhoneStateListener} instead.
3572      */
3573     @UnsupportedAppUsage
getDataConnectionState()3574     public PhoneConstants.DataState getDataConnectionState() {
3575         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
3576     }
3577 
notifyCallForwardingIndicator()3578     public void notifyCallForwardingIndicator() {
3579     }
3580 
3581     /** Send a notification that a particular data connection has failed with specified cause. */
notifyDataConnectionFailed( String apnType, String apn, @DataFailureCause int failCause)3582     public void notifyDataConnectionFailed(
3583             String apnType, String apn, @DataFailureCause int failCause) {
3584         mNotifier.notifyDataConnectionFailed(this, apnType, apn, failCause);
3585     }
3586 
3587     /**
3588      * Return if the current radio is LTE on CDMA. This
3589      * is a tri-state return value as for a period of time
3590      * the mode may be unknown.
3591      *
3592      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
3593      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
3594      */
getLteOnCdmaMode()3595     public int getLteOnCdmaMode() {
3596         return mCi.getLteOnCdmaMode();
3597     }
3598 
3599     /**
3600      * Sets the SIM voice message waiting indicator records.
3601      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
3602      * @param countWaiting The number of messages waiting, if known. Use
3603      *                     -1 to indicate that an unknown number of
3604      *                      messages are waiting
3605      */
setVoiceMessageWaiting(int line, int countWaiting)3606     public void setVoiceMessageWaiting(int line, int countWaiting) {
3607         // This function should be overridden by class GsmCdmaPhone.
3608         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone.");
3609     }
3610 
3611     /**
3612      * Gets the USIM service table from the UICC, if present and available.
3613      * @return an interface to the UsimServiceTable record, or null if not available
3614      */
getUsimServiceTable()3615     public UsimServiceTable getUsimServiceTable() {
3616         IccRecords r = mIccRecords.get();
3617         return (r != null) ? r.getUsimServiceTable() : null;
3618     }
3619 
3620     /**
3621      * Gets the Uicc card corresponding to this phone.
3622      * @return the UiccCard object corresponding to the phone ID.
3623      */
3624     @UnsupportedAppUsage
getUiccCard()3625     public UiccCard getUiccCard() {
3626         return mUiccController.getUiccCard(mPhoneId);
3627     }
3628 
3629     /**
3630      * Get P-CSCF address from PCO after data connection is established or modified.
3631      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
3632      */
getPcscfAddress(String apnType)3633     public String[] getPcscfAddress(String apnType) {
3634         if (mTransportManager != null) {
3635             int transportType = mTransportManager.getCurrentTransport(
3636                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3637             if (getDcTracker(transportType) != null) {
3638                 return getDcTracker(transportType).getPcscfAddress(apnType);
3639             }
3640         }
3641 
3642         return null;
3643     }
3644 
3645     /**
3646      * Set IMS registration state
3647      */
setImsRegistrationState(boolean registered)3648     public void setImsRegistrationState(boolean registered) {
3649     }
3650 
3651     /**
3652      * Return an instance of a IMS phone
3653      */
3654     @UnsupportedAppUsage
getImsPhone()3655     public Phone getImsPhone() {
3656         return mImsPhone;
3657     }
3658 
3659     /**
3660      * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
3661      * @param keyType whether the key is being used for WLAN or ePDG.
3662      * @return ImsiEncryptionInfo which includes the Key Type, the Public Key
3663      *        {@link java.security.PublicKey} and the Key Identifier.
3664      *        The keyIdentifier This is used by the server to help it locate the private key to
3665      *        decrypt the permanent identity.
3666      */
getCarrierInfoForImsiEncryption(int keyType)3667     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) {
3668         return null;
3669     }
3670 
3671     /**
3672      * Sets the carrier information needed to encrypt the IMSI and IMPI.
3673      * @param imsiEncryptionInfo Carrier specific information that will be used to encrypt the
3674      *        IMSI and IMPI. This includes the Key type, the Public key
3675      *        {@link java.security.PublicKey} and the Key identifier.
3676      */
setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo)3677     public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo) {
3678         return;
3679     }
3680 
3681     /**
3682      * Deletes all the keys for a given Carrier from the device keystore.
3683      */
deleteCarrierInfoForImsiEncryption()3684     public void deleteCarrierInfoForImsiEncryption() {
3685         return;
3686     }
3687 
getCarrierId()3688     public int getCarrierId() {
3689         return TelephonyManager.UNKNOWN_CARRIER_ID;
3690     }
3691 
getCarrierName()3692     public String getCarrierName() {
3693         return null;
3694     }
3695 
getMNOCarrierId()3696     public int getMNOCarrierId() {
3697         return TelephonyManager.UNKNOWN_CARRIER_ID;
3698     }
3699 
getSpecificCarrierId()3700     public int getSpecificCarrierId() {
3701         return TelephonyManager.UNKNOWN_CARRIER_ID;
3702     }
3703 
getSpecificCarrierName()3704     public String getSpecificCarrierName() {
3705         return null;
3706     }
3707 
getCarrierIdListVersion()3708     public int getCarrierIdListVersion() {
3709         return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
3710     }
3711 
getEmergencyNumberDbVersion()3712     public int getEmergencyNumberDbVersion() {
3713         return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
3714     }
3715 
resolveSubscriptionCarrierId(String simState)3716     public void resolveSubscriptionCarrierId(String simState) {
3717     }
3718 
3719     /**
3720      *  Resets the Carrier Keys in the database. This involves 2 steps:
3721      *  1. Delete the keys from the database.
3722      *  2. Send an intent to download new Certificates.
3723      */
resetCarrierKeysForImsiEncryption()3724     public void resetCarrierKeysForImsiEncryption() {
3725         return;
3726     }
3727 
3728     /**
3729      * Return if UT capability of ImsPhone is enabled or not
3730      */
3731     @UnsupportedAppUsage
isUtEnabled()3732     public boolean isUtEnabled() {
3733         if (mImsPhone != null) {
3734             return mImsPhone.isUtEnabled();
3735         }
3736         return false;
3737     }
3738 
3739     @UnsupportedAppUsage
dispose()3740     public void dispose() {
3741     }
3742 
3743     /**
3744      * Dials a number.
3745      *
3746      * @param dialString The number to dial.
3747      * @param dialArgs Parameters to dial with.
3748      * @return The Connection.
3749      * @throws CallStateException
3750      */
dialInternal(String dialString, DialArgs dialArgs)3751     protected Connection dialInternal(String dialString, DialArgs dialArgs)
3752             throws CallStateException {
3753         // dialInternal shall be overriden by GsmCdmaPhone
3754         return null;
3755     }
3756 
3757     /*
3758      * Returns the subscription id.
3759      */
3760     @UnsupportedAppUsage
getSubId()3761     public int getSubId() {
3762         if (SubscriptionController.getInstance() == null) {
3763             // TODO b/78359408 getInstance sometimes returns null in Treehugger tests, which causes
3764             // flakiness. Even though we haven't seen this crash in the wild we should keep this
3765             // check in until we've figured out the root cause.
3766             Rlog.e(LOG_TAG, "SubscriptionController.getInstance = null! Returning default subId");
3767             return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
3768         }
3769         return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId);
3770     }
3771 
3772     /**
3773      * Returns the phone id.
3774      */
3775     @UnsupportedAppUsage
getPhoneId()3776     public int getPhoneId() {
3777         return mPhoneId;
3778     }
3779 
3780     /**
3781      * Return the service state of mImsPhone if it is STATE_IN_SERVICE
3782      * otherwise return the current voice service state
3783      */
getVoicePhoneServiceState()3784     public int getVoicePhoneServiceState() {
3785         Phone imsPhone = mImsPhone;
3786         if (imsPhone != null
3787                 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
3788             return ServiceState.STATE_IN_SERVICE;
3789         }
3790         return getServiceState().getState();
3791     }
3792 
3793     /**
3794      * Override the service provider name and the operator name for the current ICCID.
3795      */
setOperatorBrandOverride(String brand)3796     public boolean setOperatorBrandOverride(String brand) {
3797         return false;
3798     }
3799 
3800     /**
3801      * Override the roaming indicator for the current ICCID.
3802      */
setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)3803     public boolean setRoamingOverride(List<String> gsmRoamingList,
3804             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3805             List<String> cdmaNonRoamingList) {
3806         String iccId = getIccSerialNumber();
3807         if (TextUtils.isEmpty(iccId)) {
3808             return false;
3809         }
3810 
3811         setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3812         setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3813         setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3814         setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3815 
3816         // Refresh.
3817         ServiceStateTracker tracker = getServiceStateTracker();
3818         if (tracker != null) {
3819             tracker.pollState();
3820         }
3821         return true;
3822     }
3823 
setRoamingOverrideHelper(List<String> list, String prefix, String iccId)3824     private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) {
3825         SharedPreferences.Editor spEditor =
3826                 PreferenceManager.getDefaultSharedPreferences(mContext).edit();
3827         String key = prefix + iccId;
3828         if (list == null || list.isEmpty()) {
3829             spEditor.remove(key).commit();
3830         } else {
3831             spEditor.putStringSet(key, new HashSet<String>(list)).commit();
3832         }
3833     }
3834 
isMccMncMarkedAsRoaming(String mccMnc)3835     public boolean isMccMncMarkedAsRoaming(String mccMnc) {
3836         return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
3837     }
3838 
isMccMncMarkedAsNonRoaming(String mccMnc)3839     public boolean isMccMncMarkedAsNonRoaming(String mccMnc) {
3840         return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
3841     }
3842 
isSidMarkedAsRoaming(int SID)3843     public boolean isSidMarkedAsRoaming(int SID) {
3844         return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX,
3845                 Integer.toString(SID));
3846     }
3847 
isSidMarkedAsNonRoaming(int SID)3848     public boolean isSidMarkedAsNonRoaming(int SID) {
3849         return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX,
3850                 Integer.toString(SID));
3851     }
3852 
3853     /**
3854      * Query the IMS Registration Status.
3855      *
3856      * @return true if IMS is Registered
3857      */
isImsRegistered()3858     public boolean isImsRegistered() {
3859         Phone imsPhone = mImsPhone;
3860         boolean isImsRegistered = false;
3861         if (imsPhone != null) {
3862             isImsRegistered = imsPhone.isImsRegistered();
3863         } else {
3864             ServiceStateTracker sst = getServiceStateTracker();
3865             if (sst != null) {
3866                 isImsRegistered = sst.isImsRegistered();
3867             }
3868         }
3869         Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered);
3870         return isImsRegistered;
3871     }
3872 
3873     /**
3874      * Get Wifi Calling Feature Availability
3875      */
3876     @UnsupportedAppUsage
isWifiCallingEnabled()3877     public boolean isWifiCallingEnabled() {
3878         Phone imsPhone = mImsPhone;
3879         boolean isWifiCallingEnabled = false;
3880         if (imsPhone != null) {
3881             isWifiCallingEnabled = imsPhone.isWifiCallingEnabled();
3882         }
3883         Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled);
3884         return isWifiCallingEnabled;
3885     }
3886 
3887     /**
3888      * @return true if the IMS capability for the registration technology specified is available,
3889      * false otherwise.
3890      */
isImsCapabilityAvailable(int capability, int regTech)3891     public boolean isImsCapabilityAvailable(int capability, int regTech) throws ImsException {
3892         Phone imsPhone = mImsPhone;
3893         boolean isAvailable = false;
3894         if (imsPhone != null) {
3895             isAvailable = imsPhone.isImsCapabilityAvailable(capability, regTech);
3896         }
3897         Rlog.d(LOG_TAG, "isImsRegistered =" + isAvailable);
3898         return isAvailable;
3899     }
3900 
3901     /**
3902      * Get Volte Feature Availability
3903      */
3904     @UnsupportedAppUsage
isVolteEnabled()3905     public boolean isVolteEnabled() {
3906         Phone imsPhone = mImsPhone;
3907         boolean isVolteEnabled = false;
3908         if (imsPhone != null) {
3909             isVolteEnabled = imsPhone.isVolteEnabled();
3910         }
3911         Rlog.d(LOG_TAG, "isImsRegistered =" + isVolteEnabled);
3912         return isVolteEnabled;
3913     }
3914 
3915     /**
3916      * @return the IMS MmTel Registration technology for this Phone, defined in
3917      * {@link ImsRegistrationImplBase}.
3918      */
getImsRegistrationTech()3919     public int getImsRegistrationTech() {
3920         Phone imsPhone = mImsPhone;
3921         int regTech = ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
3922         if (imsPhone != null) {
3923             regTech = imsPhone.getImsRegistrationTech();
3924         }
3925         Rlog.d(LOG_TAG, "getImsRegistrationTechnology =" + regTech);
3926         return regTech;
3927     }
3928 
3929     /**
3930      * Get the IMS MmTel Registration technology for this Phone, defined in
3931      * {@link ImsRegistrationImplBase}.
3932      */
getImsRegistrationTech(Consumer<Integer> callback)3933     public void getImsRegistrationTech(Consumer<Integer> callback) {
3934         Phone imsPhone = mImsPhone;
3935         if (imsPhone != null) {
3936             imsPhone.getImsRegistrationTech(callback);
3937         } else {
3938             callback.accept(ImsRegistrationImplBase.REGISTRATION_TECH_NONE);
3939         }
3940     }
3941 
3942     /**
3943      * Asynchronously get the IMS MmTel Registration state for this Phone.
3944      */
getImsRegistrationState(Consumer<Integer> callback)3945     public void getImsRegistrationState(Consumer<Integer> callback) {
3946         Phone imsPhone = mImsPhone;
3947         if (imsPhone != null) {
3948             imsPhone.getImsRegistrationState(callback);
3949         }
3950         callback.accept(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
3951     }
3952 
3953 
getRoamingOverrideHelper(String prefix, String key)3954     private boolean getRoamingOverrideHelper(String prefix, String key) {
3955         String iccId = getIccSerialNumber();
3956         if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) {
3957             return false;
3958         }
3959 
3960         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
3961         Set<String> value = sp.getStringSet(prefix + iccId, null);
3962         if (value == null) {
3963             return false;
3964         }
3965         return value.contains(key);
3966     }
3967 
3968     /**
3969      * @return returns the latest radio state from the modem
3970      */
getRadioPowerState()3971     public int getRadioPowerState() {
3972         return mCi.getRadioState();
3973     }
3974 
3975     /**
3976      * Is Radio Present on the device and is it accessible
3977      */
isRadioAvailable()3978     public boolean isRadioAvailable() {
3979         return mCi.getRadioState() != TelephonyManager.RADIO_POWER_UNAVAILABLE;
3980     }
3981 
3982     /**
3983      * Is Radio turned on
3984      */
isRadioOn()3985     public boolean isRadioOn() {
3986         return mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON;
3987     }
3988 
3989     /**
3990      * shutdown Radio gracefully
3991      */
shutdownRadio()3992     public void shutdownRadio() {
3993         getServiceStateTracker().requestShutdown();
3994     }
3995 
3996     /**
3997      * Return true if the device is shutting down.
3998      */
isShuttingDown()3999     public boolean isShuttingDown() {
4000         return getServiceStateTracker().isDeviceShuttingDown();
4001     }
4002 
4003     /**
4004      *  Set phone radio capability
4005      *
4006      *  @param rc the phone radio capability defined in
4007      *         RadioCapability. It's a input object used to transfer parameter to logic modem
4008      *  @param response Callback message.
4009      */
setRadioCapability(RadioCapability rc, Message response)4010     public void setRadioCapability(RadioCapability rc, Message response) {
4011         mCi.setRadioCapability(rc, response);
4012     }
4013 
4014     /**
4015      *  Get phone radio access family
4016      *
4017      *  @return a bit mask to identify the radio access family.
4018      */
getRadioAccessFamily()4019     public int getRadioAccessFamily() {
4020         final RadioCapability rc = getRadioCapability();
4021         return (rc == null ? RadioAccessFamily.RAF_UNKNOWN : rc.getRadioAccessFamily());
4022     }
4023 
4024     /**
4025      *  Get the associated data modems Id.
4026      *
4027      *  @return a String containing the id of the data modem
4028      */
getModemUuId()4029     public String getModemUuId() {
4030         final RadioCapability rc = getRadioCapability();
4031         return (rc == null ? "" : rc.getLogicalModemUuid());
4032     }
4033 
4034     /**
4035      *  Get phone radio capability
4036      *
4037      *  @return the capability of the radio defined in RadioCapability
4038      */
getRadioCapability()4039     public RadioCapability getRadioCapability() {
4040         return mRadioCapability.get();
4041     }
4042 
4043     /**
4044      *  The RadioCapability has changed. This comes up from the RIL and is called when radios first
4045      *  become available or after a capability switch.  The flow is we use setRadioCapability to
4046      *  request a change with the RIL and get an UNSOL response with the new data which gets set
4047      *  here.
4048      *
4049      *  @param rc the phone radio capability currently in effect for this phone.
4050      */
radioCapabilityUpdated(RadioCapability rc)4051     public void radioCapabilityUpdated(RadioCapability rc) {
4052         // Called when radios first become available or after a capability switch
4053         // Update the cached value
4054         mRadioCapability.set(rc);
4055 
4056         if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
4057             boolean restoreSelection = !mContext.getResources().getBoolean(
4058                     com.android.internal.R.bool.skip_restoring_network_selection);
4059             sendSubscriptionSettings(restoreSelection);
4060         }
4061     }
4062 
sendSubscriptionSettings(boolean restoreNetworkSelection)4063     public void sendSubscriptionSettings(boolean restoreNetworkSelection) {
4064         // Send settings down
4065         int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
4066         setPreferredNetworkType(type, null);
4067 
4068         if (restoreNetworkSelection) {
4069             restoreSavedNetworkSelection(null);
4070         }
4071     }
4072 
setPreferredNetworkTypeIfSimLoaded()4073     protected void setPreferredNetworkTypeIfSimLoaded() {
4074         int subId = getSubId();
4075         if (SubscriptionManager.isValidSubscriptionId(subId)) {
4076             int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
4077             setPreferredNetworkType(type, null);
4078         }
4079     }
4080 
4081     /**
4082      * Registers the handler when phone radio  capability is changed.
4083      *
4084      * @param h Handler for notification message.
4085      * @param what User-defined message code.
4086      * @param obj User object.
4087      */
registerForRadioCapabilityChanged(Handler h, int what, Object obj)4088     public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) {
4089         mCi.registerForRadioCapabilityChanged(h, what, obj);
4090     }
4091 
4092     /**
4093      * Unregister for notifications when phone radio type and access technology is changed.
4094      *
4095      * @param h Handler to be removed from the registrant list.
4096      */
unregisterForRadioCapabilityChanged(Handler h)4097     public void unregisterForRadioCapabilityChanged(Handler h) {
4098         mCi.unregisterForRadioCapabilityChanged(this);
4099     }
4100 
4101     /**
4102      * Determines if  IMS is enabled for call.
4103      *
4104      * @return {@code true} if IMS calling is enabled.
4105      */
isImsUseEnabled()4106     public boolean isImsUseEnabled() {
4107         ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
4108         boolean imsUseEnabled = ((imsManager.isVolteEnabledByPlatform()
4109                 && imsManager.isEnhanced4gLteModeSettingEnabledByUser())
4110                 || (imsManager.isWfcEnabledByPlatform() && imsManager.isWfcEnabledByUser())
4111                 && imsManager.isNonTtyOrTtyOnVolteEnabled());
4112         return imsUseEnabled;
4113     }
4114 
4115     /**
4116      * Determines if the connection to IMS services are available yet.
4117      * @return {@code true} if the connection to IMS services are available.
4118      */
isImsAvailable()4119     public boolean isImsAvailable() {
4120         if (mImsPhone == null) {
4121             return false;
4122         }
4123 
4124         return mImsPhone.isImsAvailable();
4125     }
4126 
4127     /**
4128      * Determines if video calling is enabled for the phone.
4129      *
4130      * @return {@code true} if video calling is enabled, {@code false} otherwise.
4131      */
4132     @UnsupportedAppUsage
isVideoEnabled()4133     public boolean isVideoEnabled() {
4134         Phone imsPhone = mImsPhone;
4135         if (imsPhone != null) {
4136             return imsPhone.isVideoEnabled();
4137         }
4138         return false;
4139     }
4140 
4141     /**
4142      * Returns the status of Link Capacity Estimation (LCE) service.
4143      */
getLceStatus()4144     public int getLceStatus() {
4145         return mLceStatus;
4146     }
4147 
4148     /**
4149      * Returns the modem activity information
4150      */
getModemActivityInfo(Message response, WorkSource workSource)4151     public void getModemActivityInfo(Message response, WorkSource workSource)  {
4152         mCi.getModemActivityInfo(response, workSource);
4153     }
4154 
4155     /**
4156      * Starts LCE service after radio becomes available.
4157      * LCE service state may get destroyed on the modem when radio becomes unavailable.
4158      */
startLceAfterRadioIsAvailable()4159     public void startLceAfterRadioIsAvailable() {
4160         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
4161                 obtainMessage(EVENT_CONFIG_LCE));
4162     }
4163 
4164     /**
4165      * Set allowed carriers
4166      */
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules, Message response, WorkSource workSource)4167     public void setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules,
4168             Message response, WorkSource workSource) {
4169         mCi.setAllowedCarriers(carrierRestrictionRules, response, workSource);
4170     }
4171 
4172     /** Sets the SignalStrength reporting criteria. */
setSignalStrengthReportingCriteria( int signalStrengthMeasure, int[] thresholds, int ran, boolean isEnabled)4173     public void setSignalStrengthReportingCriteria(
4174             int signalStrengthMeasure, int[] thresholds, int ran, boolean isEnabled) {
4175         // no-op default implementation
4176     }
4177 
4178     /** Sets the SignalStrength reporting criteria. */
setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran)4179     public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) {
4180         // no-op default implementation
4181     }
4182 
4183     /**
4184      * Get allowed carriers
4185      */
getAllowedCarriers(Message response, WorkSource workSource)4186     public void getAllowedCarriers(Message response, WorkSource workSource) {
4187         mCi.getAllowedCarriers(response, workSource);
4188     }
4189 
4190     /**
4191      * Returns the locale based on the carrier properties (such as {@code ro.carrier}) and
4192      * SIM preferences.
4193      */
getLocaleFromSimAndCarrierPrefs()4194     public Locale getLocaleFromSimAndCarrierPrefs() {
4195         final IccRecords records = mIccRecords.get();
4196         if (records != null && records.getSimLanguage() != null) {
4197             return new Locale(records.getSimLanguage());
4198         }
4199 
4200         return getLocaleFromCarrierProperties();
4201     }
4202 
updateCurrentCarrierInProvider()4203     public boolean updateCurrentCarrierInProvider() {
4204         return false;
4205     }
4206 
4207     /**
4208      * @return True if all data connections are disconnected.
4209      */
areAllDataDisconnected()4210     public boolean areAllDataDisconnected() {
4211         if (mTransportManager != null) {
4212             for (int transport : mTransportManager.getAvailableTransports()) {
4213                 if (getDcTracker(transport) != null
4214                         && !getDcTracker(transport).areAllDataDisconnected()) {
4215                     return false;
4216                 }
4217             }
4218         }
4219         return true;
4220     }
4221 
registerForAllDataDisconnected(Handler h, int what)4222     public void registerForAllDataDisconnected(Handler h, int what) {
4223         mAllDataDisconnectedRegistrants.addUnique(h, what, null);
4224         if (mTransportManager != null) {
4225             for (int transport : mTransportManager.getAvailableTransports()) {
4226                 if (getDcTracker(transport) != null
4227                         && !getDcTracker(transport).areAllDataDisconnected()) {
4228                     getDcTracker(transport).registerForAllDataDisconnected(
4229                             this, EVENT_ALL_DATA_DISCONNECTED);
4230                 }
4231             }
4232         }
4233     }
4234 
unregisterForAllDataDisconnected(Handler h)4235     public void unregisterForAllDataDisconnected(Handler h) {
4236         mAllDataDisconnectedRegistrants.remove(h);
4237     }
4238 
getDataEnabledSettings()4239     public DataEnabledSettings getDataEnabledSettings() {
4240         return mDataEnabledSettings;
4241     }
4242 
4243     @UnsupportedAppUsage
getIccSmsInterfaceManager()4244     public IccSmsInterfaceManager getIccSmsInterfaceManager(){
4245         return null;
4246     }
4247 
isMatchGid(String gid)4248     protected boolean isMatchGid(String gid) {
4249         String gid1 = getGroupIdLevel1();
4250         int gidLength = gid.length();
4251         if (!TextUtils.isEmpty(gid1) && (gid1.length() >= gidLength)
4252                 && gid1.substring(0, gidLength).equalsIgnoreCase(gid)) {
4253             return true;
4254         }
4255         return false;
4256     }
4257 
checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, int phoneId, Context context)4258     public static void checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, int phoneId, Context context)
4259             throws CallStateException {
4260         if (imsPhone == null || !imsPhone.isWifiCallingEnabled()) {
4261             ImsManager imsManager = ImsManager.getInstance(context, phoneId);
4262             boolean wfcWiFiOnly = (imsManager.isWfcEnabledByPlatform()
4263                     && imsManager.isWfcEnabledByUser() && (imsManager.getWfcMode()
4264                     == ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY));
4265             if (wfcWiFiOnly) {
4266                 throw new CallStateException(
4267                         CallStateException.ERROR_OUT_OF_SERVICE,
4268                         "WFC Wi-Fi Only Mode: IMS not registered");
4269             }
4270         }
4271     }
4272 
startRingbackTone()4273     public void startRingbackTone() {
4274     }
4275 
stopRingbackTone()4276     public void stopRingbackTone() {
4277     }
4278 
callEndCleanupHandOverCallIfAny()4279     public void callEndCleanupHandOverCallIfAny() {
4280     }
4281 
4282     /**
4283      * Cancel USSD session.
4284      *
4285      * @param msg The message to dispatch when the USSD session terminated.
4286      */
cancelUSSD(Message msg)4287     public void cancelUSSD(Message msg) {
4288     }
4289 
4290     /**
4291      * Set boolean broadcastEmergencyCallStateChanges
4292      */
setBroadcastEmergencyCallStateChanges(boolean broadcast)4293     public abstract void setBroadcastEmergencyCallStateChanges(boolean broadcast);
4294 
sendEmergencyCallStateChange(boolean callActive)4295     public abstract void sendEmergencyCallStateChange(boolean callActive);
4296 
4297     /**
4298      * This function returns the parent phone of the current phone. It is applicable
4299      * only for IMS phone (function is overridden by ImsPhone). For others the phone
4300      * object itself is returned.
4301      * @return
4302      */
getDefaultPhone()4303     public Phone getDefaultPhone() {
4304         return this;
4305     }
4306 
4307     /**
4308      * SIP URIs aliased to the current subscriber given by the IMS implementation.
4309      * Applicable only on IMS; used in absence of line1number.
4310      * @return array of SIP URIs aliased to the current subscriber
4311      */
getCurrentSubscriberUris()4312     public Uri[] getCurrentSubscriberUris() {
4313         return null;
4314     }
4315 
getAppSmsManager()4316     public AppSmsManager getAppSmsManager() {
4317         return mAppSmsManager;
4318     }
4319 
4320     /**
4321      * Set SIM card power state.
4322      * @param state State of SIM (power down, power up, pass through)
4323      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
4324      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
4325      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
4326      **/
setSimPowerState(int state, WorkSource workSource)4327     public void setSimPowerState(int state, WorkSource workSource) {
4328         mCi.setSimCardPower(state, null, workSource);
4329     }
4330 
setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1, String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn)4331     public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1,
4332             String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn) {
4333     }
4334 
4335     /**
4336      * Check if the device can only make the emergency call. The device is emergency call only if
4337      * none of the phone is in service, and one of them has the capability to make the emergency
4338      * call.
4339      *
4340      * @return {@code True} if the device is emergency call only, otherwise return {@code False}.
4341      */
isEmergencyCallOnly()4342     public static boolean isEmergencyCallOnly() {
4343         boolean isEmergencyCallOnly = false;
4344         for (Phone phone : PhoneFactory.getPhones()) {
4345             if (phone != null) {
4346                 ServiceState ss = phone.getServiceStateTracker().getServiceState();
4347                 // One of the phone is in service, hence the device is not emergency call only.
4348                 if (ss.getState() == ServiceState.STATE_IN_SERVICE
4349                         || ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
4350                     return false;
4351                 }
4352                 isEmergencyCallOnly |= ss.isEmergencyOnly();
4353             }
4354         }
4355         return isEmergencyCallOnly;
4356     }
4357 
4358     /**
4359      * Get data connection tracker based on the transport type
4360      *
4361      * @param transportType Transport type defined in AccessNetworkConstants.TransportType
4362      * @return The data connection tracker. Null if not found.
4363      */
getDcTracker(int transportType)4364     public @Nullable DcTracker getDcTracker(int transportType) {
4365         return mDcTrackers.get(transportType);
4366     }
4367 
4368     // Return true if either CSIM or RUIM app is present. By default it returns false.
isCdmaSubscriptionAppPresent()4369     public boolean isCdmaSubscriptionAppPresent() {
4370         return false;
4371     }
4372 
4373     /**
4374      * Enable or disable uicc applications.
4375      * @param enable whether to enable or disable uicc applications.
4376      * @param onCompleteMessage callback for async operation. Ignored if blockingCall is true.
4377      */
enableUiccApplications(boolean enable, Message onCompleteMessage)4378     public void enableUiccApplications(boolean enable, Message onCompleteMessage) {}
4379 
4380     /**
4381      * Whether disabling a physical subscription is supported or not.
4382      */
canDisablePhysicalSubscription()4383     public boolean canDisablePhysicalSubscription() {
4384         return false;
4385     }
4386 
4387     /**
4388      * Get the HAL version.
4389      *
4390      * @return the current HalVersion
4391      */
getHalVersion()4392     public HalVersion getHalVersion() {
4393         if (mCi != null && mCi instanceof RIL) {
4394             return ((RIL) mCi).getHalVersion();
4395         }
4396         return RIL.RADIO_HAL_VERSION_UNKNOWN;
4397     }
4398 
4399     /**
4400      * Get the SIM's MCC/MNC
4401      *
4402      * @return MCC/MNC in string format, empty string if not available.
4403      */
4404     @NonNull
getOperatorNumeric()4405     public String getOperatorNumeric() {
4406         return "";
4407     }
4408 
4409     /** Returns the {@link VoiceCallSessionStats} for this phone ID. */
getVoiceCallSessionStats()4410     public VoiceCallSessionStats getVoiceCallSessionStats() {
4411         return mVoiceCallSessionStats;
4412     }
4413 
4414     /** Sets the {@link VoiceCallSessionStats} mock for this phone ID during unit testing. */
4415     @VisibleForTesting
setVoiceCallSessionStats(VoiceCallSessionStats voiceCallSessionStats)4416     public void setVoiceCallSessionStats(VoiceCallSessionStats voiceCallSessionStats) {
4417         mVoiceCallSessionStats = voiceCallSessionStats;
4418     }
4419 
4420     /** @hide */
getCarrierPrivilegesTracker()4421     public CarrierPrivilegesTracker getCarrierPrivilegesTracker() {
4422         return mCarrierPrivilegesTracker;
4423     }
4424 
dump(FileDescriptor fd, PrintWriter pw, String[] args)4425     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
4426         pw.println("Phone: subId=" + getSubId());
4427         pw.println(" mPhoneId=" + mPhoneId);
4428         pw.println(" mCi=" + mCi);
4429         pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
4430         pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
4431         pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
4432         pw.println(" mCallRingDelay=" + mCallRingDelay);
4433         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
4434         pw.println(" mIccRecords=" + mIccRecords.get());
4435         pw.println(" mUiccApplication=" + mUiccApplication.get());
4436         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
4437         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
4438         pw.flush();
4439         pw.println(" mLooper=" + mLooper);
4440         pw.println(" mContext=" + mContext);
4441         pw.println(" mNotifier=" + mNotifier);
4442         pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
4443         pw.println(" mUnitTestMode=" + mUnitTestMode);
4444         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
4445         pw.println(" getUnitTestMode()=" + getUnitTestMode());
4446         pw.println(" getState()=" + getState());
4447         pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
4448         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
4449         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
4450         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
4451         pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
4452         pw.flush();
4453         pw.println(" isInEcm()=" + isInEcm());
4454         pw.println(" getPhoneName()=" + getPhoneName());
4455         pw.println(" getPhoneType()=" + getPhoneType());
4456         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
4457         pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
4458         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
4459         pw.println(" isInEmergencySmsMode=" + isInEmergencySmsMode());
4460         pw.println(" isEcmCanceledForEmergency=" + isEcmCanceledForEmergency());
4461         pw.println(" service state=" + getServiceState());
4462         pw.flush();
4463         pw.println("++++++++++++++++++++++++++++++++");
4464 
4465         if (mImsPhone != null) {
4466             try {
4467                 mImsPhone.dump(fd, pw, args);
4468             } catch (Exception e) {
4469                 e.printStackTrace();
4470             }
4471 
4472             pw.flush();
4473             pw.println("++++++++++++++++++++++++++++++++");
4474         }
4475 
4476         if (mTransportManager != null) {
4477             for (int transport : mTransportManager.getAvailableTransports()) {
4478                 if (getDcTracker(transport) != null) {
4479                     getDcTracker(transport).dump(fd, pw, args);
4480                     pw.flush();
4481                     pw.println("++++++++++++++++++++++++++++++++");
4482                 }
4483             }
4484         }
4485 
4486         if (getServiceStateTracker() != null) {
4487             try {
4488                 getServiceStateTracker().dump(fd, pw, args);
4489             } catch (Exception e) {
4490                 e.printStackTrace();
4491             }
4492 
4493             pw.flush();
4494             pw.println("++++++++++++++++++++++++++++++++");
4495         }
4496 
4497         if (getEmergencyNumberTracker() != null) {
4498             try {
4499                 getEmergencyNumberTracker().dump(fd, pw, args);
4500             } catch (Exception e) {
4501                 e.printStackTrace();
4502             }
4503 
4504             pw.flush();
4505             pw.println("++++++++++++++++++++++++++++++++");
4506         }
4507 
4508         if (getDisplayInfoController() != null) {
4509             try {
4510                 getDisplayInfoController().dump(fd, pw, args);
4511             } catch (Exception e) {
4512                 e.printStackTrace();
4513             }
4514 
4515             pw.flush();
4516             pw.println("++++++++++++++++++++++++++++++++");
4517         }
4518 
4519         if (mCarrierResolver != null) {
4520             try {
4521                 mCarrierResolver.dump(fd, pw, args);
4522             } catch (Exception e) {
4523                 e.printStackTrace();
4524             }
4525 
4526             pw.flush();
4527             pw.println("++++++++++++++++++++++++++++++++");
4528         }
4529 
4530         if (mCarrierActionAgent != null) {
4531             try {
4532                 mCarrierActionAgent.dump(fd, pw, args);
4533             } catch (Exception e) {
4534                 e.printStackTrace();
4535             }
4536 
4537             pw.flush();
4538             pw.println("++++++++++++++++++++++++++++++++");
4539         }
4540 
4541         if (mCarrierSignalAgent != null) {
4542             try {
4543                 mCarrierSignalAgent.dump(fd, pw, args);
4544             } catch (Exception e) {
4545                 e.printStackTrace();
4546             }
4547 
4548             pw.flush();
4549             pw.println("++++++++++++++++++++++++++++++++");
4550         }
4551 
4552         if (getCallTracker() != null) {
4553             try {
4554                 getCallTracker().dump(fd, pw, args);
4555             } catch (Exception e) {
4556                 e.printStackTrace();
4557             }
4558 
4559             pw.flush();
4560             pw.println("++++++++++++++++++++++++++++++++");
4561         }
4562 
4563         if (mSimActivationTracker != null) {
4564             try {
4565                 mSimActivationTracker.dump(fd, pw, args);
4566             } catch (Exception e) {
4567                 e.printStackTrace();
4568             }
4569 
4570             pw.flush();
4571             pw.println("++++++++++++++++++++++++++++++++");
4572         }
4573 
4574         if (mDeviceStateMonitor != null) {
4575             pw.println("DeviceStateMonitor:");
4576             mDeviceStateMonitor.dump(fd, pw, args);
4577             pw.println("++++++++++++++++++++++++++++++++");
4578         }
4579 
4580         if (mTransportManager != null) {
4581             mTransportManager.dump(fd, pw, args);
4582         }
4583 
4584         if (mCi != null && mCi instanceof RIL) {
4585             try {
4586                 ((RIL)mCi).dump(fd, pw, args);
4587             } catch (Exception e) {
4588                 e.printStackTrace();
4589             }
4590 
4591             pw.flush();
4592             pw.println("++++++++++++++++++++++++++++++++");
4593         }
4594 
4595         if (getCarrierPrivilegesTracker() != null) {
4596             pw.println("CarrierPrivilegesTracker:");
4597             getCarrierPrivilegesTracker().dump(fd, pw, args);
4598             pw.println("++++++++++++++++++++++++++++++++");
4599         }
4600 
4601         pw.println("Phone Local Log: ");
4602         if (mLocalLog != null) {
4603             try {
4604                 mLocalLog.dump(fd, pw, args);
4605             } catch (Exception e) {
4606                 e.printStackTrace();
4607             }
4608             pw.flush();
4609             pw.println("++++++++++++++++++++++++++++++++");
4610         }
4611     }
4612 }
4613