Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.telephony;
     18 
     19 import android.content.BroadcastReceiver;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.IntentFilter;
     23 import android.content.SharedPreferences;
     24 import android.net.LinkProperties;
     25 import android.net.NetworkCapabilities;
     26 import android.net.NetworkStats;
     27 import android.net.Uri;
     28 import android.net.wifi.WifiManager;
     29 import android.os.AsyncResult;
     30 import android.os.Build;
     31 import android.os.Handler;
     32 import android.os.Looper;
     33 import android.os.Message;
     34 import android.os.PersistableBundle;
     35 import android.os.Registrant;
     36 import android.os.RegistrantList;
     37 import android.os.SystemProperties;
     38 import android.os.WorkSource;
     39 import android.preference.PreferenceManager;
     40 import android.provider.Settings;
     41 import android.service.carrier.CarrierIdentifier;
     42 import android.telecom.VideoProfile;
     43 import android.telephony.CarrierConfigManager;
     44 import android.telephony.CellIdentityCdma;
     45 import android.telephony.CellInfo;
     46 import android.telephony.CellInfoCdma;
     47 import android.telephony.CellLocation;
     48 import android.telephony.ClientRequestStats;
     49 import android.telephony.ImsiEncryptionInfo;
     50 import android.telephony.PhoneStateListener;
     51 import android.telephony.PhysicalChannelConfig;
     52 import android.telephony.RadioAccessFamily;
     53 import android.telephony.Rlog;
     54 import android.telephony.ServiceState;
     55 import android.telephony.SignalStrength;
     56 import android.telephony.SubscriptionManager;
     57 import android.telephony.TelephonyManager;
     58 import android.telephony.VoLteServiceState;
     59 import android.telephony.ims.stub.ImsRegistrationImplBase;
     60 import android.text.TextUtils;
     61 
     62 import com.android.ims.ImsCall;
     63 import com.android.ims.ImsConfig;
     64 import com.android.ims.ImsManager;
     65 import com.android.internal.R;
     66 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
     67 import com.android.internal.telephony.dataconnection.DcTracker;
     68 import com.android.internal.telephony.imsphone.ImsPhoneCall;
     69 import com.android.internal.telephony.test.SimulatedRadioControl;
     70 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
     71 import com.android.internal.telephony.uicc.IccFileHandler;
     72 import com.android.internal.telephony.uicc.IccRecords;
     73 import com.android.internal.telephony.uicc.IsimRecords;
     74 import com.android.internal.telephony.uicc.UiccCard;
     75 import com.android.internal.telephony.uicc.UiccCardApplication;
     76 import com.android.internal.telephony.uicc.UiccController;
     77 import com.android.internal.telephony.uicc.UsimServiceTable;
     78 
     79 import java.io.FileDescriptor;
     80 import java.io.PrintWriter;
     81 import java.util.ArrayList;
     82 import java.util.HashSet;
     83 import java.util.List;
     84 import java.util.Locale;
     85 import java.util.Set;
     86 import java.util.concurrent.atomic.AtomicReference;
     87 
     88 /**
     89  * (<em>Not for SDK use</em>)
     90  * A base implementation for the com.android.internal.telephony.Phone interface.
     91  *
     92  * Note that implementations of Phone.java are expected to be used
     93  * from a single application thread. This should be the same thread that
     94  * originally called PhoneFactory to obtain the interface.
     95  *
     96  *  {@hide}
     97  *
     98  */
     99 
    100 public abstract class Phone extends Handler implements PhoneInternalInterface {
    101     private static final String LOG_TAG = "Phone";
    102 
    103     protected final static Object lockForRadioTechnologyChange = new Object();
    104 
    105     protected final int USSD_MAX_QUEUE = 10;
    106 
    107     private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
    108         @Override
    109         public void onReceive(Context context, Intent intent) {
    110             Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction());
    111             if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) {
    112                 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID,
    113                         SubscriptionManager.INVALID_PHONE_INDEX);
    114                 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId);
    115                 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX ||
    116                         extraPhoneId != getPhoneId()) {
    117                     return;
    118                 }
    119             }
    120 
    121             synchronized (Phone.lockForRadioTechnologyChange) {
    122                 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
    123                     mImsServiceReady = true;
    124                     updateImsPhone();
    125                     ImsManager.getInstance(mContext, mPhoneId).updateImsServiceConfig(false);
    126                 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
    127                     mImsServiceReady = false;
    128                     updateImsPhone();
    129                 }
    130             }
    131         }
    132     };
    133 
    134     // Key used to read and write the saved network selection numeric value
    135     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
    136     // Key used to read and write the saved network selection operator name
    137     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
    138     // Key used to read and write the saved network selection operator short name
    139     public static final String NETWORK_SELECTION_SHORT_KEY = "network_selection_short_key";
    140 
    141 
    142     // Key used to read/write "disable data connection on boot" pref (used for testing)
    143     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
    144 
    145     // Key used to read/write data_roaming_is_user_setting pref
    146     public static final String DATA_ROAMING_IS_USER_SETTING_KEY = "data_roaming_is_user_setting_key";
    147 
    148     /* Event Constants */
    149     protected static final int EVENT_RADIO_AVAILABLE             = 1;
    150     /** Supplementary Service Notification received. */
    151     protected static final int EVENT_SSN                         = 2;
    152     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
    153     private static final int EVENT_MMI_DONE                      = 4;
    154     protected static final int EVENT_RADIO_ON                    = 5;
    155     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
    156     protected static final int EVENT_USSD                        = 7;
    157     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
    158     protected static final int EVENT_GET_IMEI_DONE               = 9;
    159     protected static final int EVENT_GET_IMEISV_DONE             = 10;
    160     private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
    161     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
    162     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
    163     protected static final int EVENT_CALL_RING                   = 14;
    164     private static final int EVENT_CALL_RING_CONTINUE            = 15;
    165 
    166     // Used to intercept the carrier selection calls so that
    167     // we can save the values.
    168     private static final int EVENT_SET_NETWORK_MANUAL_COMPLETE      = 16;
    169     private static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE   = 17;
    170     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
    171     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
    172     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
    173     // Events for CDMA support
    174     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
    175     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
    176     protected static final int EVENT_NV_READY                       = 23;
    177     private static final int EVENT_SET_ENHANCED_VP                  = 24;
    178     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
    179     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
    180     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
    181     // other
    182     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
    183     protected static final int EVENT_ICC_RECORD_EVENTS              = 29;
    184     private static final int EVENT_ICC_CHANGED                      = 30;
    185     // Single Radio Voice Call Continuity
    186     private static final int EVENT_SRVCC_STATE_CHANGED              = 31;
    187     private static final int EVENT_INITIATE_SILENT_REDIAL           = 32;
    188     private static final int EVENT_RADIO_NOT_AVAILABLE              = 33;
    189     private static final int EVENT_UNSOL_OEM_HOOK_RAW               = 34;
    190     protected static final int EVENT_GET_RADIO_CAPABILITY           = 35;
    191     protected static final int EVENT_SS                             = 36;
    192     private static final int EVENT_CONFIG_LCE                       = 37;
    193     private static final int EVENT_CHECK_FOR_NETWORK_AUTOMATIC      = 38;
    194     protected static final int EVENT_VOICE_RADIO_TECH_CHANGED       = 39;
    195     protected static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE  = 40;
    196     protected static final int EVENT_RIL_CONNECTED                  = 41;
    197     protected static final int EVENT_UPDATE_PHONE_OBJECT            = 42;
    198     protected static final int EVENT_CARRIER_CONFIG_CHANGED         = 43;
    199     // Carrier's CDMA prefer mode setting
    200     protected static final int EVENT_SET_ROAMING_PREFERENCE_DONE    = 44;
    201     protected static final int EVENT_MODEM_RESET                    = 45;
    202 
    203     protected static final int EVENT_LAST                       = EVENT_MODEM_RESET;
    204 
    205     // For shared prefs.
    206     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
    207     private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_";
    208     private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_";
    209     private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_";
    210 
    211     // Key used to read/write current CLIR setting
    212     public static final String CLIR_KEY = "clir_key";
    213 
    214     // Key used for storing voice mail count
    215     private static final String VM_COUNT = "vm_count_key";
    216     // Key used to read/write the ID for storing the voice mail
    217     private static final String VM_ID = "vm_id_key";
    218 
    219     // Key used for storing call forwarding status
    220     public static final String CF_STATUS = "cf_status_key";
    221     // Key used to read/write the ID for storing the call forwarding status
    222     public static final String CF_ID = "cf_id_key";
    223 
    224     // Key used to read/write "disable DNS server check" pref (used for testing)
    225     private static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
    226 
    227     // Integer used to let the calling application know that the we are ignoring auto mode switch.
    228     private static final int ALREADY_IN_AUTO_SELECTION = 1;
    229 
    230     /**
    231      * This method is invoked when the Phone exits Emergency Callback Mode.
    232      */
    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