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.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.SharedPreferences;
24 import android.net.LinkProperties;
25 import android.net.NetworkCapabilities;
26 import android.net.NetworkStats;
27 import android.net.Uri;
28 import android.net.wifi.WifiManager;
29 import android.os.AsyncResult;
30 import android.os.Build;
31 import android.os.Handler;
32 import android.os.Looper;
33 import android.os.Message;
34 import android.os.PersistableBundle;
35 import android.os.Registrant;
36 import android.os.RegistrantList;
37 import android.os.SystemProperties;
38 import android.os.WorkSource;
39 import android.preference.PreferenceManager;
40 import android.provider.Settings;
41 import android.service.carrier.CarrierIdentifier;
42 import android.telecom.VideoProfile;
43 import android.telephony.CarrierConfigManager;
44 import android.telephony.CellIdentityCdma;
45 import android.telephony.CellInfo;
46 import android.telephony.CellInfoCdma;
47 import android.telephony.CellLocation;
48 import android.telephony.ClientRequestStats;
49 import android.telephony.ImsiEncryptionInfo;
50 import android.telephony.PhoneStateListener;
51 import android.telephony.PhysicalChannelConfig;
52 import android.telephony.RadioAccessFamily;
53 import android.telephony.Rlog;
54 import android.telephony.ServiceState;
55 import android.telephony.SignalStrength;
56 import android.telephony.SubscriptionManager;
57 import android.telephony.TelephonyManager;
58 import android.telephony.VoLteServiceState;
59 import android.telephony.ims.stub.ImsRegistrationImplBase;
60 import android.text.TextUtils;
61 
62 import com.android.ims.ImsCall;
63 import com.android.ims.ImsConfig;
64 import com.android.ims.ImsManager;
65 import com.android.internal.R;
66 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
67 import com.android.internal.telephony.dataconnection.DcTracker;
68 import com.android.internal.telephony.imsphone.ImsPhoneCall;
69 import com.android.internal.telephony.test.SimulatedRadioControl;
70 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
71 import com.android.internal.telephony.uicc.IccFileHandler;
72 import com.android.internal.telephony.uicc.IccRecords;
73 import com.android.internal.telephony.uicc.IsimRecords;
74 import com.android.internal.telephony.uicc.UiccCard;
75 import com.android.internal.telephony.uicc.UiccCardApplication;
76 import com.android.internal.telephony.uicc.UiccController;
77 import com.android.internal.telephony.uicc.UsimServiceTable;
78 
79 import java.io.FileDescriptor;
80 import java.io.PrintWriter;
81 import java.util.ArrayList;
82 import java.util.HashSet;
83 import java.util.List;
84 import java.util.Locale;
85 import java.util.Set;
86 import java.util.concurrent.atomic.AtomicReference;
87 
88 /**
89  * (<em>Not for SDK use</em>)
90  * A base implementation for the com.android.internal.telephony.Phone interface.
91  *
92  * Note that implementations of Phone.java are expected to be used
93  * from a single application thread. This should be the same thread that
94  * originally called PhoneFactory to obtain the interface.
95  *
96  *  {@hide}
97  *
98  */
99 
100 public abstract class Phone extends Handler implements PhoneInternalInterface {
101     private static final String LOG_TAG = "Phone";
102 
103     protected final static Object lockForRadioTechnologyChange = new Object();
104 
105     protected final int USSD_MAX_QUEUE = 10;
106 
107     private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
108         @Override
109         public void onReceive(Context context, Intent intent) {
110             Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction());
111             if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) {
112                 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID,
113                         SubscriptionManager.INVALID_PHONE_INDEX);
114                 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId);
115                 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX ||
116                         extraPhoneId != getPhoneId()) {
117                     return;
118                 }
119             }
120 
121             synchronized (Phone.lockForRadioTechnologyChange) {
122                 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
123                     mImsServiceReady = true;
124                     updateImsPhone();
125                     ImsManager.getInstance(mContext, mPhoneId).updateImsServiceConfig(false);
126                 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
127                     mImsServiceReady = false;
128                     updateImsPhone();
129                 }
130             }
131         }
132     };
133 
134     // Key used to read and write the saved network selection numeric value
135     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
136     // Key used to read and write the saved network selection operator name
137     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
138     // Key used to read and write the saved network selection operator short name
139     public static final String NETWORK_SELECTION_SHORT_KEY = "network_selection_short_key";
140 
141 
142     // Key used to read/write "disable data connection on boot" pref (used for testing)
143     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
144 
145     // Key used to read/write data_roaming_is_user_setting pref
146     public static final String DATA_ROAMING_IS_USER_SETTING_KEY = "data_roaming_is_user_setting_key";
147 
148     /* Event Constants */
149     protected static final int EVENT_RADIO_AVAILABLE             = 1;
150     /** Supplementary Service Notification received. */
151     protected static final int EVENT_SSN                         = 2;
152     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
153     private static final int EVENT_MMI_DONE                      = 4;
154     protected static final int EVENT_RADIO_ON                    = 5;
155     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
156     protected static final int EVENT_USSD                        = 7;
157     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
158     protected static final int EVENT_GET_IMEI_DONE               = 9;
159     protected static final int EVENT_GET_IMEISV_DONE             = 10;
160     private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
161     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
162     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
163     protected static final int EVENT_CALL_RING                   = 14;
164     private static final int EVENT_CALL_RING_CONTINUE            = 15;
165 
166     // Used to intercept the carrier selection calls so that
167     // we can save the values.
168     private static final int EVENT_SET_NETWORK_MANUAL_COMPLETE      = 16;
169     private static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE   = 17;
170     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
171     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
172     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
173     // Events for CDMA support
174     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
175     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
176     protected static final int EVENT_NV_READY                       = 23;
177     private static final int EVENT_SET_ENHANCED_VP                  = 24;
178     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
179     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
180     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
181     // other
182     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
183     protected static final int EVENT_ICC_RECORD_EVENTS              = 29;
184     private static final int EVENT_ICC_CHANGED                      = 30;
185     // Single Radio Voice Call Continuity
186     private 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 
203     protected static final int EVENT_LAST                       = EVENT_MODEM_RESET;
204 
205     // For shared prefs.
206     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
207     private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_";
208     private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_";
209     private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_";
210 
211     // Key used to read/write current CLIR setting
212     public static final String CLIR_KEY = "clir_key";
213 
214     // Key used for storing voice mail count
215     private static final String VM_COUNT = "vm_count_key";
216     // Key used to read/write the ID for storing the voice mail
217     private static final String VM_ID = "vm_id_key";
218 
219     // Key used for storing call forwarding status
220     public static final String CF_STATUS = "cf_status_key";
221     // Key used to read/write the ID for storing the call forwarding status
222     public static final String CF_ID = "cf_id_key";
223 
224     // Key used to read/write "disable DNS server check" pref (used for testing)
225     private static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
226 
227     // Integer used to let the calling application know that the we are ignoring auto mode switch.
228     private static final int ALREADY_IN_AUTO_SELECTION = 1;
229 
230     /**
231      * This method is invoked when the Phone exits Emergency Callback Mode.
232      */
handleExitEmergencyCallbackMode()233     protected void handleExitEmergencyCallbackMode() {
234     }
235 
236     /**
237      * Small container class used to hold information relevant to
238      * the carrier selection process. operatorNumeric can be ""
239      * if we are looking for automatic selection. operatorAlphaLong is the
240      * corresponding operator name.
241      */
242     private static class NetworkSelectMessage {
243         public Message message;
244         public String operatorNumeric;
245         public String operatorAlphaLong;
246         public String operatorAlphaShort;
247     }
248 
249     /* Instance Variables */
250     public CommandsInterface mCi;
251     protected int mVmCount = 0;
252     private boolean mDnsCheckDisabled;
253     public DcTracker mDcTracker;
254     /* Used for dispatching signals to configured carrier apps */
255     protected CarrierSignalAgent mCarrierSignalAgent;
256     /* Used for dispatching carrier action from carrier apps */
257     protected CarrierActionAgent mCarrierActionAgent;
258     private boolean mDoesRilSendMultipleCallRing;
259     private int mCallRingContinueToken;
260     private int mCallRingDelay;
261     private boolean mIsVoiceCapable = true;
262     private final AppSmsManager mAppSmsManager;
263     private SimActivationTracker mSimActivationTracker;
264     // Keep track of whether or not the phone is in Emergency Callback Mode for Phone and
265     // subclasses
266     protected boolean mIsPhoneInEcmState = false;
267 
268     // Variable to cache the video capability. When RAT changes, we lose this info and are unable
269     // to recover from the state. We cache it and notify listeners when they register.
270     protected boolean mIsVideoCapable = false;
271     protected UiccController mUiccController = null;
272     protected final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
273     public SmsStorageMonitor mSmsStorageMonitor;
274     public SmsUsageMonitor mSmsUsageMonitor;
275     protected AtomicReference<UiccCardApplication> mUiccApplication =
276             new AtomicReference<UiccCardApplication>();
277     TelephonyTester mTelephonyTester;
278     private String mName;
279     private final String mActionDetached;
280     private final String mActionAttached;
281     protected DeviceStateMonitor mDeviceStateMonitor;
282 
283     protected int mPhoneId;
284 
285     private boolean mImsServiceReady = false;
286     protected Phone mImsPhone = null;
287 
288     private final AtomicReference<RadioCapability> mRadioCapability =
289             new AtomicReference<RadioCapability>();
290 
291     private static final int DEFAULT_REPORT_INTERVAL_MS = 200;
292     private static final boolean LCE_PULL_MODE = true;
293     private int mLceStatus = RILConstants.LCE_NOT_AVAILABLE;
294     protected TelephonyComponentFactory mTelephonyComponentFactory;
295 
296     //IMS
297     /**
298      * {@link CallStateException} message text used to indicate that an IMS call has failed because
299      * it needs to be retried using GSM or CDMA (e.g. CS fallback).
300      * TODO: Replace this with a proper exception; {@link CallStateException} doesn't make sense.
301      */
302     public static final String CS_FALLBACK = "cs_fallback";
303     public static final String EXTRA_KEY_ALERT_TITLE = "alertTitle";
304     public static final String EXTRA_KEY_ALERT_MESSAGE = "alertMessage";
305     public static final String EXTRA_KEY_ALERT_SHOW = "alertShow";
306     public static final String EXTRA_KEY_NOTIFICATION_MESSAGE = "notificationMessage";
307 
308     private final RegistrantList mPreciseCallStateRegistrants
309             = new RegistrantList();
310 
311     private final RegistrantList mHandoverRegistrants
312             = new RegistrantList();
313 
314     private final RegistrantList mNewRingingConnectionRegistrants
315             = new RegistrantList();
316 
317     private final RegistrantList mIncomingRingRegistrants
318             = new RegistrantList();
319 
320     protected final RegistrantList mDisconnectRegistrants
321             = new RegistrantList();
322 
323     private final RegistrantList mServiceStateRegistrants
324             = new RegistrantList();
325 
326     protected final RegistrantList mMmiCompleteRegistrants
327             = new RegistrantList();
328 
329     protected final RegistrantList mMmiRegistrants
330             = new RegistrantList();
331 
332     protected final RegistrantList mUnknownConnectionRegistrants
333             = new RegistrantList();
334 
335     protected final RegistrantList mSuppServiceFailedRegistrants
336             = new RegistrantList();
337 
338     protected final RegistrantList mRadioOffOrNotAvailableRegistrants
339             = new RegistrantList();
340 
341     protected final RegistrantList mSimRecordsLoadedRegistrants
342             = new RegistrantList();
343 
344     private final RegistrantList mVideoCapabilityChangedRegistrants
345             = new RegistrantList();
346 
347     protected final RegistrantList mEmergencyCallToggledRegistrants
348             = new RegistrantList();
349 
350     protected Registrant mPostDialHandler;
351 
352     private Looper mLooper; /* to insure registrants are in correct thread*/
353 
354     protected final Context mContext;
355 
356     /**
357      * PhoneNotifier is an abstraction for all system-wide
358      * state change notification. DefaultPhoneNotifier is
359      * used here unless running we're inside a unit test.
360      */
361     protected PhoneNotifier mNotifier;
362 
363     protected SimulatedRadioControl mSimulatedRadioControl;
364 
365     private boolean mUnitTestMode;
366 
getIccRecords()367     public IccRecords getIccRecords() {
368         return mIccRecords.get();
369     }
370 
371     /**
372      * Returns a string identifier for this phone interface for parties
373      *  outside the phone app process.
374      *  @return The string name.
375      */
getPhoneName()376     public String getPhoneName() {
377         return mName;
378     }
379 
setPhoneName(String name)380     protected void setPhoneName(String name) {
381         mName = name;
382     }
383 
384     /**
385      * Retrieves Nai for phones. Returns null if Nai is not set.
386      */
getNai()387     public String getNai(){
388          return null;
389     }
390 
391     /**
392      * Return the ActionDetached string. When this action is received by components
393      * they are to simulate detaching from the network.
394      *
395      * @return com.android.internal.telephony.{mName}.action_detached
396      *          {mName} is GSM, CDMA ...
397      */
getActionDetached()398     public String getActionDetached() {
399         return mActionDetached;
400     }
401 
402     /**
403      * Return the ActionAttached string. When this action is received by components
404      * they are to simulate attaching to the network.
405      *
406      * @return com.android.internal.telephony.{mName}.action_detached
407      *          {mName} is GSM, CDMA ...
408      */
getActionAttached()409     public String getActionAttached() {
410         return mActionAttached;
411     }
412 
413     /**
414      * Set a system property for the current phone, unless we're in unit test mode
415      */
416     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
setSystemProperty(String property, String value)417     public void setSystemProperty(String property, String value) {
418         if (getUnitTestMode()) {
419             return;
420         }
421         TelephonyManager.setTelephonyProperty(mPhoneId, property, value);
422     }
423 
424     /**
425      * Set a system property for all phones, unless we're in unit test mode
426      */
setGlobalSystemProperty(String property, String value)427     public void setGlobalSystemProperty(String property, String value) {
428         if (getUnitTestMode()) {
429             return;
430         }
431         TelephonyManager.setTelephonyProperty(property, value);
432     }
433 
434     /**
435      * Set a system property, unless we're in unit test mode
436      */
437     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
getSystemProperty(String property, String defValue)438     public String getSystemProperty(String property, String defValue) {
439         if(getUnitTestMode()) {
440             return null;
441         }
442         return SystemProperties.get(property, defValue);
443     }
444 
445     /**
446      * Constructs a Phone in normal (non-unit test) mode.
447      *
448      * @param notifier An instance of DefaultPhoneNotifier,
449      * @param context Context object from hosting application
450      * unless unit testing.
451      * @param ci is CommandsInterface
452      * @param unitTestMode when true, prevents notifications
453      * of state change events
454      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode)455     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
456                     boolean unitTestMode) {
457         this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX,
458                 TelephonyComponentFactory.getInstance());
459     }
460 
461     /**
462      * Constructs a Phone in normal (non-unit test) mode.
463      *
464      * @param notifier An instance of DefaultPhoneNotifier,
465      * @param context Context object from hosting application
466      * unless unit testing.
467      * @param ci is CommandsInterface
468      * @param unitTestMode when true, prevents notifications
469      * of state change events
470      * @param phoneId the phone-id of this phone.
471      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode, int phoneId, TelephonyComponentFactory telephonyComponentFactory)472     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
473                     boolean unitTestMode, int phoneId,
474                     TelephonyComponentFactory telephonyComponentFactory) {
475         mPhoneId = phoneId;
476         mName = name;
477         mNotifier = notifier;
478         mContext = context;
479         mLooper = Looper.myLooper();
480         mCi = ci;
481         mActionDetached = this.getClass().getPackage().getName() + ".action_detached";
482         mActionAttached = this.getClass().getPackage().getName() + ".action_attached";
483         mAppSmsManager = telephonyComponentFactory.makeAppSmsManager(context);
484 
485         if (Build.IS_DEBUGGABLE) {
486             mTelephonyTester = new TelephonyTester(this);
487         }
488 
489         setUnitTestMode(unitTestMode);
490 
491         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
492         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
493         mCi.setOnCallRing(this, EVENT_CALL_RING, null);
494 
495         /* "Voice capable" means that this device supports circuit-switched
496         * (i.e. voice) phone calls over the telephony network, and is allowed
497         * to display the in-call UI while a cellular voice call is active.
498         * This will be false on "data only" devices which can't make voice
499         * calls and don't support any in-call UI.
500         */
501         mIsVoiceCapable = mContext.getResources().getBoolean(
502                 com.android.internal.R.bool.config_voice_capable);
503 
504         /**
505          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
506          *  to be generated locally. Ideally all ring tones should be loops
507          * and this wouldn't be necessary. But to minimize changes to upper
508          * layers it is requested that it be generated by lower layers.
509          *
510          * By default old phones won't have the property set but do generate
511          * the RIL_UNSOL_CALL_RING so the default if there is no property is
512          * true.
513          */
514         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
515                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
516         Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
517 
518         mCallRingDelay = SystemProperties.getInt(
519                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
520         Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
521 
522         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
523             return;
524         }
525 
526         // The locale from the "ro.carrier" system property or R.array.carrier_properties.
527         // This will be overwritten by the Locale from the SIM language settings (EF-PL, EF-LI)
528         // if applicable.
529         final Locale carrierLocale = getLocaleFromCarrierProperties(mContext);
530         if (carrierLocale != null && !TextUtils.isEmpty(carrierLocale.getCountry())) {
531             final String country = carrierLocale.getCountry();
532             try {
533                 Settings.Global.getInt(mContext.getContentResolver(),
534                         Settings.Global.WIFI_COUNTRY_CODE);
535             } catch (Settings.SettingNotFoundException e) {
536                 // note this is not persisting
537                 WifiManager wM = (WifiManager)
538                         mContext.getSystemService(Context.WIFI_SERVICE);
539                 wM.setCountryCode(country);
540             }
541         }
542 
543         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
544         mTelephonyComponentFactory = telephonyComponentFactory;
545         mSmsStorageMonitor = mTelephonyComponentFactory.makeSmsStorageMonitor(this);
546         mSmsUsageMonitor = mTelephonyComponentFactory.makeSmsUsageMonitor(context);
547         mUiccController = UiccController.getInstance();
548         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
549         mSimActivationTracker = mTelephonyComponentFactory.makeSimActivationTracker(this);
550         if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
551             mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
552         }
553         mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null);
554         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
555                 obtainMessage(EVENT_CONFIG_LCE));
556     }
557 
558     /**
559      * Start listening for IMS service UP/DOWN events. If using the new ImsResolver APIs, we should
560      * always be setting up ImsPhones.
561      */
startMonitoringImsService()562     public void startMonitoringImsService() {
563         if (getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
564             return;
565         }
566 
567         synchronized(Phone.lockForRadioTechnologyChange) {
568             IntentFilter filter = new IntentFilter();
569             ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId());
570             // Don't listen to deprecated intents using the new dynamic binding.
571             if (imsManager != null && !imsManager.isDynamicBinding()) {
572                 filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
573                 filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
574             }
575             mContext.registerReceiver(mImsIntentReceiver, filter);
576 
577             // Monitor IMS service - but first poll to see if already up (could miss
578             // intent). Also, when using new ImsResolver APIs, the service will be available soon,
579             // so start trying to bind.
580             if (imsManager != null) {
581                 // If it is dynamic binding, kick off ImsPhone creation now instead of waiting for
582                 // the service to be available.
583                 if (imsManager.isDynamicBinding() || imsManager.isServiceAvailable()) {
584                     mImsServiceReady = true;
585                     updateImsPhone();
586                 }
587             }
588         }
589     }
590 
591     /**
592      * Checks if device should convert CDMA Caller ID restriction related MMI codes to
593      * equivalent 3GPP MMI Codes that provide same functionality when device is roaming.
594      * This method should only return true on multi-mode devices when carrier requires this
595      * conversion to be done on the device.
596      *
597      * @return true when carrier config
598      * "KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL" is set to true
599      */
supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming()600     public boolean supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming() {
601         CarrierConfigManager configManager = (CarrierConfigManager)
602                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
603         PersistableBundle b = configManager.getConfig();
604         if (b != null) {
605             return b.getBoolean(
606                     CarrierConfigManager
607                             .KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL,
608                     false);
609         } else {
610             // Default value set in CarrierConfigManager
611             return false;
612         }
613     }
614 
615     /**
616      * When overridden the derived class needs to call
617      * super.handleMessage(msg) so this method has a
618      * a chance to process the message.
619      *
620      * @param msg
621      */
622     @Override
handleMessage(Message msg)623     public void handleMessage(Message msg) {
624         AsyncResult ar;
625 
626         // messages to be handled whether or not the phone is being destroyed
627         // should only include messages which are being re-directed and do not use
628         // resources of the phone being destroyed
629         switch (msg.what) {
630             // handle the select network completion callbacks.
631             case EVENT_SET_NETWORK_MANUAL_COMPLETE:
632             case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
633                 handleSetSelectNetwork((AsyncResult) msg.obj);
634                 return;
635         }
636 
637         switch(msg.what) {
638             case EVENT_CALL_RING:
639                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
640                 ar = (AsyncResult)msg.obj;
641                 if (ar.exception == null) {
642                     PhoneConstants.State state = getState();
643                     if ((!mDoesRilSendMultipleCallRing)
644                             && ((state == PhoneConstants.State.RINGING) ||
645                                     (state == PhoneConstants.State.IDLE))) {
646                         mCallRingContinueToken += 1;
647                         sendIncomingCallRingNotification(mCallRingContinueToken);
648                     } else {
649                         notifyIncomingRing();
650                     }
651                 }
652                 break;
653 
654             case EVENT_CALL_RING_CONTINUE:
655                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received state=" + getState());
656                 if (getState() == PhoneConstants.State.RINGING) {
657                     sendIncomingCallRingNotification(msg.arg1);
658                 }
659                 break;
660 
661             case EVENT_ICC_CHANGED:
662                 onUpdateIccAvailability();
663                 break;
664 
665             case EVENT_INITIATE_SILENT_REDIAL:
666                 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
667                 ar = (AsyncResult) msg.obj;
668                 if ((ar.exception == null) && (ar.result != null)) {
669                     String dialString = (String) ar.result;
670                     if (TextUtils.isEmpty(dialString)) return;
671                     try {
672                         dialInternal(dialString, new DialArgs.Builder().build());
673                     } catch (CallStateException e) {
674                         Rlog.e(LOG_TAG, "silent redial failed: " + e);
675                     }
676                 }
677                 break;
678 
679             case EVENT_SRVCC_STATE_CHANGED:
680                 ar = (AsyncResult)msg.obj;
681                 if (ar.exception == null) {
682                     handleSrvccStateChanged((int[]) ar.result);
683                 } else {
684                     Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception);
685                 }
686                 break;
687 
688             case EVENT_UNSOL_OEM_HOOK_RAW:
689                 ar = (AsyncResult)msg.obj;
690                 if (ar.exception == null) {
691                     byte[] data = (byte[])ar.result;
692                     mNotifier.notifyOemHookRawEventForSubscriber(getSubId(), data);
693                 } else {
694                     Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception);
695                 }
696                 break;
697 
698             case EVENT_CONFIG_LCE:
699                 ar = (AsyncResult) msg.obj;
700                 if (ar.exception != null) {
701                     Rlog.d(LOG_TAG, "config LCE service failed: " + ar.exception);
702                 } else {
703                     final ArrayList<Integer> statusInfo = (ArrayList<Integer>)ar.result;
704                     mLceStatus = statusInfo.get(0);
705                 }
706                 break;
707 
708             case EVENT_CHECK_FOR_NETWORK_AUTOMATIC: {
709                 onCheckForNetworkSelectionModeAutomatic(msg);
710                 break;
711             }
712             default:
713                 throw new RuntimeException("unexpected event not handled");
714         }
715     }
716 
getHandoverConnection()717     public ArrayList<Connection> getHandoverConnection() {
718         return null;
719     }
720 
notifySrvccState(Call.SrvccState state)721     public void notifySrvccState(Call.SrvccState state) {
722     }
723 
registerForSilentRedial(Handler h, int what, Object obj)724     public void registerForSilentRedial(Handler h, int what, Object obj) {
725     }
726 
unregisterForSilentRedial(Handler h)727     public void unregisterForSilentRedial(Handler h) {
728     }
729 
handleSrvccStateChanged(int[] ret)730     private void handleSrvccStateChanged(int[] ret) {
731         Rlog.d(LOG_TAG, "handleSrvccStateChanged");
732 
733         ArrayList<Connection> conn = null;
734         Phone imsPhone = mImsPhone;
735         Call.SrvccState srvccState = Call.SrvccState.NONE;
736         if (ret != null && ret.length != 0) {
737             int state = ret[0];
738             switch(state) {
739                 case VoLteServiceState.HANDOVER_STARTED:
740                     srvccState = Call.SrvccState.STARTED;
741                     if (imsPhone != null) {
742                         conn = imsPhone.getHandoverConnection();
743                         migrateFrom(imsPhone);
744                     } else {
745                         Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null");
746                     }
747                     break;
748                 case VoLteServiceState.HANDOVER_COMPLETED:
749                     srvccState = Call.SrvccState.COMPLETED;
750                     if (imsPhone != null) {
751                         imsPhone.notifySrvccState(srvccState);
752                     } else {
753                         Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null");
754                     }
755                     break;
756                 case VoLteServiceState.HANDOVER_FAILED:
757                 case VoLteServiceState.HANDOVER_CANCELED:
758                     srvccState = Call.SrvccState.FAILED;
759                     break;
760 
761                 default:
762                     //ignore invalid state
763                     return;
764             }
765 
766             getCallTracker().notifySrvccState(srvccState, conn);
767 
768             VoLteServiceState lteState = new VoLteServiceState(state);
769             notifyVoLteServiceStateChanged(lteState);
770         }
771     }
772 
773     /**
774      * Gets the context for the phone, as set at initialization time.
775      */
getContext()776     public Context getContext() {
777         return mContext;
778     }
779 
780     // Will be called when icc changed
onUpdateIccAvailability()781     protected abstract void onUpdateIccAvailability();
782 
783     /**
784      * Disables the DNS check (i.e., allows "0.0.0.0").
785      * Useful for lab testing environment.
786      * @param b true disables the check, false enables.
787      */
disableDnsCheck(boolean b)788     public void disableDnsCheck(boolean b) {
789         mDnsCheckDisabled = b;
790         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
791         SharedPreferences.Editor editor = sp.edit();
792         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
793         editor.apply();
794     }
795 
796     /**
797      * Returns true if the DNS check is currently disabled.
798      */
isDnsCheckDisabled()799     public boolean isDnsCheckDisabled() {
800         return mDnsCheckDisabled;
801     }
802 
803     /**
804      * Register for getting notifications for change in the Call State {@link Call.State}
805      * This is called PreciseCallState because the call state is more precise than the
806      * {@link PhoneConstants.State} which can be obtained using the {@link PhoneStateListener}
807      *
808      * Resulting events will have an AsyncResult in <code>Message.obj</code>.
809      * AsyncResult.userData will be set to the obj argument here.
810      * The <em>h</em> parameter is held only by a weak reference.
811      */
registerForPreciseCallStateChanged(Handler h, int what, Object obj)812     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
813         checkCorrectThread(h);
814 
815         mPreciseCallStateRegistrants.addUnique(h, what, obj);
816     }
817 
818     /**
819      * Unregisters for voice call state change notifications.
820      * Extraneous calls are tolerated silently.
821      */
unregisterForPreciseCallStateChanged(Handler h)822     public void unregisterForPreciseCallStateChanged(Handler h) {
823         mPreciseCallStateRegistrants.remove(h);
824     }
825 
826     /**
827      * Subclasses of Phone probably want to replace this with a
828      * version scoped to their packages
829      */
notifyPreciseCallStateChangedP()830     protected void notifyPreciseCallStateChangedP() {
831         AsyncResult ar = new AsyncResult(null, this, null);
832         mPreciseCallStateRegistrants.notifyRegistrants(ar);
833 
834         mNotifier.notifyPreciseCallState(this);
835     }
836 
837     /**
838      * Notifies when a Handover happens due to SRVCC or Silent Redial
839      */
registerForHandoverStateChanged(Handler h, int what, Object obj)840     public void registerForHandoverStateChanged(Handler h, int what, Object obj) {
841         checkCorrectThread(h);
842         mHandoverRegistrants.addUnique(h, what, obj);
843     }
844 
845     /**
846      * Unregisters for handover state notifications
847      */
unregisterForHandoverStateChanged(Handler h)848     public void unregisterForHandoverStateChanged(Handler h) {
849         mHandoverRegistrants.remove(h);
850     }
851 
852     /**
853      * Subclasses of Phone probably want to replace this with a
854      * version scoped to their packages
855      */
notifyHandoverStateChanged(Connection cn)856     public void notifyHandoverStateChanged(Connection cn) {
857        AsyncResult ar = new AsyncResult(null, cn, null);
858        mHandoverRegistrants.notifyRegistrants(ar);
859     }
860 
setIsInEmergencyCall()861     protected void setIsInEmergencyCall() {
862     }
863 
migrateFrom(Phone from)864     protected void migrateFrom(Phone from) {
865         migrate(mHandoverRegistrants, from.mHandoverRegistrants);
866         migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
867         migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
868         migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
869         migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
870         migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
871         migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
872         migrate(mMmiRegistrants, from.mMmiRegistrants);
873         migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
874         migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
875         if (from.isInEmergencyCall()) {
876             setIsInEmergencyCall();
877         }
878     }
879 
migrate(RegistrantList to, RegistrantList from)880     protected void migrate(RegistrantList to, RegistrantList from) {
881         from.removeCleared();
882         for (int i = 0, n = from.size(); i < n; i++) {
883             Registrant r = (Registrant) from.get(i);
884             Message msg = r.messageForRegistrant();
885             // Since CallManager has already registered with both CS and IMS phones,
886             // the migrate should happen only for those registrants which are not
887             // registered with CallManager.Hence the below check is needed to add
888             // only those registrants to the registrant list which are not
889             // coming from the CallManager.
890             if (msg != null) {
891                 if (msg.obj == CallManager.getInstance().getRegistrantIdentifier()) {
892                     continue;
893                 } else {
894                     to.add((Registrant) from.get(i));
895                 }
896             } else {
897                 Rlog.d(LOG_TAG, "msg is null");
898             }
899         }
900     }
901 
902     /**
903      * Notifies when a previously untracked non-ringing/waiting connection has appeared.
904      * This is likely due to some other entity (eg, SIM card application) initiating a call.
905      */
registerForUnknownConnection(Handler h, int what, Object obj)906     public void registerForUnknownConnection(Handler h, int what, Object obj) {
907         checkCorrectThread(h);
908 
909         mUnknownConnectionRegistrants.addUnique(h, what, obj);
910     }
911 
912     /**
913      * Unregisters for unknown connection notifications.
914      */
unregisterForUnknownConnection(Handler h)915     public void unregisterForUnknownConnection(Handler h) {
916         mUnknownConnectionRegistrants.remove(h);
917     }
918 
919     /**
920      * Notifies when a new ringing or waiting connection has appeared.<p>
921      *
922      *  Messages received from this:
923      *  Message.obj will be an AsyncResult
924      *  AsyncResult.userObj = obj
925      *  AsyncResult.result = a Connection. <p>
926      *  Please check Connection.isRinging() to make sure the Connection
927      *  has not dropped since this message was posted.
928      *  If Connection.isRinging() is true, then
929      *   Connection.getCall() == Phone.getRingingCall()
930      */
registerForNewRingingConnection( Handler h, int what, Object obj)931     public void registerForNewRingingConnection(
932             Handler h, int what, Object obj) {
933         checkCorrectThread(h);
934 
935         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
936     }
937 
938     /**
939      * Unregisters for new ringing connection notification.
940      * Extraneous calls are tolerated silently
941      */
unregisterForNewRingingConnection(Handler h)942     public void unregisterForNewRingingConnection(Handler h) {
943         mNewRingingConnectionRegistrants.remove(h);
944     }
945 
946     /**
947      * Notifies when phone's video capabilities changes <p>
948      *
949      *  Messages received from this:
950      *  Message.obj will be an AsyncResult
951      *  AsyncResult.userObj = obj
952      *  AsyncResult.result = true if phone supports video calling <p>
953      */
registerForVideoCapabilityChanged( Handler h, int what, Object obj)954     public void registerForVideoCapabilityChanged(
955             Handler h, int what, Object obj) {
956         checkCorrectThread(h);
957 
958         mVideoCapabilityChangedRegistrants.addUnique(h, what, obj);
959 
960         // Notify any registrants of the cached video capability as soon as they register.
961         notifyForVideoCapabilityChanged(mIsVideoCapable);
962     }
963 
964     /**
965      * Unregisters for video capability changed notification.
966      * Extraneous calls are tolerated silently
967      */
unregisterForVideoCapabilityChanged(Handler h)968     public void unregisterForVideoCapabilityChanged(Handler h) {
969         mVideoCapabilityChangedRegistrants.remove(h);
970     }
971 
972     /**
973      * Register for notifications when a sInCall VoicePrivacy is enabled
974      *
975      * @param h Handler that receives the notification message.
976      * @param what User-defined message code.
977      * @param obj User object.
978      */
registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)979     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
980         mCi.registerForInCallVoicePrivacyOn(h, what, obj);
981     }
982 
983     /**
984      * Unegister for notifications when a sInCall VoicePrivacy is enabled
985      *
986      * @param h Handler to be removed from the registrant list.
987      */
unregisterForInCallVoicePrivacyOn(Handler h)988     public void unregisterForInCallVoicePrivacyOn(Handler h){
989         mCi.unregisterForInCallVoicePrivacyOn(h);
990     }
991 
992     /**
993      * Register for notifications when a sInCall VoicePrivacy is disabled
994      *
995      * @param h Handler that receives the notification message.
996      * @param what User-defined message code.
997      * @param obj User object.
998      */
registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)999     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
1000         mCi.registerForInCallVoicePrivacyOff(h, what, obj);
1001     }
1002 
1003     /**
1004      * Unregister for notifications when a sInCall VoicePrivacy is disabled
1005      *
1006      * @param h Handler to be removed from the registrant list.
1007      */
unregisterForInCallVoicePrivacyOff(Handler h)1008     public void unregisterForInCallVoicePrivacyOff(Handler h){
1009         mCi.unregisterForInCallVoicePrivacyOff(h);
1010     }
1011 
1012     /**
1013      * Notifies when an incoming call rings.<p>
1014      *
1015      *  Messages received from this:
1016      *  Message.obj will be an AsyncResult
1017      *  AsyncResult.userObj = obj
1018      *  AsyncResult.result = a Connection. <p>
1019      */
registerForIncomingRing( Handler h, int what, Object obj)1020     public void registerForIncomingRing(
1021             Handler h, int what, Object obj) {
1022         checkCorrectThread(h);
1023 
1024         mIncomingRingRegistrants.addUnique(h, what, obj);
1025     }
1026 
1027     /**
1028      * Unregisters for ring notification.
1029      * Extraneous calls are tolerated silently
1030      */
unregisterForIncomingRing(Handler h)1031     public void unregisterForIncomingRing(Handler h) {
1032         mIncomingRingRegistrants.remove(h);
1033     }
1034 
1035     /**
1036      * Notifies when a voice connection has disconnected, either due to local
1037      * or remote hangup or error.
1038      *
1039      *  Messages received from this will have the following members:<p>
1040      *  <ul><li>Message.obj will be an AsyncResult</li>
1041      *  <li>AsyncResult.userObj = obj</li>
1042      *  <li>AsyncResult.result = a Connection object that is
1043      *  no longer connected.</li></ul>
1044      */
registerForDisconnect(Handler h, int what, Object obj)1045     public void registerForDisconnect(Handler h, int what, Object obj) {
1046         checkCorrectThread(h);
1047 
1048         mDisconnectRegistrants.addUnique(h, what, obj);
1049     }
1050 
1051     /**
1052      * Unregisters for voice disconnection notification.
1053      * Extraneous calls are tolerated silently
1054      */
unregisterForDisconnect(Handler h)1055     public void unregisterForDisconnect(Handler h) {
1056         mDisconnectRegistrants.remove(h);
1057     }
1058 
1059     /**
1060      * Register for notifications when a supplementary service attempt fails.
1061      * Message.obj will contain an AsyncResult.
1062      *
1063      * @param h Handler that receives the notification message.
1064      * @param what User-defined message code.
1065      * @param obj User object.
1066      */
registerForSuppServiceFailed(Handler h, int what, Object obj)1067     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
1068         checkCorrectThread(h);
1069 
1070         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
1071     }
1072 
1073     /**
1074      * Unregister for notifications when a supplementary service attempt fails.
1075      * Extraneous calls are tolerated silently
1076      *
1077      * @param h Handler to be removed from the registrant list.
1078      */
unregisterForSuppServiceFailed(Handler h)1079     public void unregisterForSuppServiceFailed(Handler h) {
1080         mSuppServiceFailedRegistrants.remove(h);
1081     }
1082 
1083     /**
1084      * Register for notifications of initiation of a new MMI code request.
1085      * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
1086      *
1087      * Example: If Phone.dial is called with "*#31#", then the app will
1088      * be notified here.<p>
1089      *
1090      * The returned <code>Message.obj</code> will contain an AsyncResult.
1091      *
1092      * <code>obj.result</code> will be an "MmiCode" object.
1093      */
registerForMmiInitiate(Handler h, int what, Object obj)1094     public void registerForMmiInitiate(Handler h, int what, Object obj) {
1095         checkCorrectThread(h);
1096 
1097         mMmiRegistrants.addUnique(h, what, obj);
1098     }
1099 
1100     /**
1101      * Unregisters for new MMI initiate notification.
1102      * Extraneous calls are tolerated silently
1103      */
unregisterForMmiInitiate(Handler h)1104     public void unregisterForMmiInitiate(Handler h) {
1105         mMmiRegistrants.remove(h);
1106     }
1107 
1108     /**
1109      * Register for notifications that an MMI request has completed
1110      * its network activity and is in its final state. This may mean a state
1111      * of COMPLETE, FAILED, or CANCELLED.
1112      *
1113      * <code>Message.obj</code> will contain an AsyncResult.
1114      * <code>obj.result</code> will be an "MmiCode" object
1115      */
registerForMmiComplete(Handler h, int what, Object obj)1116     public void registerForMmiComplete(Handler h, int what, Object obj) {
1117         checkCorrectThread(h);
1118 
1119         mMmiCompleteRegistrants.addUnique(h, what, obj);
1120     }
1121 
1122     /**
1123      * Unregisters for MMI complete notification.
1124      * Extraneous calls are tolerated silently
1125      */
unregisterForMmiComplete(Handler h)1126     public void unregisterForMmiComplete(Handler h) {
1127         checkCorrectThread(h);
1128 
1129         mMmiCompleteRegistrants.remove(h);
1130     }
1131 
1132     /**
1133      * Registration point for Sim records loaded
1134      * @param h handler to notify
1135      * @param what what code of message when delivered
1136      * @param obj placed in Message.obj
1137      */
registerForSimRecordsLoaded(Handler h, int what, Object obj)1138     public void registerForSimRecordsLoaded(Handler h, int what, Object obj) {
1139     }
1140 
1141     /**
1142      * Unregister for notifications for Sim records loaded
1143      * @param h Handler to be removed from the registrant list.
1144      */
unregisterForSimRecordsLoaded(Handler h)1145     public void unregisterForSimRecordsLoaded(Handler h) {
1146     }
1147 
1148     /**
1149      * Register for TTY mode change notifications from the network.
1150      * Message.obj will contain an AsyncResult.
1151      * AsyncResult.result will be an Integer containing new mode.
1152      *
1153      * @param h Handler that receives the notification message.
1154      * @param what User-defined message code.
1155      * @param obj User object.
1156      */
registerForTtyModeReceived(Handler h, int what, Object obj)1157     public void registerForTtyModeReceived(Handler h, int what, Object obj) {
1158     }
1159 
1160     /**
1161      * Unregisters for TTY mode change notifications.
1162      * Extraneous calls are tolerated silently
1163      *
1164      * @param h Handler to be removed from the registrant list.
1165      */
unregisterForTtyModeReceived(Handler h)1166     public void unregisterForTtyModeReceived(Handler h) {
1167     }
1168 
1169     /**
1170      * Switches network selection mode to "automatic", re-scanning and
1171      * re-selecting a network if appropriate.
1172      *
1173      * @param response The message to dispatch when the network selection
1174      * is complete.
1175      *
1176      * @see #selectNetworkManually(OperatorInfo, boolean, android.os.Message)
1177      */
setNetworkSelectionModeAutomatic(Message response)1178     public void setNetworkSelectionModeAutomatic(Message response) {
1179         Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode");
1180         // we don't want to do this unecesarily - it acutally causes
1181         // the radio to repeate network selection and is costly
1182         // first check if we're already in automatic mode
1183         Message msg = obtainMessage(EVENT_CHECK_FOR_NETWORK_AUTOMATIC);
1184         msg.obj = response;
1185         mCi.getNetworkSelectionMode(msg);
1186     }
1187 
onCheckForNetworkSelectionModeAutomatic(Message fromRil)1188     private void onCheckForNetworkSelectionModeAutomatic(Message fromRil) {
1189         AsyncResult ar = (AsyncResult)fromRil.obj;
1190         Message response = (Message)ar.userObj;
1191         boolean doAutomatic = true;
1192         if (ar.exception == null && ar.result != null) {
1193             try {
1194                 int[] modes = (int[])ar.result;
1195                 if (modes[0] == 0) {
1196                     // already confirmed to be in automatic mode - don't resend
1197                     doAutomatic = false;
1198                 }
1199             } catch (Exception e) {
1200                 // send the setting on error
1201             }
1202         }
1203 
1204         // wrap the response message in our own message along with
1205         // an empty string (to indicate automatic selection) for the
1206         // operator's id.
1207         NetworkSelectMessage nsm = new NetworkSelectMessage();
1208         nsm.message = response;
1209         nsm.operatorNumeric = "";
1210         nsm.operatorAlphaLong = "";
1211         nsm.operatorAlphaShort = "";
1212 
1213         if (doAutomatic) {
1214             Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
1215             mCi.setNetworkSelectionModeAutomatic(msg);
1216         } else {
1217             Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - already auto, ignoring");
1218             // let the calling application know that the we are ignoring automatic mode switch.
1219             if (nsm.message != null) {
1220                 nsm.message.arg1 = ALREADY_IN_AUTO_SELECTION;
1221             }
1222 
1223             ar.userObj = nsm;
1224             handleSetSelectNetwork(ar);
1225         }
1226 
1227         updateSavedNetworkOperator(nsm);
1228     }
1229 
1230     /**
1231      * Query the radio for the current network selection mode.
1232      *
1233      * Return values:
1234      *     0 - automatic.
1235      *     1 - manual.
1236      */
getNetworkSelectionMode(Message message)1237     public void getNetworkSelectionMode(Message message) {
1238         mCi.getNetworkSelectionMode(message);
1239     }
1240 
getClientRequestStats()1241     public List<ClientRequestStats> getClientRequestStats() {
1242         return mCi.getClientRequestStats();
1243     }
1244 
1245     /**
1246      * Manually selects a network. <code>response</code> is
1247      * dispatched when this is complete.  <code>response.obj</code> will be
1248      * an AsyncResult, and <code>response.obj.exception</code> will be non-null
1249      * on failure.
1250      *
1251      * @see #setNetworkSelectionModeAutomatic(Message)
1252      */
selectNetworkManually(OperatorInfo network, boolean persistSelection, Message response)1253     public void selectNetworkManually(OperatorInfo network, boolean persistSelection,
1254             Message response) {
1255         // wrap the response message in our own message along with
1256         // the operator's id.
1257         NetworkSelectMessage nsm = new NetworkSelectMessage();
1258         nsm.message = response;
1259         nsm.operatorNumeric = network.getOperatorNumeric();
1260         nsm.operatorAlphaLong = network.getOperatorAlphaLong();
1261         nsm.operatorAlphaShort = network.getOperatorAlphaShort();
1262 
1263         Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
1264         mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
1265 
1266         if (persistSelection) {
1267             updateSavedNetworkOperator(nsm);
1268         } else {
1269             clearSavedNetworkSelection();
1270         }
1271     }
1272 
1273     /**
1274      * Registration point for emergency call/callback mode start. Message.obj is AsyncResult and
1275      * Message.obj.result will be Integer indicating start of call by value 1 or end of call by
1276      * value 0
1277      * @param h handler to notify
1278      * @param what what code of message when delivered
1279      * @param obj placed in Message.obj.userObj
1280      */
registerForEmergencyCallToggle(Handler h, int what, Object obj)1281     public void registerForEmergencyCallToggle(Handler h, int what, Object obj) {
1282         Registrant r = new Registrant(h, what, obj);
1283         mEmergencyCallToggledRegistrants.add(r);
1284     }
1285 
unregisterForEmergencyCallToggle(Handler h)1286     public void unregisterForEmergencyCallToggle(Handler h) {
1287         mEmergencyCallToggledRegistrants.remove(h);
1288     }
1289 
updateSavedNetworkOperator(NetworkSelectMessage nsm)1290     private void updateSavedNetworkOperator(NetworkSelectMessage nsm) {
1291         int subId = getSubId();
1292         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1293             // open the shared preferences editor, and write the value.
1294             // nsm.operatorNumeric is "" if we're in automatic.selection.
1295             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1296             SharedPreferences.Editor editor = sp.edit();
1297             editor.putString(NETWORK_SELECTION_KEY + subId, nsm.operatorNumeric);
1298             editor.putString(NETWORK_SELECTION_NAME_KEY + subId, nsm.operatorAlphaLong);
1299             editor.putString(NETWORK_SELECTION_SHORT_KEY + subId, nsm.operatorAlphaShort);
1300 
1301             // commit and log the result.
1302             if (!editor.commit()) {
1303                 Rlog.e(LOG_TAG, "failed to commit network selection preference");
1304             }
1305         } else {
1306             Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " +
1307                     subId);
1308         }
1309     }
1310 
1311     /**
1312      * Used to track the settings upon completion of the network change.
1313      */
handleSetSelectNetwork(AsyncResult ar)1314     private void handleSetSelectNetwork(AsyncResult ar) {
1315         // look for our wrapper within the asyncresult, skip the rest if it
1316         // is null.
1317         if (!(ar.userObj instanceof NetworkSelectMessage)) {
1318             Rlog.e(LOG_TAG, "unexpected result from user object.");
1319             return;
1320         }
1321 
1322         NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
1323 
1324         // found the object, now we send off the message we had originally
1325         // attached to the request.
1326         if (nsm.message != null) {
1327             AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
1328             nsm.message.sendToTarget();
1329         }
1330     }
1331 
1332     /**
1333      * Method to retrieve the saved operator from the Shared Preferences
1334      */
getSavedNetworkSelection()1335     private OperatorInfo getSavedNetworkSelection() {
1336         // open the shared preferences and search with our key.
1337         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1338         String numeric = sp.getString(NETWORK_SELECTION_KEY + getSubId(), "");
1339         String name = sp.getString(NETWORK_SELECTION_NAME_KEY + getSubId(), "");
1340         String shrt = sp.getString(NETWORK_SELECTION_SHORT_KEY + getSubId(), "");
1341         return new OperatorInfo(name, shrt, numeric);
1342     }
1343 
1344     /**
1345      * Clears the saved network selection.
1346      */
clearSavedNetworkSelection()1347     private void clearSavedNetworkSelection() {
1348         // open the shared preferences and search with our key.
1349         PreferenceManager.getDefaultSharedPreferences(getContext()).edit().
1350                 remove(NETWORK_SELECTION_KEY + getSubId()).
1351                 remove(NETWORK_SELECTION_NAME_KEY + getSubId()).
1352                 remove(NETWORK_SELECTION_SHORT_KEY + getSubId()).commit();
1353     }
1354 
1355     /**
1356      * Method to restore the previously saved operator id, or reset to
1357      * automatic selection, all depending upon the value in the shared
1358      * preferences.
1359      */
restoreSavedNetworkSelection(Message response)1360     private void restoreSavedNetworkSelection(Message response) {
1361         // retrieve the operator
1362         OperatorInfo networkSelection = getSavedNetworkSelection();
1363 
1364         // set to auto if the id is empty, otherwise select the network.
1365         if (networkSelection == null || TextUtils.isEmpty(networkSelection.getOperatorNumeric())) {
1366             setNetworkSelectionModeAutomatic(response);
1367         } else {
1368             selectNetworkManually(networkSelection, true, response);
1369         }
1370     }
1371 
1372     /**
1373      * Saves CLIR setting so that we can re-apply it as necessary
1374      * (in case the RIL resets it across reboots).
1375      */
saveClirSetting(int commandInterfaceCLIRMode)1376     public void saveClirSetting(int commandInterfaceCLIRMode) {
1377         // Open the shared preferences editor, and write the value.
1378         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1379         SharedPreferences.Editor editor = sp.edit();
1380         editor.putInt(CLIR_KEY + getPhoneId(), commandInterfaceCLIRMode);
1381         Rlog.i(LOG_TAG, "saveClirSetting: " + CLIR_KEY + getPhoneId() + "=" +
1382                 commandInterfaceCLIRMode);
1383 
1384         // Commit and log the result.
1385         if (!editor.commit()) {
1386             Rlog.e(LOG_TAG, "Failed to commit CLIR preference");
1387         }
1388     }
1389 
1390     /**
1391      * For unit tests; don't send notifications to "Phone"
1392      * mailbox registrants if true.
1393      */
setUnitTestMode(boolean f)1394     private void setUnitTestMode(boolean f) {
1395         mUnitTestMode = f;
1396     }
1397 
1398     /**
1399      * @return true If unit test mode is enabled
1400      */
getUnitTestMode()1401     public boolean getUnitTestMode() {
1402         return mUnitTestMode;
1403     }
1404 
1405     /**
1406      * To be invoked when a voice call Connection disconnects.
1407      *
1408      * Subclasses of Phone probably want to replace this with a
1409      * version scoped to their packages
1410      */
notifyDisconnectP(Connection cn)1411     protected void notifyDisconnectP(Connection cn) {
1412         AsyncResult ar = new AsyncResult(null, cn, null);
1413         mDisconnectRegistrants.notifyRegistrants(ar);
1414     }
1415 
1416     /**
1417      * Register for ServiceState changed.
1418      * Message.obj will contain an AsyncResult.
1419      * AsyncResult.result will be a ServiceState instance
1420      */
registerForServiceStateChanged( Handler h, int what, Object obj)1421     public void registerForServiceStateChanged(
1422             Handler h, int what, Object obj) {
1423         mServiceStateRegistrants.add(h, what, obj);
1424     }
1425 
1426     /**
1427      * Unregisters for ServiceStateChange notification.
1428      * Extraneous calls are tolerated silently
1429      */
unregisterForServiceStateChanged(Handler h)1430     public void unregisterForServiceStateChanged(Handler h) {
1431         mServiceStateRegistrants.remove(h);
1432     }
1433 
1434     /**
1435      * Notifies when out-band ringback tone is needed.<p>
1436      *
1437      *  Messages received from this:
1438      *  Message.obj will be an AsyncResult
1439      *  AsyncResult.userObj = obj
1440      *  AsyncResult.result = boolean, true to start play ringback tone
1441      *                       and false to stop. <p>
1442      */
registerForRingbackTone(Handler h, int what, Object obj)1443     public void registerForRingbackTone(Handler h, int what, Object obj) {
1444         mCi.registerForRingbackTone(h, what, obj);
1445     }
1446 
1447     /**
1448      * Unregisters for ringback tone notification.
1449      */
unregisterForRingbackTone(Handler h)1450     public void unregisterForRingbackTone(Handler h) {
1451         mCi.unregisterForRingbackTone(h);
1452     }
1453 
1454     /**
1455      * Notifies when out-band on-hold tone is needed.<p>
1456      *
1457      *  Messages received from this:
1458      *  Message.obj will be an AsyncResult
1459      *  AsyncResult.userObj = obj
1460      *  AsyncResult.result = boolean, true to start play on-hold tone
1461      *                       and false to stop. <p>
1462      */
registerForOnHoldTone(Handler h, int what, Object obj)1463     public void registerForOnHoldTone(Handler h, int what, Object obj) {
1464     }
1465 
1466     /**
1467      * Unregisters for on-hold tone notification.
1468      */
unregisterForOnHoldTone(Handler h)1469     public void unregisterForOnHoldTone(Handler h) {
1470     }
1471 
1472     /**
1473      * Registers the handler to reset the uplink mute state to get
1474      * uplink audio.
1475      */
registerForResendIncallMute(Handler h, int what, Object obj)1476     public void registerForResendIncallMute(Handler h, int what, Object obj) {
1477         mCi.registerForResendIncallMute(h, what, obj);
1478     }
1479 
1480     /**
1481      * Unregisters for resend incall mute notifications.
1482      */
unregisterForResendIncallMute(Handler h)1483     public void unregisterForResendIncallMute(Handler h) {
1484         mCi.unregisterForResendIncallMute(h);
1485     }
1486 
1487     /**
1488      * Enables or disables echo suppression.
1489      */
setEchoSuppressionEnabled()1490     public void setEchoSuppressionEnabled() {
1491         // no need for regular phone
1492     }
1493 
1494     /**
1495      * Subclasses of Phone probably want to replace this with a
1496      * version scoped to their packages
1497      */
notifyServiceStateChangedP(ServiceState ss)1498     protected void notifyServiceStateChangedP(ServiceState ss) {
1499         AsyncResult ar = new AsyncResult(null, ss, null);
1500         mServiceStateRegistrants.notifyRegistrants(ar);
1501 
1502         mNotifier.notifyServiceState(this);
1503     }
1504 
1505     /**
1506      * If this is a simulated phone interface, returns a SimulatedRadioControl.
1507      * @return SimulatedRadioControl if this is a simulated interface;
1508      * otherwise, null.
1509      */
getSimulatedRadioControl()1510     public SimulatedRadioControl getSimulatedRadioControl() {
1511         return mSimulatedRadioControl;
1512     }
1513 
1514     /**
1515      * Verifies the current thread is the same as the thread originally
1516      * used in the initialization of this instance. Throws RuntimeException
1517      * if not.
1518      *
1519      * @exception RuntimeException if the current thread is not
1520      * the thread that originally obtained this Phone instance.
1521      */
checkCorrectThread(Handler h)1522     private void checkCorrectThread(Handler h) {
1523         if (h.getLooper() != mLooper) {
1524             throw new RuntimeException(
1525                     "com.android.internal.telephony.Phone must be used from within one thread");
1526         }
1527     }
1528 
1529     /**
1530      * Set the properties by matching the carrier string in
1531      * a string-array resource
1532      */
getLocaleFromCarrierProperties(Context ctx)1533     private static Locale getLocaleFromCarrierProperties(Context ctx) {
1534         String carrier = SystemProperties.get("ro.carrier");
1535 
1536         if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
1537             return null;
1538         }
1539 
1540         CharSequence[] carrierLocales = ctx.getResources().getTextArray(R.array.carrier_properties);
1541 
1542         for (int i = 0; i < carrierLocales.length; i+=3) {
1543             String c = carrierLocales[i].toString();
1544             if (carrier.equals(c)) {
1545                 return Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-'));
1546             }
1547         }
1548 
1549         return null;
1550     }
1551 
1552     /**
1553      * Get current coarse-grained voice call state.
1554      * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object)
1555      * registerForPreciseCallStateChanged()} for change notification. <p>
1556      * If the phone has an active call and call waiting occurs,
1557      * then the phone state is RINGING not OFFHOOK
1558      * <strong>Note:</strong>
1559      * This registration point provides notification of finer-grained
1560      * changes.<p>
1561      */
getState()1562     public abstract PhoneConstants.State getState();
1563 
1564     /**
1565      * Retrieves the IccFileHandler of the Phone instance
1566      */
getIccFileHandler()1567     public IccFileHandler getIccFileHandler(){
1568         UiccCardApplication uiccApplication = mUiccApplication.get();
1569         IccFileHandler fh;
1570 
1571         if (uiccApplication == null) {
1572             Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null");
1573             fh = null;
1574         } else {
1575             fh = uiccApplication.getIccFileHandler();
1576         }
1577 
1578         Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh);
1579         return fh;
1580     }
1581 
1582     /*
1583      * Retrieves the Handler of the Phone instance
1584      */
getHandler()1585     public Handler getHandler() {
1586         return this;
1587     }
1588 
1589     /**
1590      * Update the phone object if the voice radio technology has changed
1591      *
1592      * @param voiceRadioTech The new voice radio technology
1593      */
updatePhoneObject(int voiceRadioTech)1594     public void updatePhoneObject(int voiceRadioTech) {
1595     }
1596 
1597     /**
1598     * Retrieves the ServiceStateTracker of the phone instance.
1599     */
getServiceStateTracker()1600     public ServiceStateTracker getServiceStateTracker() {
1601         return null;
1602     }
1603 
1604     /**
1605     * Get call tracker
1606     */
getCallTracker()1607     public CallTracker getCallTracker() {
1608         return null;
1609     }
1610 
1611     /**
1612      * Update voice activation state
1613      */
setVoiceActivationState(int state)1614     public void setVoiceActivationState(int state) {
1615         mSimActivationTracker.setVoiceActivationState(state);
1616     }
1617     /**
1618      * Update data activation state
1619      */
setDataActivationState(int state)1620     public void setDataActivationState(int state) {
1621         mSimActivationTracker.setDataActivationState(state);
1622     }
1623 
1624     /**
1625      * Returns voice activation state
1626      */
getVoiceActivationState()1627     public int getVoiceActivationState() {
1628         return mSimActivationTracker.getVoiceActivationState();
1629     }
1630     /**
1631      * Returns data activation state
1632      */
getDataActivationState()1633     public int getDataActivationState() {
1634         return mSimActivationTracker.getDataActivationState();
1635     }
1636 
1637     /**
1638      * Update voice mail count related fields and notify listeners
1639      */
updateVoiceMail()1640     public void updateVoiceMail() {
1641         Rlog.e(LOG_TAG, "updateVoiceMail() should be overridden");
1642     }
1643 
getCurrentUiccAppType()1644     public AppType getCurrentUiccAppType() {
1645         UiccCardApplication currentApp = mUiccApplication.get();
1646         if (currentApp != null) {
1647             return currentApp.getType();
1648         }
1649         return AppType.APPTYPE_UNKNOWN;
1650     }
1651 
1652     /**
1653      * Returns the ICC card interface for this phone, or null
1654      * if not applicable to underlying technology.
1655      */
getIccCard()1656     public IccCard getIccCard() {
1657         return null;
1658         //throw new Exception("getIccCard Shouldn't be called from Phone");
1659     }
1660 
1661     /**
1662      * Retrieves the serial number of the ICC, if applicable. Returns only the decimal digits before
1663      * the first hex digit in the ICC ID.
1664      */
getIccSerialNumber()1665     public String getIccSerialNumber() {
1666         IccRecords r = mIccRecords.get();
1667         return (r != null) ? r.getIccId() : null;
1668     }
1669 
1670     /**
1671      * Retrieves the full serial number of the ICC (including hex digits), if applicable.
1672      */
getFullIccSerialNumber()1673     public String getFullIccSerialNumber() {
1674         IccRecords r = mIccRecords.get();
1675         return (r != null) ? r.getFullIccId() : null;
1676     }
1677 
1678     /**
1679      * Returns SIM record load state. Use
1680      * <code>getSimCard().registerForReady()</code> for change notification.
1681      *
1682      * @return true if records from the SIM have been loaded and are
1683      * available (if applicable). If not applicable to the underlying
1684      * technology, returns true as well.
1685      */
getIccRecordsLoaded()1686     public boolean getIccRecordsLoaded() {
1687         IccRecords r = mIccRecords.get();
1688         return (r != null) ? r.getRecordsLoaded() : false;
1689     }
1690 
1691     /**
1692      * @param workSource calling WorkSource
1693      * @return all available cell information or null if none.
1694      */
getAllCellInfo(WorkSource workSource)1695     public List<CellInfo> getAllCellInfo(WorkSource workSource) {
1696         List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo(workSource);
1697         return privatizeCellInfoList(cellInfoList);
1698     }
1699 
getCellLocation()1700     public CellLocation getCellLocation() {
1701         return getCellLocation(null);
1702     }
1703 
1704     /**
1705      * Clear CDMA base station lat/long values if location setting is disabled.
1706      * @param cellInfoList the original cell info list from the RIL
1707      * @return the original list with CDMA lat/long cleared if necessary
1708      */
privatizeCellInfoList(List<CellInfo> cellInfoList)1709     private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) {
1710         if (cellInfoList == null) return null;
1711         int mode = Settings.Secure.getInt(getContext().getContentResolver(),
1712                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
1713         if (mode == Settings.Secure.LOCATION_MODE_OFF) {
1714             ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size());
1715             // clear lat/lon values for location privacy
1716             for (CellInfo c : cellInfoList) {
1717                 if (c instanceof CellInfoCdma) {
1718                     CellInfoCdma cellInfoCdma = (CellInfoCdma) c;
1719                     CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity();
1720                     CellIdentityCdma maskedCellIdentity = new CellIdentityCdma(
1721                             cellIdentity.getNetworkId(),
1722                             cellIdentity.getSystemId(),
1723                             cellIdentity.getBasestationId(),
1724                             Integer.MAX_VALUE, Integer.MAX_VALUE);
1725                     CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma);
1726                     privateCellInfoCdma.setCellIdentity(maskedCellIdentity);
1727                     privateCellInfoList.add(privateCellInfoCdma);
1728                 } else {
1729                     privateCellInfoList.add(c);
1730                 }
1731             }
1732             cellInfoList = privateCellInfoList;
1733         }
1734         return cellInfoList;
1735     }
1736 
1737     /**
1738      * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
1739      * PhoneStateListener.onCellInfoChanged} will be invoked.
1740      *
1741      * The default, 0, means invoke onCellInfoChanged when any of the reported
1742      * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
1743      * A onCellInfoChanged.
1744      *
1745      * @param rateInMillis the rate
1746      * @param workSource calling WorkSource
1747      */
setCellInfoListRate(int rateInMillis, WorkSource workSource)1748     public void setCellInfoListRate(int rateInMillis, WorkSource workSource) {
1749         mCi.setCellInfoListRate(rateInMillis, null, workSource);
1750     }
1751 
1752     /**
1753      * Get voice message waiting indicator status. No change notification
1754      * available on this interface. Use PhoneStateNotifier or similar instead.
1755      *
1756      * @return true if there is a voice message waiting
1757      */
getMessageWaitingIndicator()1758     public boolean getMessageWaitingIndicator() {
1759         return mVmCount != 0;
1760     }
1761 
getCallForwardingIndicatorFromSharedPref()1762     private int getCallForwardingIndicatorFromSharedPref() {
1763         int status = IccRecords.CALL_FORWARDING_STATUS_DISABLED;
1764         int subId = getSubId();
1765         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1766             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1767             status = sp.getInt(CF_STATUS + subId, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN);
1768             Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " +
1769                     status);
1770             // Check for old preference if status is UNKNOWN for current subId. This part of the
1771             // code is needed only when upgrading from M to N.
1772             if (status == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
1773                 String subscriberId = sp.getString(CF_ID, null);
1774                 if (subscriberId != null) {
1775                     String currentSubscriberId = getSubscriberId();
1776 
1777                     if (subscriberId.equals(currentSubscriberId)) {
1778                         // get call forwarding status from preferences
1779                         status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED);
1780                         setCallForwardingIndicatorInSharedPref(
1781                                 status == IccRecords.CALL_FORWARDING_STATUS_ENABLED ? true : false);
1782                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: " + status);
1783                     } else {
1784                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: returning " +
1785                                 "DISABLED as status for matching subscriberId not found");
1786                     }
1787 
1788                     // get rid of old preferences.
1789                     SharedPreferences.Editor editor = sp.edit();
1790                     editor.remove(CF_ID);
1791                     editor.remove(CF_STATUS);
1792                     editor.apply();
1793                 }
1794             }
1795         } else {
1796             Rlog.e(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId);
1797         }
1798         return status;
1799     }
1800 
setCallForwardingIndicatorInSharedPref(boolean enable)1801     private void setCallForwardingIndicatorInSharedPref(boolean enable) {
1802         int status = enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED :
1803                 IccRecords.CALL_FORWARDING_STATUS_DISABLED;
1804         int subId = getSubId();
1805         Rlog.i(LOG_TAG, "setCallForwardingIndicatorInSharedPref: Storing status = " + status +
1806                 " in pref " + CF_STATUS + subId);
1807 
1808         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1809         SharedPreferences.Editor editor = sp.edit();
1810         editor.putInt(CF_STATUS + subId, status);
1811         editor.apply();
1812     }
1813 
setVoiceCallForwardingFlag(int line, boolean enable, String number)1814     public void setVoiceCallForwardingFlag(int line, boolean enable, String number) {
1815         setCallForwardingIndicatorInSharedPref(enable);
1816         IccRecords r = mIccRecords.get();
1817         if (r != null) {
1818             r.setVoiceCallForwardingFlag(line, enable, number);
1819         }
1820     }
1821 
setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, String number)1822     protected void setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable,
1823                                               String number) {
1824         setCallForwardingIndicatorInSharedPref(enable);
1825         r.setVoiceCallForwardingFlag(line, enable, number);
1826     }
1827 
1828     /**
1829      * Get voice call forwarding indicator status. No change notification
1830      * available on this interface. Use PhoneStateNotifier or similar instead.
1831      *
1832      * @return true if there is a voice call forwarding
1833      */
getCallForwardingIndicator()1834     public boolean getCallForwardingIndicator() {
1835         if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
1836             Rlog.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
1837             return false;
1838         }
1839         IccRecords r = mIccRecords.get();
1840         int callForwardingIndicator = IccRecords.CALL_FORWARDING_STATUS_UNKNOWN;
1841         if (r != null) {
1842             callForwardingIndicator = r.getVoiceCallForwardingFlag();
1843         }
1844         if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
1845             callForwardingIndicator = getCallForwardingIndicatorFromSharedPref();
1846         }
1847         Rlog.v(LOG_TAG, "getCallForwardingIndicator: iccForwardingFlag=" + (r != null
1848                     ? r.getVoiceCallForwardingFlag() : "null") + ", sharedPrefFlag="
1849                     + getCallForwardingIndicatorFromSharedPref());
1850         return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED);
1851     }
1852 
getCarrierSignalAgent()1853     public CarrierSignalAgent getCarrierSignalAgent() {
1854         return mCarrierSignalAgent;
1855     }
1856 
getCarrierActionAgent()1857     public CarrierActionAgent getCarrierActionAgent() {
1858         return mCarrierActionAgent;
1859     }
1860 
1861     /**
1862      *  Query the CDMA roaming preference setting
1863      *
1864      * @param response is callback message to report one of  CDMA_RM_*
1865      */
queryCdmaRoamingPreference(Message response)1866     public void queryCdmaRoamingPreference(Message response) {
1867         mCi.queryCdmaRoamingPreference(response);
1868     }
1869 
1870     /**
1871      * Get current signal strength. No change notification available on this
1872      * interface. Use <code>PhoneStateNotifier</code> or an equivalent.
1873      * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
1874      * The following special values are defined:</p>
1875      * <ul><li>0 means "-113 dBm or less".</li>
1876      * <li>31 means "-51 dBm or greater".</li></ul>
1877      *
1878      * @return Current signal strength as SignalStrength
1879      */
getSignalStrength()1880     public SignalStrength getSignalStrength() {
1881         ServiceStateTracker sst = getServiceStateTracker();
1882         if (sst == null) {
1883             return new SignalStrength();
1884         } else {
1885             return sst.getSignalStrength();
1886         }
1887     }
1888 
1889     /**
1890      * @return true, if the device is in a state where both voice and data
1891      * are supported simultaneously. This can change based on location or network condition.
1892      */
isConcurrentVoiceAndDataAllowed()1893     public boolean isConcurrentVoiceAndDataAllowed() {
1894         ServiceStateTracker sst = getServiceStateTracker();
1895         return sst == null ? false : sst.isConcurrentVoiceAndDataAllowed();
1896     }
1897 
1898     /**
1899      *  Requests to set the CDMA roaming preference
1900      * @param cdmaRoamingType one of  CDMA_RM_*
1901      * @param response is callback message
1902      */
setCdmaRoamingPreference(int cdmaRoamingType, Message response)1903     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
1904         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
1905     }
1906 
1907     /**
1908      *  Requests to set the CDMA subscription mode
1909      * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
1910      * @param response is callback message
1911      */
setCdmaSubscription(int cdmaSubscriptionType, Message response)1912     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
1913         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
1914     }
1915 
1916     /**
1917      *  Requests to set the preferred network type for searching and registering
1918      * (CS/PS domain, RAT, and operation mode)
1919      * @param networkType one of  NT_*_TYPE
1920      * @param response is callback message
1921      */
setPreferredNetworkType(int networkType, Message response)1922     public void setPreferredNetworkType(int networkType, Message response) {
1923         // Only set preferred network types to that which the modem supports
1924         int modemRaf = getRadioAccessFamily();
1925         int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType);
1926 
1927         if (modemRaf == RadioAccessFamily.RAF_UNKNOWN
1928                 || rafFromType == RadioAccessFamily.RAF_UNKNOWN) {
1929             Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: "
1930                     + modemRaf + " " + rafFromType);
1931             if (response != null) {
1932                 CommandException ex;
1933 
1934                 ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
1935                 AsyncResult.forMessage(response, null, ex);
1936                 response.sendToTarget();
1937             }
1938             return;
1939         }
1940 
1941         int filteredRaf = (rafFromType & modemRaf);
1942         int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf);
1943 
1944         Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType
1945                 + " modemRaf = " + modemRaf
1946                 + " rafFromType = " + rafFromType
1947                 + " filteredType = " + filteredType);
1948 
1949         mCi.setPreferredNetworkType(filteredType, response);
1950     }
1951 
1952     /**
1953      *  Query the preferred network type setting
1954      *
1955      * @param response is callback message to report one of  NT_*_TYPE
1956      */
getPreferredNetworkType(Message response)1957     public void getPreferredNetworkType(Message response) {
1958         mCi.getPreferredNetworkType(response);
1959     }
1960 
1961     /**
1962      * Gets the default SMSC address.
1963      *
1964      * @param result Callback message contains the SMSC address.
1965      */
getSmscAddress(Message result)1966     public void getSmscAddress(Message result) {
1967         mCi.getSmscAddress(result);
1968     }
1969 
1970     /**
1971      * Sets the default SMSC address.
1972      *
1973      * @param address new SMSC address
1974      * @param result Callback message is empty on completion
1975      */
setSmscAddress(String address, Message result)1976     public void setSmscAddress(String address, Message result) {
1977         mCi.setSmscAddress(address, result);
1978     }
1979 
1980     /**
1981      * setTTYMode
1982      * sets a TTY mode option.
1983      * @param ttyMode is a one of the following:
1984      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1985      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1986      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1987      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1988      * @param onComplete a callback message when the action is completed
1989      */
setTTYMode(int ttyMode, Message onComplete)1990     public void setTTYMode(int ttyMode, Message onComplete) {
1991         mCi.setTTYMode(ttyMode, onComplete);
1992     }
1993 
1994     /**
1995      * setUiTTYMode
1996      * sets a TTY mode option.
1997      * @param ttyMode is a one of the following:
1998      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1999      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
2000      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
2001      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
2002      * @param onComplete a callback message when the action is completed
2003      */
setUiTTYMode(int uiTtyMode, Message onComplete)2004     public void setUiTTYMode(int uiTtyMode, Message onComplete) {
2005         Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call");
2006     }
2007 
2008     /**
2009      * queryTTYMode
2010      * query the status of the TTY mode
2011      *
2012      * @param onComplete a callback message when the action is completed.
2013      */
queryTTYMode(Message onComplete)2014     public void queryTTYMode(Message onComplete) {
2015         mCi.queryTTYMode(onComplete);
2016     }
2017 
2018     /**
2019      * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is
2020      * disabled, normal VP is enabled.
2021      *
2022      * @param enable whether true or false to enable or disable.
2023      * @param onComplete a callback message when the action is completed.
2024      */
enableEnhancedVoicePrivacy(boolean enable, Message onComplete)2025     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
2026     }
2027 
2028     /**
2029      * Get the currently set Voice Privacy (VP) mode.
2030      *
2031      * @param onComplete a callback message when the action is completed.
2032      */
getEnhancedVoicePrivacy(Message onComplete)2033     public void getEnhancedVoicePrivacy(Message onComplete) {
2034     }
2035 
2036     /**
2037      * Assign a specified band for RF configuration.
2038      *
2039      * @param bandMode one of BM_*_BAND
2040      * @param response is callback message
2041      */
setBandMode(int bandMode, Message response)2042     public void setBandMode(int bandMode, Message response) {
2043         mCi.setBandMode(bandMode, response);
2044     }
2045 
2046     /**
2047      * Query the list of band mode supported by RF.
2048      *
2049      * @param response is callback message
2050      *        ((AsyncResult)response.obj).result  is an int[] where int[0] is
2051      *        the size of the array and the rest of each element representing
2052      *        one available BM_*_BAND
2053      */
queryAvailableBandMode(Message response)2054     public void queryAvailableBandMode(Message response) {
2055         mCi.queryAvailableBandMode(response);
2056     }
2057 
2058     /**
2059      * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
2060      *
2061      * @param data The data for the request.
2062      * @param response <strong>On success</strong>,
2063      * (byte[])(((AsyncResult)response.obj).result)
2064      * <strong>On failure</strong>,
2065      * (((AsyncResult)response.obj).result) == null and
2066      * (((AsyncResult)response.obj).exception) being an instance of
2067      * com.android.internal.telephony.gsm.CommandException
2068      *
2069      * @see #invokeOemRilRequestRaw(byte[], android.os.Message)
2070      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
2071      */
2072     @Deprecated
invokeOemRilRequestRaw(byte[] data, Message response)2073     public void invokeOemRilRequestRaw(byte[] data, Message response) {
2074         mCi.invokeOemRilRequestRaw(data, response);
2075     }
2076 
2077     /**
2078      * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation.
2079      *
2080      * @param strings The strings to make available as the request data.
2081      * @param response <strong>On success</strong>, "response" bytes is
2082      * made available as:
2083      * (String[])(((AsyncResult)response.obj).result).
2084      * <strong>On failure</strong>,
2085      * (((AsyncResult)response.obj).result) == null and
2086      * (((AsyncResult)response.obj).exception) being an instance of
2087      * com.android.internal.telephony.gsm.CommandException
2088      *
2089      * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message)
2090      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
2091      */
2092     @Deprecated
invokeOemRilRequestStrings(String[] strings, Message response)2093     public void invokeOemRilRequestStrings(String[] strings, Message response) {
2094         mCi.invokeOemRilRequestStrings(strings, response);
2095     }
2096 
2097     /**
2098      * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
2099      * Used for device configuration by some CDMA operators.
2100      *
2101      * @param itemID the ID of the item to read
2102      * @param response callback message with the String response in the obj field
2103      */
nvReadItem(int itemID, Message response)2104     public void nvReadItem(int itemID, Message response) {
2105         mCi.nvReadItem(itemID, response);
2106     }
2107 
2108     /**
2109      * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
2110      * Used for device configuration by some CDMA operators.
2111      *
2112      * @param itemID the ID of the item to read
2113      * @param itemValue the value to write, as a String
2114      * @param response Callback message.
2115      */
nvWriteItem(int itemID, String itemValue, Message response)2116     public void nvWriteItem(int itemID, String itemValue, Message response) {
2117         mCi.nvWriteItem(itemID, itemValue, response);
2118     }
2119 
2120     /**
2121      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
2122      * Used for device configuration by some CDMA operators.
2123      *
2124      * @param preferredRoamingList byte array containing the new PRL
2125      * @param response Callback message.
2126      */
nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)2127     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
2128         mCi.nvWriteCdmaPrl(preferredRoamingList, response);
2129     }
2130 
2131     /**
2132      * Perform the specified type of NV config reset. The radio will be taken offline
2133      * and the device must be rebooted after erasing the NV. Used for device
2134      * configuration by some CDMA operators.
2135      *
2136      * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
2137      * @param response Callback message.
2138      */
nvResetConfig(int resetType, Message response)2139     public void nvResetConfig(int resetType, Message response) {
2140         mCi.nvResetConfig(resetType, response);
2141     }
2142 
notifyDataActivity()2143     public void notifyDataActivity() {
2144         mNotifier.notifyDataActivity(this);
2145     }
2146 
notifyMessageWaitingIndicator()2147     private void notifyMessageWaitingIndicator() {
2148         // Do not notify voice mail waiting if device doesn't support voice
2149         if (!mIsVoiceCapable)
2150             return;
2151 
2152         // This function is added to send the notification to DefaultPhoneNotifier.
2153         mNotifier.notifyMessageWaitingChanged(this);
2154     }
2155 
notifyDataConnection(String reason, String apnType, PhoneConstants.DataState state)2156     public void notifyDataConnection(String reason, String apnType,
2157             PhoneConstants.DataState state) {
2158         mNotifier.notifyDataConnection(this, reason, apnType, state);
2159     }
2160 
notifyDataConnection(String reason, String apnType)2161     public void notifyDataConnection(String reason, String apnType) {
2162         mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
2163     }
2164 
notifyDataConnection(String reason)2165     public void notifyDataConnection(String reason) {
2166         String types[] = getActiveApnTypes();
2167         for (String apnType : types) {
2168             mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
2169         }
2170     }
2171 
notifyOtaspChanged(int otaspMode)2172     public void notifyOtaspChanged(int otaspMode) {
2173         mNotifier.notifyOtaspChanged(this, otaspMode);
2174     }
2175 
notifyVoiceActivationStateChanged(int state)2176     public void notifyVoiceActivationStateChanged(int state) {
2177         mNotifier.notifyVoiceActivationStateChanged(this, state);
2178     }
2179 
notifyDataActivationStateChanged(int state)2180     public void notifyDataActivationStateChanged(int state) {
2181         mNotifier.notifyDataActivationStateChanged(this, state);
2182     }
2183 
notifyUserMobileDataStateChanged(boolean state)2184     public void notifyUserMobileDataStateChanged(boolean state) {
2185         mNotifier.notifyUserMobileDataStateChanged(this, state);
2186     }
2187 
notifySignalStrength()2188     public void notifySignalStrength() {
2189         mNotifier.notifySignalStrength(this);
2190     }
2191 
notifyCellInfo(List<CellInfo> cellInfo)2192     public void notifyCellInfo(List<CellInfo> cellInfo) {
2193         mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo));
2194     }
2195 
2196     /** Notify {@link PhysicalChannelConfig} changes. */
notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs)2197     public void notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
2198         mNotifier.notifyPhysicalChannelConfiguration(this, configs);
2199     }
2200 
notifyVoLteServiceStateChanged(VoLteServiceState lteState)2201     public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) {
2202         mNotifier.notifyVoLteServiceStateChanged(this, lteState);
2203     }
2204 
2205     /**
2206      * @return true if a mobile originating emergency call is active
2207      */
isInEmergencyCall()2208     public boolean isInEmergencyCall() {
2209         return false;
2210     }
2211 
2212     // This property is used to handle phone process crashes, and is the same for CDMA and IMS
2213     // phones
getInEcmMode()2214     protected static boolean getInEcmMode() {
2215         return SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false);
2216     }
2217 
2218     /**
2219      * @return {@code true} if we are in emergency call back mode. This is a period where the phone
2220      * should be using as little power as possible and be ready to receive an incoming call from the
2221      * emergency operator.
2222      */
isInEcm()2223     public boolean isInEcm() {
2224         return mIsPhoneInEcmState;
2225     }
2226 
setIsInEcm(boolean isInEcm)2227     public void setIsInEcm(boolean isInEcm) {
2228         setGlobalSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, String.valueOf(isInEcm));
2229         mIsPhoneInEcmState = isInEcm;
2230     }
2231 
getVideoState(Call call)2232     private static int getVideoState(Call call) {
2233         int videoState = VideoProfile.STATE_AUDIO_ONLY;
2234         Connection conn = call.getEarliestConnection();
2235         if (conn != null) {
2236             videoState = conn.getVideoState();
2237         }
2238         return videoState;
2239     }
2240 
2241     /**
2242      * Determines if the specified call currently is or was at some point a video call, or if it is
2243      * a conference call.
2244      * @param call The call.
2245      * @return {@code true} if the call is or was a video call or is a conference call,
2246      *      {@code false} otherwise.
2247      */
isVideoCallOrConference(Call call)2248     private boolean isVideoCallOrConference(Call call) {
2249         if (call.isMultiparty()) {
2250             return true;
2251         }
2252 
2253         boolean isDowngradedVideoCall = false;
2254         if (call instanceof ImsPhoneCall) {
2255             ImsPhoneCall imsPhoneCall = (ImsPhoneCall) call;
2256             ImsCall imsCall = imsPhoneCall.getImsCall();
2257             return imsCall != null && (imsCall.isVideoCall() ||
2258                     imsCall.wasVideoCall());
2259         }
2260         return isDowngradedVideoCall;
2261     }
2262 
2263     /**
2264      * @return {@code true} if an IMS video call or IMS conference is present, false otherwise.
2265      */
isImsVideoCallOrConferencePresent()2266     public boolean isImsVideoCallOrConferencePresent() {
2267         boolean isPresent = false;
2268         if (mImsPhone != null) {
2269             isPresent = isVideoCallOrConference(mImsPhone.getForegroundCall()) ||
2270                     isVideoCallOrConference(mImsPhone.getBackgroundCall()) ||
2271                     isVideoCallOrConference(mImsPhone.getRingingCall());
2272         }
2273         Rlog.d(LOG_TAG, "isImsVideoCallOrConferencePresent: " + isPresent);
2274         return isPresent;
2275     }
2276 
2277     /**
2278      * Return a numerical identifier for the phone radio interface.
2279      * @return PHONE_TYPE_XXX as defined above.
2280      */
getPhoneType()2281     public abstract int getPhoneType();
2282 
2283     /**
2284      * Returns unread voicemail count. This count is shown when the  voicemail
2285      * notification is expanded.<p>
2286      */
getVoiceMessageCount()2287     public int getVoiceMessageCount(){
2288         return mVmCount;
2289     }
2290 
2291     /** sets the voice mail count of the phone and notifies listeners. */
setVoiceMessageCount(int countWaiting)2292     public void setVoiceMessageCount(int countWaiting) {
2293         mVmCount = countWaiting;
2294         int subId = getSubId();
2295         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2296 
2297             Rlog.d(LOG_TAG, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting +
2298                     " for mVmCountKey = " + VM_COUNT + subId + " in preferences.");
2299 
2300             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2301             SharedPreferences.Editor editor = sp.edit();
2302             editor.putInt(VM_COUNT + subId, countWaiting);
2303             editor.apply();
2304         } else {
2305             Rlog.e(LOG_TAG, "setVoiceMessageCount in sharedPreference: invalid subId " + subId);
2306         }
2307         // notify listeners of voice mail
2308         notifyMessageWaitingIndicator();
2309     }
2310 
2311     /** gets the voice mail count from preferences */
getStoredVoiceMessageCount()2312     protected int getStoredVoiceMessageCount() {
2313         int countVoiceMessages = 0;
2314         int subId = getSubId();
2315         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2316             int invalidCount = -2;  //-1 is not really invalid. It is used for unknown number of vm
2317             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2318             int countFromSP = sp.getInt(VM_COUNT + subId, invalidCount);
2319             if (countFromSP != invalidCount) {
2320                 countVoiceMessages = countFromSP;
2321                 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference for subId " + subId +
2322                         "= " + countVoiceMessages);
2323             } else {
2324                 // Check for old preference if count not found for current subId. This part of the
2325                 // code is needed only when upgrading from M to N.
2326                 String subscriberId = sp.getString(VM_ID, null);
2327                 if (subscriberId != null) {
2328                     String currentSubscriberId = getSubscriberId();
2329 
2330                     if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) {
2331                         // get voice mail count from preferences
2332                         countVoiceMessages = sp.getInt(VM_COUNT, 0);
2333                         setVoiceMessageCount(countVoiceMessages);
2334                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference = " +
2335                                 countVoiceMessages);
2336                     } else {
2337                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: returning 0 as count for " +
2338                                 "matching subscriberId not found");
2339 
2340                     }
2341                     // get rid of old preferences.
2342                     SharedPreferences.Editor editor = sp.edit();
2343                     editor.remove(VM_ID);
2344                     editor.remove(VM_COUNT);
2345                     editor.apply();
2346                 }
2347             }
2348         } else {
2349             Rlog.e(LOG_TAG, "getStoredVoiceMessageCount: invalid subId " + subId);
2350         }
2351         return countVoiceMessages;
2352     }
2353 
2354     /**
2355      * send secret dialer codes to launch arbitrary activities.
2356      * an Intent is started with the android_secret_code://<code> URI.
2357      *
2358      * @param code stripped version of secret code without *#*# prefix and #*#* suffix
2359      */
sendDialerSpecialCode(String code)2360     public void sendDialerSpecialCode(String code) {
2361         if (!TextUtils.isEmpty(code)) {
2362             Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION,
2363                     Uri.parse("android_secret_code://" + code));
2364             intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
2365             mContext.sendBroadcast(intent);
2366         }
2367     }
2368 
2369     /**
2370      * Returns the CDMA ERI icon index to display
2371      */
getCdmaEriIconIndex()2372     public int getCdmaEriIconIndex() {
2373         return -1;
2374     }
2375 
2376     /**
2377      * Returns the CDMA ERI icon mode,
2378      * 0 - ON
2379      * 1 - FLASHING
2380      */
getCdmaEriIconMode()2381     public int getCdmaEriIconMode() {
2382         return -1;
2383     }
2384 
2385     /**
2386      * Returns the CDMA ERI text,
2387      */
getCdmaEriText()2388     public String getCdmaEriText() {
2389         return "GSM nw, no ERI";
2390     }
2391 
2392     /**
2393      * Retrieves the MIN for CDMA phones.
2394      */
getCdmaMin()2395     public String getCdmaMin() {
2396         return null;
2397     }
2398 
2399     /**
2400      * Check if subscription data has been assigned to mMin
2401      *
2402      * return true if MIN info is ready; false otherwise.
2403      */
isMinInfoReady()2404     public boolean isMinInfoReady() {
2405         return false;
2406     }
2407 
2408     /**
2409      *  Retrieves PRL Version for CDMA phones
2410      */
getCdmaPrlVersion()2411     public String getCdmaPrlVersion(){
2412         return null;
2413     }
2414 
2415     /**
2416      * send burst DTMF tone, it can send the string as single character or multiple character
2417      * ignore if there is no active call or not valid digits string.
2418      * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
2419      * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
2420      * this api can send single character and multiple character, also, this api has response
2421      * back to caller.
2422      *
2423      * @param dtmfString is string representing the dialing digit(s) in the active call
2424      * @param on the DTMF ON length in milliseconds, or 0 for default
2425      * @param off the DTMF OFF length in milliseconds, or 0 for default
2426      * @param onComplete is the callback message when the action is processed by BP
2427      *
2428      */
sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)2429     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
2430     }
2431 
2432     /**
2433      * Sets an event to be fired when the telephony system processes
2434      * a post-dial character on an outgoing call.<p>
2435      *
2436      * Messages of type <code>what</code> will be sent to <code>h</code>.
2437      * The <code>obj</code> field of these Message's will be instances of
2438      * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
2439      * a Connection object.<p>
2440      *
2441      * Message.arg1 will be the post dial character being processed,
2442      * or 0 ('\0') if end of string.<p>
2443      *
2444      * If Connection.getPostDialState() == WAIT,
2445      * the application must call
2446      * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
2447      * Connection.proceedAfterWaitChar()} or
2448      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2449      * Connection.cancelPostDial()}
2450      * for the telephony system to continue playing the post-dial
2451      * DTMF sequence.<p>
2452      *
2453      * If Connection.getPostDialState() == WILD,
2454      * the application must call
2455      * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
2456      * Connection.proceedAfterWildChar()}
2457      * or
2458      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2459      * Connection.cancelPostDial()}
2460      * for the telephony system to continue playing the
2461      * post-dial DTMF sequence.<p>
2462      *
2463      * Only one post dial character handler may be set. <p>
2464      * Calling this method with "h" equal to null unsets this handler.<p>
2465      */
setOnPostDialCharacter(Handler h, int what, Object obj)2466     public void setOnPostDialCharacter(Handler h, int what, Object obj) {
2467         mPostDialHandler = new Registrant(h, what, obj);
2468     }
2469 
getPostDialHandler()2470     public Registrant getPostDialHandler() {
2471         return mPostDialHandler;
2472     }
2473 
2474     /**
2475      * request to exit emergency call back mode
2476      * the caller should use setOnECMModeExitResponse
2477      * to receive the emergency callback mode exit response
2478      */
exitEmergencyCallbackMode()2479     public void exitEmergencyCallbackMode() {
2480     }
2481 
2482     /**
2483      * Register for notifications when CDMA OTA Provision status change
2484      *
2485      * @param h Handler that receives the notification message.
2486      * @param what User-defined message code.
2487      * @param obj User object.
2488      */
registerForCdmaOtaStatusChange(Handler h, int what, Object obj)2489     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
2490     }
2491 
2492     /**
2493      * Unregister for notifications when CDMA OTA Provision status change
2494      * @param h Handler to be removed from the registrant list.
2495      */
unregisterForCdmaOtaStatusChange(Handler h)2496     public void unregisterForCdmaOtaStatusChange(Handler h) {
2497     }
2498 
2499     /**
2500      * Registration point for subscription info ready
2501      * @param h handler to notify
2502      * @param what what code of message when delivered
2503      * @param obj placed in Message.obj
2504      */
registerForSubscriptionInfoReady(Handler h, int what, Object obj)2505     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
2506     }
2507 
2508     /**
2509      * Unregister for notifications for subscription info
2510      * @param h Handler to be removed from the registrant list.
2511      */
unregisterForSubscriptionInfoReady(Handler h)2512     public void unregisterForSubscriptionInfoReady(Handler h) {
2513     }
2514 
2515     /**
2516      * Returns true if OTA Service Provisioning needs to be performed.
2517      */
needsOtaServiceProvisioning()2518     public boolean needsOtaServiceProvisioning() {
2519         return false;
2520     }
2521 
2522     /**
2523      * this decides if the dial number is OTA(Over the air provision) number or not
2524      * @param dialStr is string representing the dialing digit(s)
2525      * @return  true means the dialStr is OTA number, and false means the dialStr is not OTA number
2526      */
isOtaSpNumber(String dialStr)2527     public  boolean isOtaSpNumber(String dialStr) {
2528         return false;
2529     }
2530 
2531     /**
2532      * Register for notifications when CDMA call waiting comes
2533      *
2534      * @param h Handler that receives the notification message.
2535      * @param what User-defined message code.
2536      * @param obj User object.
2537      */
registerForCallWaiting(Handler h, int what, Object obj)2538     public void registerForCallWaiting(Handler h, int what, Object obj){
2539     }
2540 
2541     /**
2542      * Unegister for notifications when CDMA Call waiting comes
2543      * @param h Handler to be removed from the registrant list.
2544      */
unregisterForCallWaiting(Handler h)2545     public void unregisterForCallWaiting(Handler h){
2546     }
2547 
2548     /**
2549      * Registration point for Ecm timer reset
2550      * @param h handler to notify
2551      * @param what user-defined message code
2552      * @param obj placed in Message.obj
2553      */
registerForEcmTimerReset(Handler h, int what, Object obj)2554     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
2555     }
2556 
2557     /**
2558      * Unregister for notification for Ecm timer reset
2559      * @param h Handler to be removed from the registrant list.
2560      */
unregisterForEcmTimerReset(Handler h)2561     public void unregisterForEcmTimerReset(Handler h) {
2562     }
2563 
2564     /**
2565      * Register for signal information notifications from the network.
2566      * Message.obj will contain an AsyncResult.
2567      * AsyncResult.result will be a SuppServiceNotification instance.
2568      *
2569      * @param h Handler that receives the notification message.
2570      * @param what User-defined message code.
2571      * @param obj User object.
2572      */
registerForSignalInfo(Handler h, int what, Object obj)2573     public void registerForSignalInfo(Handler h, int what, Object obj) {
2574         mCi.registerForSignalInfo(h, what, obj);
2575     }
2576 
2577     /**
2578      * Unregisters for signal information notifications.
2579      * Extraneous calls are tolerated silently
2580      *
2581      * @param h Handler to be removed from the registrant list.
2582      */
unregisterForSignalInfo(Handler h)2583     public void unregisterForSignalInfo(Handler h) {
2584         mCi.unregisterForSignalInfo(h);
2585     }
2586 
2587     /**
2588      * Register for display information notifications from the network.
2589      * Message.obj will contain an AsyncResult.
2590      * AsyncResult.result will be a SuppServiceNotification instance.
2591      *
2592      * @param h Handler that receives the notification message.
2593      * @param what User-defined message code.
2594      * @param obj User object.
2595      */
registerForDisplayInfo(Handler h, int what, Object obj)2596     public void registerForDisplayInfo(Handler h, int what, Object obj) {
2597         mCi.registerForDisplayInfo(h, what, obj);
2598     }
2599 
2600     /**
2601      * Unregisters for display information notifications.
2602      * Extraneous calls are tolerated silently
2603      *
2604      * @param h Handler to be removed from the registrant list.
2605      */
unregisterForDisplayInfo(Handler h)2606     public void unregisterForDisplayInfo(Handler h) {
2607          mCi.unregisterForDisplayInfo(h);
2608     }
2609 
2610     /**
2611      * Register for CDMA number information record notification from the network.
2612      * Message.obj will contain an AsyncResult.
2613      * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
2614      * instance.
2615      *
2616      * @param h Handler that receives the notification message.
2617      * @param what User-defined message code.
2618      * @param obj User object.
2619      */
registerForNumberInfo(Handler h, int what, Object obj)2620     public void registerForNumberInfo(Handler h, int what, Object obj) {
2621         mCi.registerForNumberInfo(h, what, obj);
2622     }
2623 
2624     /**
2625      * Unregisters for number information record notifications.
2626      * Extraneous calls are tolerated silently
2627      *
2628      * @param h Handler to be removed from the registrant list.
2629      */
unregisterForNumberInfo(Handler h)2630     public void unregisterForNumberInfo(Handler h) {
2631         mCi.unregisterForNumberInfo(h);
2632     }
2633 
2634     /**
2635      * Register for CDMA redirected number information record notification
2636      * from the network.
2637      * Message.obj will contain an AsyncResult.
2638      * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
2639      * instance.
2640      *
2641      * @param h Handler that receives the notification message.
2642      * @param what User-defined message code.
2643      * @param obj User object.
2644      */
registerForRedirectedNumberInfo(Handler h, int what, Object obj)2645     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
2646         mCi.registerForRedirectedNumberInfo(h, what, obj);
2647     }
2648 
2649     /**
2650      * Unregisters for redirected number information record notification.
2651      * Extraneous calls are tolerated silently
2652      *
2653      * @param h Handler to be removed from the registrant list.
2654      */
unregisterForRedirectedNumberInfo(Handler h)2655     public void unregisterForRedirectedNumberInfo(Handler h) {
2656         mCi.unregisterForRedirectedNumberInfo(h);
2657     }
2658 
2659     /**
2660      * Register for CDMA line control information record notification
2661      * from the network.
2662      * Message.obj will contain an AsyncResult.
2663      * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
2664      * instance.
2665      *
2666      * @param h Handler that receives the notification message.
2667      * @param what User-defined message code.
2668      * @param obj User object.
2669      */
registerForLineControlInfo(Handler h, int what, Object obj)2670     public void registerForLineControlInfo(Handler h, int what, Object obj) {
2671         mCi.registerForLineControlInfo(h, what, obj);
2672     }
2673 
2674     /**
2675      * Unregisters for line control information notifications.
2676      * Extraneous calls are tolerated silently
2677      *
2678      * @param h Handler to be removed from the registrant list.
2679      */
unregisterForLineControlInfo(Handler h)2680     public void unregisterForLineControlInfo(Handler h) {
2681         mCi.unregisterForLineControlInfo(h);
2682     }
2683 
2684     /**
2685      * Register for CDMA T53 CLIR information record notifications
2686      * from the network.
2687      * Message.obj will contain an AsyncResult.
2688      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
2689      * instance.
2690      *
2691      * @param h Handler that receives the notification message.
2692      * @param what User-defined message code.
2693      * @param obj User object.
2694      */
registerFoT53ClirlInfo(Handler h, int what, Object obj)2695     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
2696         mCi.registerFoT53ClirlInfo(h, what, obj);
2697     }
2698 
2699     /**
2700      * Unregisters for T53 CLIR information record notification
2701      * Extraneous calls are tolerated silently
2702      *
2703      * @param h Handler to be removed from the registrant list.
2704      */
unregisterForT53ClirInfo(Handler h)2705     public void unregisterForT53ClirInfo(Handler h) {
2706         mCi.unregisterForT53ClirInfo(h);
2707     }
2708 
2709     /**
2710      * Register for CDMA T53 audio control information record notifications
2711      * from the network.
2712      * Message.obj will contain an AsyncResult.
2713      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
2714      * instance.
2715      *
2716      * @param h Handler that receives the notification message.
2717      * @param what User-defined message code.
2718      * @param obj User object.
2719      */
registerForT53AudioControlInfo(Handler h, int what, Object obj)2720     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
2721         mCi.registerForT53AudioControlInfo(h, what, obj);
2722     }
2723 
2724     /**
2725      * Unregisters for T53 audio control information record notifications.
2726      * Extraneous calls are tolerated silently
2727      *
2728      * @param h Handler to be removed from the registrant list.
2729      */
unregisterForT53AudioControlInfo(Handler h)2730     public void unregisterForT53AudioControlInfo(Handler h) {
2731         mCi.unregisterForT53AudioControlInfo(h);
2732     }
2733 
2734     /**
2735      * registers for exit emergency call back mode request response
2736      *
2737      * @param h Handler that receives the notification message.
2738      * @param what User-defined message code.
2739      * @param obj User object.
2740      */
setOnEcbModeExitResponse(Handler h, int what, Object obj)2741     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
2742     }
2743 
2744     /**
2745      * Unregisters for exit emergency call back mode request response
2746      *
2747      * @param h Handler to be removed from the registrant list.
2748      */
unsetOnEcbModeExitResponse(Handler h)2749     public void unsetOnEcbModeExitResponse(Handler h){
2750     }
2751 
2752     /**
2753      * Register for radio off or not available
2754      *
2755      * @param h Handler that receives the notification message.
2756      * @param what User-defined message code.
2757      * @param obj User object.
2758      */
registerForRadioOffOrNotAvailable(Handler h, int what, Object obj)2759     public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) {
2760         mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj);
2761     }
2762 
2763     /**
2764      * Unregisters for radio off or not available
2765      *
2766      * @param h Handler to be removed from the registrant list.
2767      */
unregisterForRadioOffOrNotAvailable(Handler h)2768     public void unregisterForRadioOffOrNotAvailable(Handler h) {
2769         mRadioOffOrNotAvailableRegistrants.remove(h);
2770     }
2771 
2772     /**
2773      * Returns an array of string identifiers for the APN types serviced by the
2774      * currently active.
2775      *  @return The string array will always return at least one entry, Phone.APN_TYPE_DEFAULT.
2776      * TODO: Revisit if we always should return at least one entry.
2777      */
getActiveApnTypes()2778     public String[] getActiveApnTypes() {
2779         if (mDcTracker == null) {
2780             return null;
2781         }
2782 
2783         return mDcTracker.getActiveApnTypes();
2784     }
2785 
2786     /**
2787      * Check if TETHER_DUN_APN setting or config_tether_apndata includes APN that matches
2788      * current operator.
2789      * @return true if there is a matching DUN APN.
2790      */
hasMatchedTetherApnSetting()2791     public boolean hasMatchedTetherApnSetting() {
2792         return mDcTracker.hasMatchedTetherApnSetting();
2793     }
2794 
2795     /**
2796      * Returns string for the active APN host.
2797      *  @return type as a string or null if none.
2798      */
getActiveApnHost(String apnType)2799     public String getActiveApnHost(String apnType) {
2800         return mDcTracker.getActiveApnString(apnType);
2801     }
2802 
2803     /**
2804      * Return the LinkProperties for the named apn or null if not available
2805      */
getLinkProperties(String apnType)2806     public LinkProperties getLinkProperties(String apnType) {
2807         return mDcTracker.getLinkProperties(apnType);
2808     }
2809 
2810     /**
2811      * Return the NetworkCapabilities
2812      */
getNetworkCapabilities(String apnType)2813     public NetworkCapabilities getNetworkCapabilities(String apnType) {
2814         return mDcTracker.getNetworkCapabilities(apnType);
2815     }
2816 
2817     /**
2818      * Report on whether data connectivity is allowed.
2819      *
2820      * @return True if data is allowed to be established.
2821      */
isDataAllowed()2822     public boolean isDataAllowed() {
2823         return ((mDcTracker != null) && (mDcTracker.isDataAllowed(null)));
2824     }
2825 
2826     /**
2827      * Report on whether data connectivity is allowed.
2828      *
2829      * @param reasons The reasons that data can/can't be established. This is an output param.
2830      * @return True if data is allowed to be established
2831      */
isDataAllowed(DataConnectionReasons reasons)2832     public boolean isDataAllowed(DataConnectionReasons reasons) {
2833         return ((mDcTracker != null) && (mDcTracker.isDataAllowed(reasons)));
2834     }
2835 
2836 
2837     /**
2838      * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
2839      */
carrierActionSetMeteredApnsEnabled(boolean enabled)2840     public void carrierActionSetMeteredApnsEnabled(boolean enabled) {
2841         mCarrierActionAgent.carrierActionSetMeteredApnsEnabled(enabled);
2842     }
2843 
2844     /**
2845      * Action set from carrier signalling broadcast receivers to enable/disable radio
2846      */
carrierActionSetRadioEnabled(boolean enabled)2847     public void carrierActionSetRadioEnabled(boolean enabled) {
2848         mCarrierActionAgent.carrierActionSetRadioEnabled(enabled);
2849     }
2850 
2851     /**
2852      * Action set from carrier app to start/stop reporting default network condition.
2853      */
carrierActionReportDefaultNetworkStatus(boolean report)2854     public void carrierActionReportDefaultNetworkStatus(boolean report) {
2855         mCarrierActionAgent.carrierActionReportDefaultNetworkStatus(report);
2856     }
2857 
2858     /**
2859      * Notify registrants of a new ringing Connection.
2860      * Subclasses of Phone probably want to replace this with a
2861      * version scoped to their packages
2862      */
notifyNewRingingConnectionP(Connection cn)2863     public void notifyNewRingingConnectionP(Connection cn) {
2864         if (!mIsVoiceCapable)
2865             return;
2866         AsyncResult ar = new AsyncResult(null, cn, null);
2867         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
2868     }
2869 
2870     /**
2871      * Notify registrants of a new unknown connection.
2872      */
notifyUnknownConnectionP(Connection cn)2873     public void notifyUnknownConnectionP(Connection cn) {
2874         mUnknownConnectionRegistrants.notifyResult(cn);
2875     }
2876 
2877     /**
2878      * Notify registrants if phone is video capable.
2879      */
notifyForVideoCapabilityChanged(boolean isVideoCallCapable)2880     public void notifyForVideoCapabilityChanged(boolean isVideoCallCapable) {
2881         // Cache the current video capability so that we don't lose the information.
2882         mIsVideoCapable = isVideoCallCapable;
2883 
2884         AsyncResult ar = new AsyncResult(null, isVideoCallCapable, null);
2885         mVideoCapabilityChangedRegistrants.notifyRegistrants(ar);
2886     }
2887 
2888     /**
2889      * Notify registrants of a RING event.
2890      */
notifyIncomingRing()2891     private void notifyIncomingRing() {
2892         if (!mIsVoiceCapable)
2893             return;
2894         AsyncResult ar = new AsyncResult(null, this, null);
2895         mIncomingRingRegistrants.notifyRegistrants(ar);
2896     }
2897 
2898     /**
2899      * Send the incoming call Ring notification if conditions are right.
2900      */
sendIncomingCallRingNotification(int token)2901     private void sendIncomingCallRingNotification(int token) {
2902         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
2903                 (token == mCallRingContinueToken)) {
2904             Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
2905             notifyIncomingRing();
2906             sendMessageDelayed(
2907                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
2908         } else {
2909             Rlog.d(LOG_TAG, "Ignoring ring notification request,"
2910                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
2911                     + " token=" + token
2912                     + " mCallRingContinueToken=" + mCallRingContinueToken
2913                     + " mIsVoiceCapable=" + mIsVoiceCapable);
2914         }
2915     }
2916 
2917     /**
2918      * TODO: Adding a function for each property is not good.
2919      * A fucntion of type getPhoneProp(propType) where propType is an
2920      * enum of GSM+CDMA+LTE props would be a better approach.
2921      *
2922      * Get "Restriction of menu options for manual PLMN selection" bit
2923      * status from EF_CSP data, this belongs to "Value Added Services Group".
2924      * @return true if this bit is set or EF_CSP data is unavailable,
2925      * false otherwise
2926      */
isCspPlmnEnabled()2927     public boolean isCspPlmnEnabled() {
2928         return false;
2929     }
2930 
2931     /**
2932      * Return an interface to retrieve the ISIM records for IMS, if available.
2933      * @return the interface to retrieve the ISIM records, or null if not supported
2934      */
getIsimRecords()2935     public IsimRecords getIsimRecords() {
2936         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
2937         return null;
2938     }
2939 
2940     /**
2941      * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to
2942      * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns
2943      * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones.
2944      */
getMsisdn()2945     public String getMsisdn() {
2946         return null;
2947     }
2948 
2949     /**
2950      * Retrieves the EF_PNN from the UICC For GSM/UMTS phones.
2951      */
getPlmn()2952     public String getPlmn() {
2953         return null;
2954     }
2955 
2956     /**
2957      * Get the current for the default apn DataState. No change notification
2958      * exists at this interface -- use
2959      * {@link android.telephony.PhoneStateListener} instead.
2960      */
getDataConnectionState()2961     public PhoneConstants.DataState getDataConnectionState() {
2962         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
2963     }
2964 
notifyCallForwardingIndicator()2965     public void notifyCallForwardingIndicator() {
2966     }
2967 
notifyDataConnectionFailed(String reason, String apnType)2968     public void notifyDataConnectionFailed(String reason, String apnType) {
2969         mNotifier.notifyDataConnectionFailed(this, reason, apnType);
2970     }
2971 
notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause)2972     public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
2973             String failCause) {
2974         mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause);
2975     }
2976 
2977     /**
2978      * Return if the current radio is LTE on CDMA. This
2979      * is a tri-state return value as for a period of time
2980      * the mode may be unknown.
2981      *
2982      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
2983      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
2984      */
getLteOnCdmaMode()2985     public int getLteOnCdmaMode() {
2986         return mCi.getLteOnCdmaMode();
2987     }
2988 
2989     /**
2990      * Sets the SIM voice message waiting indicator records.
2991      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
2992      * @param countWaiting The number of messages waiting, if known. Use
2993      *                     -1 to indicate that an unknown number of
2994      *                      messages are waiting
2995      */
setVoiceMessageWaiting(int line, int countWaiting)2996     public void setVoiceMessageWaiting(int line, int countWaiting) {
2997         // This function should be overridden by class GsmCdmaPhone.
2998         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone.");
2999     }
3000 
3001     /**
3002      * Gets the USIM service table from the UICC, if present and available.
3003      * @return an interface to the UsimServiceTable record, or null if not available
3004      */
getUsimServiceTable()3005     public UsimServiceTable getUsimServiceTable() {
3006         IccRecords r = mIccRecords.get();
3007         return (r != null) ? r.getUsimServiceTable() : null;
3008     }
3009 
3010     /**
3011      * Gets the Uicc card corresponding to this phone.
3012      * @return the UiccCard object corresponding to the phone ID.
3013      */
getUiccCard()3014     public UiccCard getUiccCard() {
3015         return mUiccController.getUiccCard(mPhoneId);
3016     }
3017 
3018     /**
3019      * Get P-CSCF address from PCO after data connection is established or modified.
3020      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
3021      */
getPcscfAddress(String apnType)3022     public String[] getPcscfAddress(String apnType) {
3023         return mDcTracker.getPcscfAddress(apnType);
3024     }
3025 
3026     /**
3027      * Set IMS registration state
3028      */
setImsRegistrationState(boolean registered)3029     public void setImsRegistrationState(boolean registered) {
3030     }
3031 
3032     /**
3033      * Return an instance of a IMS phone
3034      */
getImsPhone()3035     public Phone getImsPhone() {
3036         return mImsPhone;
3037     }
3038 
3039     /**
3040      * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
3041      * @param keyType whether the key is being used for WLAN or ePDG.
3042      * @return ImsiEncryptionInfo which includes the Key Type, the Public Key
3043      *        {@link java.security.PublicKey} and the Key Identifier.
3044      *        The keyIdentifier This is used by the server to help it locate the private key to
3045      *        decrypt the permanent identity.
3046      */
getCarrierInfoForImsiEncryption(int keyType)3047     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) {
3048         return null;
3049     }
3050 
3051     /**
3052      * Sets the carrier information needed to encrypt the IMSI and IMPI.
3053      * @param imsiEncryptionInfo Carrier specific information that will be used to encrypt the
3054      *        IMSI and IMPI. This includes the Key type, the Public key
3055      *        {@link java.security.PublicKey} and the Key identifier.
3056      */
setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo)3057     public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo) {
3058         return;
3059     }
3060 
getCarrierId()3061     public int getCarrierId() {
3062         return TelephonyManager.UNKNOWN_CARRIER_ID;
3063     }
3064 
getCarrierName()3065     public String getCarrierName() {
3066         return null;
3067     }
3068 
getCarrierIdListVersion()3069     public int getCarrierIdListVersion() {
3070         return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
3071     }
3072 
3073     /**
3074      *  Resets the Carrier Keys in the database. This involves 2 steps:
3075      *  1. Delete the keys from the database.
3076      *  2. Send an intent to download new Certificates.
3077      */
resetCarrierKeysForImsiEncryption()3078     public void resetCarrierKeysForImsiEncryption() {
3079         return;
3080     }
3081 
3082     /**
3083      * Return if UT capability of ImsPhone is enabled or not
3084      */
isUtEnabled()3085     public boolean isUtEnabled() {
3086         if (mImsPhone != null) {
3087             return mImsPhone.isUtEnabled();
3088         }
3089         return false;
3090     }
3091 
dispose()3092     public void dispose() {
3093     }
3094 
updateImsPhone()3095     private void updateImsPhone() {
3096         Rlog.d(LOG_TAG, "updateImsPhone"
3097                 + " mImsServiceReady=" + mImsServiceReady);
3098 
3099         if (mImsServiceReady && (mImsPhone == null)) {
3100             mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
3101             CallManager.getInstance().registerPhone(mImsPhone);
3102             mImsPhone.registerForSilentRedial(
3103                     this, EVENT_INITIATE_SILENT_REDIAL, null);
3104         } else if (!mImsServiceReady && (mImsPhone != null)) {
3105             CallManager.getInstance().unregisterPhone(mImsPhone);
3106             mImsPhone.unregisterForSilentRedial(this);
3107 
3108             mImsPhone.dispose();
3109             // Potential GC issue if someone keeps a reference to ImsPhone.
3110             // However: this change will make sure that such a reference does
3111             // not access functions through NULL pointer.
3112             //mImsPhone.removeReferences();
3113             mImsPhone = null;
3114         }
3115     }
3116 
3117     /**
3118      * Dials a number.
3119      *
3120      * @param dialString The number to dial.
3121      * @param dialArgs Parameters to dial with.
3122      * @return The Connection.
3123      * @throws CallStateException
3124      */
dialInternal(String dialString, DialArgs dialArgs)3125     protected Connection dialInternal(String dialString, DialArgs dialArgs)
3126             throws CallStateException {
3127         // dialInternal shall be overriden by GsmCdmaPhone
3128         return null;
3129     }
3130 
3131     /*
3132      * Returns the subscription id.
3133      */
getSubId()3134     public int getSubId() {
3135         return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId);
3136     }
3137 
3138     /**
3139      * Returns the phone id.
3140      */
getPhoneId()3141     public int getPhoneId() {
3142         return mPhoneId;
3143     }
3144 
3145     /**
3146      * Return the service state of mImsPhone if it is STATE_IN_SERVICE
3147      * otherwise return the current voice service state
3148      */
getVoicePhoneServiceState()3149     public int getVoicePhoneServiceState() {
3150         Phone imsPhone = mImsPhone;
3151         if (imsPhone != null
3152                 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
3153             return ServiceState.STATE_IN_SERVICE;
3154         }
3155         return getServiceState().getState();
3156     }
3157 
3158     /**
3159      * Override the service provider name and the operator name for the current ICCID.
3160      */
setOperatorBrandOverride(String brand)3161     public boolean setOperatorBrandOverride(String brand) {
3162         return false;
3163     }
3164 
3165     /**
3166      * Override the roaming indicator for the current ICCID.
3167      */
setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)3168     public boolean setRoamingOverride(List<String> gsmRoamingList,
3169             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3170             List<String> cdmaNonRoamingList) {
3171         String iccId = getIccSerialNumber();
3172         if (TextUtils.isEmpty(iccId)) {
3173             return false;
3174         }
3175 
3176         setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3177         setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3178         setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3179         setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3180 
3181         // Refresh.
3182         ServiceStateTracker tracker = getServiceStateTracker();
3183         if (tracker != null) {
3184             tracker.pollState();
3185         }
3186         return true;
3187     }
3188 
setRoamingOverrideHelper(List<String> list, String prefix, String iccId)3189     private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) {
3190         SharedPreferences.Editor spEditor =
3191                 PreferenceManager.getDefaultSharedPreferences(mContext).edit();
3192         String key = prefix + iccId;
3193         if (list == null || list.isEmpty()) {
3194             spEditor.remove(key).commit();
3195         } else {
3196             spEditor.putStringSet(key, new HashSet<String>(list)).commit();
3197         }
3198     }
3199 
isMccMncMarkedAsRoaming(String mccMnc)3200     public boolean isMccMncMarkedAsRoaming(String mccMnc) {
3201         return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
3202     }
3203 
isMccMncMarkedAsNonRoaming(String mccMnc)3204     public boolean isMccMncMarkedAsNonRoaming(String mccMnc) {
3205         return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
3206     }
3207 
isSidMarkedAsRoaming(int SID)3208     public boolean isSidMarkedAsRoaming(int SID) {
3209         return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX,
3210                 Integer.toString(SID));
3211     }
3212 
isSidMarkedAsNonRoaming(int SID)3213     public boolean isSidMarkedAsNonRoaming(int SID) {
3214         return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX,
3215                 Integer.toString(SID));
3216     }
3217 
3218     /**
3219      * Query the IMS Registration Status.
3220      *
3221      * @return true if IMS is Registered
3222      */
isImsRegistered()3223     public boolean isImsRegistered() {
3224         Phone imsPhone = mImsPhone;
3225         boolean isImsRegistered = false;
3226         if (imsPhone != null) {
3227             isImsRegistered = imsPhone.isImsRegistered();
3228         } else {
3229             ServiceStateTracker sst = getServiceStateTracker();
3230             if (sst != null) {
3231                 isImsRegistered = sst.isImsRegistered();
3232             }
3233         }
3234         Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered);
3235         return isImsRegistered;
3236     }
3237 
3238     /**
3239      * Get Wifi Calling Feature Availability
3240      */
isWifiCallingEnabled()3241     public boolean isWifiCallingEnabled() {
3242         Phone imsPhone = mImsPhone;
3243         boolean isWifiCallingEnabled = false;
3244         if (imsPhone != null) {
3245             isWifiCallingEnabled = imsPhone.isWifiCallingEnabled();
3246         }
3247         Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled);
3248         return isWifiCallingEnabled;
3249     }
3250 
3251     /**
3252      * Get Volte Feature Availability
3253      */
isVolteEnabled()3254     public boolean isVolteEnabled() {
3255         Phone imsPhone = mImsPhone;
3256         boolean isVolteEnabled = false;
3257         if (imsPhone != null) {
3258             isVolteEnabled = imsPhone.isVolteEnabled();
3259         }
3260         Rlog.d(LOG_TAG, "isImsRegistered =" + isVolteEnabled);
3261         return isVolteEnabled;
3262     }
3263 
3264     /**
3265      * @return the IMS MmTel Registration technology for this Phone, defined in
3266      * {@link ImsRegistrationImplBase}.
3267      */
getImsRegistrationTech()3268     public int getImsRegistrationTech() {
3269         Phone imsPhone = mImsPhone;
3270         int regTech = ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
3271         if (imsPhone != null) {
3272             regTech = imsPhone.getImsRegistrationTech();
3273         }
3274         Rlog.d(LOG_TAG, "getImsRegistrationTechnology =" + regTech);
3275         return regTech;
3276     }
3277 
getRoamingOverrideHelper(String prefix, String key)3278     private boolean getRoamingOverrideHelper(String prefix, String key) {
3279         String iccId = getIccSerialNumber();
3280         if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) {
3281             return false;
3282         }
3283 
3284         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
3285         Set<String> value = sp.getStringSet(prefix + iccId, null);
3286         if (value == null) {
3287             return false;
3288         }
3289         return value.contains(key);
3290     }
3291 
3292     /**
3293      * Is Radio Present on the device and is it accessible
3294      */
isRadioAvailable()3295     public boolean isRadioAvailable() {
3296         return mCi.getRadioState().isAvailable();
3297     }
3298 
3299     /**
3300      * Is Radio turned on
3301      */
isRadioOn()3302     public boolean isRadioOn() {
3303         return mCi.getRadioState().isOn();
3304     }
3305 
3306     /**
3307      * shutdown Radio gracefully
3308      */
shutdownRadio()3309     public void shutdownRadio() {
3310         getServiceStateTracker().requestShutdown();
3311     }
3312 
3313     /**
3314      * Return true if the device is shutting down.
3315      */
isShuttingDown()3316     public boolean isShuttingDown() {
3317         return getServiceStateTracker().isDeviceShuttingDown();
3318     }
3319 
3320     /**
3321      *  Set phone radio capability
3322      *
3323      *  @param rc the phone radio capability defined in
3324      *         RadioCapability. It's a input object used to transfer parameter to logic modem
3325      *  @param response Callback message.
3326      */
setRadioCapability(RadioCapability rc, Message response)3327     public void setRadioCapability(RadioCapability rc, Message response) {
3328         mCi.setRadioCapability(rc, response);
3329     }
3330 
3331     /**
3332      *  Get phone radio access family
3333      *
3334      *  @return a bit mask to identify the radio access family.
3335      */
getRadioAccessFamily()3336     public int getRadioAccessFamily() {
3337         final RadioCapability rc = getRadioCapability();
3338         return (rc == null ? RadioAccessFamily.RAF_UNKNOWN : rc.getRadioAccessFamily());
3339     }
3340 
3341     /**
3342      *  Get the associated data modems Id.
3343      *
3344      *  @return a String containing the id of the data modem
3345      */
getModemUuId()3346     public String getModemUuId() {
3347         final RadioCapability rc = getRadioCapability();
3348         return (rc == null ? "" : rc.getLogicalModemUuid());
3349     }
3350 
3351     /**
3352      *  Get phone radio capability
3353      *
3354      *  @return the capability of the radio defined in RadioCapability
3355      */
getRadioCapability()3356     public RadioCapability getRadioCapability() {
3357         return mRadioCapability.get();
3358     }
3359 
3360     /**
3361      *  The RadioCapability has changed. This comes up from the RIL and is called when radios first
3362      *  become available or after a capability switch.  The flow is we use setRadioCapability to
3363      *  request a change with the RIL and get an UNSOL response with the new data which gets set
3364      *  here.
3365      *
3366      *  @param rc the phone radio capability currently in effect for this phone.
3367      */
radioCapabilityUpdated(RadioCapability rc)3368     public void radioCapabilityUpdated(RadioCapability rc) {
3369         // Called when radios first become available or after a capability switch
3370         // Update the cached value
3371         mRadioCapability.set(rc);
3372 
3373         if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
3374             boolean restoreSelection = !mContext.getResources().getBoolean(
3375                     com.android.internal.R.bool.skip_restoring_network_selection);
3376             sendSubscriptionSettings(restoreSelection);
3377         }
3378     }
3379 
sendSubscriptionSettings(boolean restoreNetworkSelection)3380     public void sendSubscriptionSettings(boolean restoreNetworkSelection) {
3381         // Send settings down
3382         int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
3383         setPreferredNetworkType(type, null);
3384 
3385         if (restoreNetworkSelection) {
3386             restoreSavedNetworkSelection(null);
3387         }
3388     }
3389 
setPreferredNetworkTypeIfSimLoaded()3390     protected void setPreferredNetworkTypeIfSimLoaded() {
3391         int subId = getSubId();
3392         if (SubscriptionManager.isValidSubscriptionId(subId)) {
3393             int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
3394             setPreferredNetworkType(type, null);
3395         }
3396     }
3397 
3398     /**
3399      * Registers the handler when phone radio  capability is changed.
3400      *
3401      * @param h Handler for notification message.
3402      * @param what User-defined message code.
3403      * @param obj User object.
3404      */
registerForRadioCapabilityChanged(Handler h, int what, Object obj)3405     public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) {
3406         mCi.registerForRadioCapabilityChanged(h, what, obj);
3407     }
3408 
3409     /**
3410      * Unregister for notifications when phone radio type and access technology is changed.
3411      *
3412      * @param h Handler to be removed from the registrant list.
3413      */
unregisterForRadioCapabilityChanged(Handler h)3414     public void unregisterForRadioCapabilityChanged(Handler h) {
3415         mCi.unregisterForRadioCapabilityChanged(this);
3416     }
3417 
3418     /**
3419      * Determines if  IMS is enabled for call.
3420      *
3421      * @return {@code true} if IMS calling is enabled.
3422      */
isImsUseEnabled()3423     public boolean isImsUseEnabled() {
3424         ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
3425         boolean imsUseEnabled = ((imsManager.isVolteEnabledByPlatform()
3426                 && imsManager.isEnhanced4gLteModeSettingEnabledByUser())
3427                 || (imsManager.isWfcEnabledByPlatform() && imsManager.isWfcEnabledByUser())
3428                 && imsManager.isNonTtyOrTtyOnVolteEnabled());
3429         return imsUseEnabled;
3430     }
3431 
3432     /**
3433      * Determines if the connection to IMS services are available yet.
3434      * @return {@code true} if the connection to IMS services are available.
3435      */
isImsAvailable()3436     public boolean isImsAvailable() {
3437         if (mImsPhone == null) {
3438             return false;
3439         }
3440 
3441         return mImsPhone.isImsAvailable();
3442     }
3443 
3444     /**
3445      * Determines if video calling is enabled for the phone.
3446      *
3447      * @return {@code true} if video calling is enabled, {@code false} otherwise.
3448      */
isVideoEnabled()3449     public boolean isVideoEnabled() {
3450         Phone imsPhone = mImsPhone;
3451         if (imsPhone != null) {
3452             return imsPhone.isVideoEnabled();
3453         }
3454         return false;
3455     }
3456 
3457     /**
3458      * Returns the status of Link Capacity Estimation (LCE) service.
3459      */
getLceStatus()3460     public int getLceStatus() {
3461         return mLceStatus;
3462     }
3463 
3464     /**
3465      * Returns the modem activity information
3466      */
getModemActivityInfo(Message response)3467     public void getModemActivityInfo(Message response)  {
3468         mCi.getModemActivityInfo(response);
3469     }
3470 
3471     /**
3472      * Starts LCE service after radio becomes available.
3473      * LCE service state may get destroyed on the modem when radio becomes unavailable.
3474      */
startLceAfterRadioIsAvailable()3475     public void startLceAfterRadioIsAvailable() {
3476         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
3477                 obtainMessage(EVENT_CONFIG_LCE));
3478     }
3479 
3480     /**
3481      * Set allowed carriers
3482      */
setAllowedCarriers(List<CarrierIdentifier> carriers, Message response)3483     public void setAllowedCarriers(List<CarrierIdentifier> carriers, Message response) {
3484         mCi.setAllowedCarriers(carriers, response);
3485     }
3486 
3487     /** Sets the SignalStrength reporting criteria. */
setSignalStrengthReportingCriteria(int[] thresholds, int ran)3488     public void setSignalStrengthReportingCriteria(int[] thresholds, int ran) {
3489         // no-op default implementation
3490     }
3491 
3492     /** Sets the SignalStrength reporting criteria. */
setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran)3493     public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) {
3494         // no-op default implementation
3495     }
3496 
3497     /**
3498      * Get allowed carriers
3499      */
getAllowedCarriers(Message response)3500     public void getAllowedCarriers(Message response) {
3501         mCi.getAllowedCarriers(response);
3502     }
3503 
3504     /**
3505      * Returns the locale based on the carrier properties (such as {@code ro.carrier}) and
3506      * SIM preferences.
3507      */
getLocaleFromSimAndCarrierPrefs()3508     public Locale getLocaleFromSimAndCarrierPrefs() {
3509         final IccRecords records = mIccRecords.get();
3510         if (records != null && records.getSimLanguage() != null) {
3511             return new Locale(records.getSimLanguage());
3512         }
3513 
3514         return getLocaleFromCarrierProperties(mContext);
3515     }
3516 
updateDataConnectionTracker()3517     public void updateDataConnectionTracker() {
3518         mDcTracker.update();
3519     }
3520 
setInternalDataEnabled(boolean enable, Message onCompleteMsg)3521     public void setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
3522         mDcTracker.setInternalDataEnabled(enable, onCompleteMsg);
3523     }
3524 
updateCurrentCarrierInProvider()3525     public boolean updateCurrentCarrierInProvider() {
3526         return false;
3527     }
3528 
registerForAllDataDisconnected(Handler h, int what, Object obj)3529     public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
3530         mDcTracker.registerForAllDataDisconnected(h, what, obj);
3531     }
3532 
unregisterForAllDataDisconnected(Handler h)3533     public void unregisterForAllDataDisconnected(Handler h) {
3534         mDcTracker.unregisterForAllDataDisconnected(h);
3535     }
3536 
registerForDataEnabledChanged(Handler h, int what, Object obj)3537     public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
3538         mDcTracker.registerForDataEnabledChanged(h, what, obj);
3539     }
3540 
unregisterForDataEnabledChanged(Handler h)3541     public void unregisterForDataEnabledChanged(Handler h) {
3542         mDcTracker.unregisterForDataEnabledChanged(h);
3543     }
3544 
getIccSmsInterfaceManager()3545     public IccSmsInterfaceManager getIccSmsInterfaceManager(){
3546         return null;
3547     }
3548 
isMatchGid(String gid)3549     protected boolean isMatchGid(String gid) {
3550         String gid1 = getGroupIdLevel1();
3551         int gidLength = gid.length();
3552         if (!TextUtils.isEmpty(gid1) && (gid1.length() >= gidLength)
3553                 && gid1.substring(0, gidLength).equalsIgnoreCase(gid)) {
3554             return true;
3555         }
3556         return false;
3557     }
3558 
checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, int phoneId, Context context)3559     public static void checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, int phoneId, Context context)
3560             throws CallStateException {
3561         if (imsPhone == null || !imsPhone.isWifiCallingEnabled()) {
3562             ImsManager imsManager = ImsManager.getInstance(context, phoneId);
3563             boolean wfcWiFiOnly = (imsManager.isWfcEnabledByPlatform()
3564                     && imsManager.isWfcEnabledByUser() && (imsManager.getWfcMode()
3565                     == ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY));
3566             if (wfcWiFiOnly) {
3567                 throw new CallStateException(
3568                         CallStateException.ERROR_OUT_OF_SERVICE,
3569                         "WFC Wi-Fi Only Mode: IMS not registered");
3570             }
3571         }
3572     }
3573 
startRingbackTone()3574     public void startRingbackTone() {
3575     }
3576 
stopRingbackTone()3577     public void stopRingbackTone() {
3578     }
3579 
callEndCleanupHandOverCallIfAny()3580     public void callEndCleanupHandOverCallIfAny() {
3581     }
3582 
cancelUSSD()3583     public void cancelUSSD() {
3584     }
3585 
3586     /**
3587      * Set boolean broadcastEmergencyCallStateChanges
3588      */
setBroadcastEmergencyCallStateChanges(boolean broadcast)3589     public abstract void setBroadcastEmergencyCallStateChanges(boolean broadcast);
3590 
sendEmergencyCallStateChange(boolean callActive)3591     public abstract void sendEmergencyCallStateChange(boolean callActive);
3592 
3593     /**
3594      * This function returns the parent phone of the current phone. It is applicable
3595      * only for IMS phone (function is overridden by ImsPhone). For others the phone
3596      * object itself is returned.
3597      * @return
3598      */
getDefaultPhone()3599     public Phone getDefaultPhone() {
3600         return this;
3601     }
3602 
3603     /**
3604      * Get aggregated video call data usage since boot.
3605      * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
3606      *
3607      * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
3608      * @return Snapshot of video call data usage
3609      */
getVtDataUsage(boolean perUidStats)3610     public NetworkStats getVtDataUsage(boolean perUidStats) {
3611         if (mImsPhone == null) return null;
3612         return mImsPhone.getVtDataUsage(perUidStats);
3613     }
3614 
3615     /**
3616      * Policy control of data connection. Usually used when we hit data limit.
3617      * @param enabled True if enabling the data, otherwise disabling.
3618      */
setPolicyDataEnabled(boolean enabled)3619     public void setPolicyDataEnabled(boolean enabled) {
3620         mDcTracker.setPolicyDataEnabled(enabled);
3621     }
3622 
3623     /**
3624      * SIP URIs aliased to the current subscriber given by the IMS implementation.
3625      * Applicable only on IMS; used in absence of line1number.
3626      * @return array of SIP URIs aliased to the current subscriber
3627      */
getCurrentSubscriberUris()3628     public Uri[] getCurrentSubscriberUris() {
3629         return null;
3630     }
3631 
getAppSmsManager()3632     public AppSmsManager getAppSmsManager() {
3633         return mAppSmsManager;
3634     }
3635 
3636     /**
3637      * Set SIM card power state.
3638      * @param state State of SIM (power down, power up, pass through)
3639      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
3640      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
3641      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
3642      **/
setSimPowerState(int state)3643     public void setSimPowerState(int state) {
3644         mCi.setSimCardPower(state, null);
3645     }
3646 
setRadioIndicationUpdateMode(int filters, int mode)3647     public void setRadioIndicationUpdateMode(int filters, int mode) {
3648         if (mDeviceStateMonitor != null) {
3649             mDeviceStateMonitor.setIndicationUpdateMode(filters, mode);
3650         }
3651     }
3652 
setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1, String gid2, String pnn, String spn)3653     public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1,
3654             String gid2, String pnn, String spn) {
3655     }
3656 
dump(FileDescriptor fd, PrintWriter pw, String[] args)3657     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3658         pw.println("Phone: subId=" + getSubId());
3659         pw.println(" mPhoneId=" + mPhoneId);
3660         pw.println(" mCi=" + mCi);
3661         pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
3662         pw.println(" mDcTracker=" + mDcTracker);
3663         pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
3664         pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
3665         pw.println(" mCallRingDelay=" + mCallRingDelay);
3666         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
3667         pw.println(" mIccRecords=" + mIccRecords.get());
3668         pw.println(" mUiccApplication=" + mUiccApplication.get());
3669         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
3670         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
3671         pw.flush();
3672         pw.println(" mLooper=" + mLooper);
3673         pw.println(" mContext=" + mContext);
3674         pw.println(" mNotifier=" + mNotifier);
3675         pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
3676         pw.println(" mUnitTestMode=" + mUnitTestMode);
3677         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
3678         pw.println(" getUnitTestMode()=" + getUnitTestMode());
3679         pw.println(" getState()=" + getState());
3680         pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
3681         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
3682         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
3683         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
3684         pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
3685         pw.flush();
3686         pw.println(" isInEcm()=" + isInEcm());
3687         pw.println(" getPhoneName()=" + getPhoneName());
3688         pw.println(" getPhoneType()=" + getPhoneType());
3689         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
3690         pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
3691         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
3692         pw.flush();
3693         pw.println("++++++++++++++++++++++++++++++++");
3694 
3695         if (mImsPhone != null) {
3696             try {
3697                 mImsPhone.dump(fd, pw, args);
3698             } catch (Exception e) {
3699                 e.printStackTrace();
3700             }
3701 
3702             pw.flush();
3703             pw.println("++++++++++++++++++++++++++++++++");
3704         }
3705 
3706         if (mDcTracker != null) {
3707             try {
3708                 mDcTracker.dump(fd, pw, args);
3709             } catch (Exception e) {
3710                 e.printStackTrace();
3711             }
3712 
3713             pw.flush();
3714             pw.println("++++++++++++++++++++++++++++++++");
3715         }
3716 
3717         if (getServiceStateTracker() != null) {
3718             try {
3719                 getServiceStateTracker().dump(fd, pw, args);
3720             } catch (Exception e) {
3721                 e.printStackTrace();
3722             }
3723 
3724             pw.flush();
3725             pw.println("++++++++++++++++++++++++++++++++");
3726         }
3727 
3728         if (mCarrierActionAgent != null) {
3729             try {
3730                 mCarrierActionAgent.dump(fd, pw, args);
3731             } catch (Exception e) {
3732                 e.printStackTrace();
3733             }
3734 
3735             pw.flush();
3736             pw.println("++++++++++++++++++++++++++++++++");
3737         }
3738 
3739         if (mCarrierSignalAgent != null) {
3740             try {
3741                 mCarrierSignalAgent.dump(fd, pw, args);
3742             } catch (Exception e) {
3743                 e.printStackTrace();
3744             }
3745 
3746             pw.flush();
3747             pw.println("++++++++++++++++++++++++++++++++");
3748         }
3749 
3750         if (getCallTracker() != null) {
3751             try {
3752                 getCallTracker().dump(fd, pw, args);
3753             } catch (Exception e) {
3754                 e.printStackTrace();
3755             }
3756 
3757             pw.flush();
3758             pw.println("++++++++++++++++++++++++++++++++");
3759         }
3760 
3761         if (mSimActivationTracker != null) {
3762             try {
3763                 mSimActivationTracker.dump(fd, pw, args);
3764             } catch (Exception e) {
3765                 e.printStackTrace();
3766             }
3767 
3768             pw.flush();
3769             pw.println("++++++++++++++++++++++++++++++++");
3770         }
3771 
3772         if (mDeviceStateMonitor != null) {
3773             pw.println("DeviceStateMonitor:");
3774             mDeviceStateMonitor.dump(fd, pw, args);
3775             pw.println("++++++++++++++++++++++++++++++++");
3776         }
3777 
3778         if (mCi != null && mCi instanceof RIL) {
3779             try {
3780                 ((RIL)mCi).dump(fd, pw, args);
3781             } catch (Exception e) {
3782                 e.printStackTrace();
3783             }
3784 
3785             pw.flush();
3786             pw.println("++++++++++++++++++++++++++++++++");
3787         }
3788     }
3789 }
3790