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