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