Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2007 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.wifi.WifiManager;
     27 import android.os.AsyncResult;
     28 import android.os.Build;
     29 import android.os.Handler;
     30 import android.os.Looper;
     31 import android.os.Message;
     32 import android.os.Registrant;
     33 import android.os.RegistrantList;
     34 import android.os.SystemProperties;
     35 import android.preference.PreferenceManager;
     36 import android.provider.Settings;
     37 import android.telecom.VideoProfile;
     38 import android.telephony.CellIdentityCdma;
     39 import android.telephony.CellInfo;
     40 import android.telephony.CellInfoCdma;
     41 import android.telephony.DataConnectionRealTimeInfo;
     42 import android.telephony.VoLteServiceState;
     43 import android.telephony.Rlog;
     44 import android.telephony.ServiceState;
     45 import android.telephony.SignalStrength;
     46 import android.telephony.SubscriptionManager;
     47 import android.text.TextUtils;
     48 
     49 import com.android.ims.ImsManager;
     50 import com.android.internal.R;
     51 import com.android.internal.telephony.dataconnection.DcTrackerBase;
     52 import com.android.internal.telephony.imsphone.ImsPhone;
     53 import com.android.internal.telephony.test.SimulatedRadioControl;
     54 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
     55 import com.android.internal.telephony.uicc.IccFileHandler;
     56 import com.android.internal.telephony.uicc.IccRecords;
     57 import com.android.internal.telephony.uicc.IsimRecords;
     58 import com.android.internal.telephony.uicc.UiccCard;
     59 import com.android.internal.telephony.uicc.UiccCardApplication;
     60 import com.android.internal.telephony.uicc.UiccController;
     61 import com.android.internal.telephony.uicc.UsimServiceTable;
     62 
     63 import java.io.FileDescriptor;
     64 import java.io.PrintWriter;
     65 import java.util.ArrayList;
     66 import java.util.List;
     67 import java.util.Locale;
     68 import java.util.concurrent.atomic.AtomicReference;
     69 
     70 /**
     71  * (<em>Not for SDK use</em>)
     72  * A base implementation for the com.android.internal.telephony.Phone interface.
     73  *
     74  * Note that implementations of Phone.java are expected to be used
     75  * from a single application thread. This should be the same thread that
     76  * originally called PhoneFactory to obtain the interface.
     77  *
     78  *  {@hide}
     79  *
     80  */
     81 
     82 public abstract class PhoneBase extends Handler implements Phone {
     83     private static final String LOG_TAG = "PhoneBase";
     84 
     85     private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
     86         @Override
     87         public void onReceive(Context context, Intent intent) {
     88             // TODO: MSIM potentially replace SUBID with information available to external
     89             // service, e.g. slot ID
     90             if (intent.hasExtra(ImsManager.EXTRA_SUBID)) {
     91                 if (intent.getLongExtra(ImsManager.EXTRA_SUBID, -1) != getSubId())
     92                     return;
     93             }
     94 
     95             if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
     96                 mImsServiceReady = true;
     97                 updateImsPhone();
     98             } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
     99                 mImsServiceReady = false;
    100                 updateImsPhone();
    101             }
    102         }
    103     };
    104 
    105     // Key used to read and write the saved network selection numeric value
    106     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
    107     // Key used to read and write the saved network selection operator name
    108     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
    109 
    110 
    111     // Key used to read/write "disable data connection on boot" pref (used for testing)
    112     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
    113 
    114     /* Event Constants */
    115     protected static final int EVENT_RADIO_AVAILABLE             = 1;
    116     /** Supplementary Service Notification received. */
    117     protected static final int EVENT_SSN                         = 2;
    118     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
    119     protected static final int EVENT_MMI_DONE                    = 4;
    120     protected static final int EVENT_RADIO_ON                    = 5;
    121     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
    122     protected static final int EVENT_USSD                        = 7;
    123     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
    124     protected static final int EVENT_GET_IMEI_DONE               = 9;
    125     protected static final int EVENT_GET_IMEISV_DONE             = 10;
    126     protected static final int EVENT_GET_SIM_STATUS_DONE         = 11;
    127     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
    128     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
    129     protected static final int EVENT_CALL_RING                   = 14;
    130     protected static final int EVENT_CALL_RING_CONTINUE          = 15;
    131 
    132     // Used to intercept the carrier selection calls so that
    133     // we can save the values.
    134     protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE    = 16;
    135     protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17;
    136     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
    137     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
    138     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
    139     // Events for CDMA support
    140     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
    141     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
    142     protected static final int EVENT_NV_READY                       = 23;
    143     protected static final int EVENT_SET_ENHANCED_VP                = 24;
    144     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
    145     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
    146     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
    147     // other
    148     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
    149     protected static final int EVENT_ICC_RECORD_EVENTS              = 29;
    150     protected static final int EVENT_ICC_CHANGED                    = 30;
    151     // Single Radio Voice Call Continuity
    152     protected static final int EVENT_SRVCC_STATE_CHANGED            = 31;
    153     protected static final int EVENT_INITIATE_SILENT_REDIAL         = 32;
    154     protected static final int EVENT_UNSOL_OEM_HOOK_RAW             = 33;
    155     protected static final int EVENT_LAST                           = EVENT_UNSOL_OEM_HOOK_RAW;
    156 
    157     // Key used to read/write current CLIR setting
    158     public static final String CLIR_KEY = "clir_key";
    159 
    160     // Key used to read/write "disable DNS server check" pref (used for testing)
    161     public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
    162 
    163     /**
    164      * Small container class used to hold information relevant to
    165      * the carrier selection process. operatorNumeric can be ""
    166      * if we are looking for automatic selection. operatorAlphaLong is the
    167      * corresponding operator name.
    168      */
    169     protected static class NetworkSelectMessage {
    170         public Message message;
    171         public String operatorNumeric;
    172         public String operatorAlphaLong;
    173     }
    174 
    175     /* Instance Variables */
    176     public CommandsInterface mCi;
    177     boolean mDnsCheckDisabled;
    178     public DcTrackerBase mDcTracker;
    179     boolean mDoesRilSendMultipleCallRing;
    180     int mCallRingContinueToken;
    181     int mCallRingDelay;
    182     public boolean mIsTheCurrentActivePhone = true;
    183     boolean mIsVoiceCapable = true;
    184     protected UiccController mUiccController = null;
    185     public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
    186     public SmsStorageMonitor mSmsStorageMonitor;
    187     public SmsUsageMonitor mSmsUsageMonitor;
    188     protected AtomicReference<UiccCardApplication> mUiccApplication =
    189             new AtomicReference<UiccCardApplication>();
    190 
    191     private TelephonyTester mTelephonyTester;
    192     private final String mName;
    193     private final String mActionDetached;
    194     private final String mActionAttached;
    195 
    196     // Holds the subscription information
    197     protected Subscription mSubscriptionData = null;
    198     protected int mPhoneId;
    199 
    200     private final Object mImsLock = new Object();
    201     private boolean mImsServiceReady = false;
    202     protected ImsPhone mImsPhone = null;
    203 
    204     @Override
    205     public String getPhoneName() {
    206         return mName;
    207     }
    208 
    209     /**
    210      * Return the ActionDetached string. When this action is received by components
    211      * they are to simulate detaching from the network.
    212      *
    213      * @return com.android.internal.telephony.{mName}.action_detached
    214      *          {mName} is GSM, CDMA ...
    215      */
    216     public String getActionDetached() {
    217         return mActionDetached;
    218     }
    219 
    220     /**
    221      * Return the ActionAttached string. When this action is received by components
    222      * they are to simulate attaching to the network.
    223      *
    224      * @return com.android.internal.telephony.{mName}.action_detached
    225      *          {mName} is GSM, CDMA ...
    226      */
    227     public String getActionAttached() {
    228         return mActionAttached;
    229     }
    230 
    231     /**
    232      * Set a system property, unless we're in unit test mode
    233      */
    234     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
    235     public void setSystemProperty(String property, String value) {
    236         if(getUnitTestMode()) {
    237             return;
    238         }
    239         SystemProperties.set(property, value);
    240     }
    241 
    242     /**
    243      * Set a system property, unless we're in unit test mode
    244      */
    245     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
    246     public String getSystemProperty(String property, String defValue) {
    247         if(getUnitTestMode()) {
    248             return null;
    249         }
    250         return SystemProperties.get(property, defValue);
    251     }
    252 
    253 
    254     protected final RegistrantList mPreciseCallStateRegistrants
    255             = new RegistrantList();
    256 
    257     protected final RegistrantList mHandoverRegistrants
    258              = new RegistrantList();
    259 
    260     protected final RegistrantList mNewRingingConnectionRegistrants
    261             = new RegistrantList();
    262 
    263     protected final RegistrantList mIncomingRingRegistrants
    264             = new RegistrantList();
    265 
    266     protected final RegistrantList mDisconnectRegistrants
    267             = new RegistrantList();
    268 
    269     protected final RegistrantList mServiceStateRegistrants
    270             = new RegistrantList();
    271 
    272     protected final RegistrantList mMmiCompleteRegistrants
    273             = new RegistrantList();
    274 
    275     protected final RegistrantList mMmiRegistrants
    276             = new RegistrantList();
    277 
    278     protected final RegistrantList mUnknownConnectionRegistrants
    279             = new RegistrantList();
    280 
    281     protected final RegistrantList mSuppServiceFailedRegistrants
    282             = new RegistrantList();
    283 
    284     protected final RegistrantList mSimRecordsLoadedRegistrants
    285             = new RegistrantList();
    286 
    287     protected Looper mLooper; /* to insure registrants are in correct thread*/
    288 
    289     protected final Context mContext;
    290 
    291     /**
    292      * PhoneNotifier is an abstraction for all system-wide
    293      * state change notification. DefaultPhoneNotifier is
    294      * used here unless running we're inside a unit test.
    295      */
    296     protected PhoneNotifier mNotifier;
    297 
    298     protected SimulatedRadioControl mSimulatedRadioControl;
    299 
    300     boolean mUnitTestMode;
    301 
    302     /**
    303      * Constructs a PhoneBase in normal (non-unit test) mode.
    304      *
    305      * @param notifier An instance of DefaultPhoneNotifier,
    306      * @param context Context object from hosting application
    307      * unless unit testing.
    308      * @param ci the CommandsInterface
    309      */
    310     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci) {
    311         this(name, notifier, context, ci, false);
    312     }
    313 
    314     /**
    315      * Constructs a PhoneBase in normal (non-unit test) mode.
    316      *
    317      * @param notifier An instance of DefaultPhoneNotifier,
    318      * @param context Context object from hosting application
    319      * unless unit testing.
    320      * @param ci is CommandsInterface
    321      * @param unitTestMode when true, prevents notifications
    322      * of state change events
    323      */
    324     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
    325             boolean unitTestMode) {
    326         this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_ID);
    327     }
    328 
    329     /**
    330      * Constructs a PhoneBase in normal (non-unit test) mode.
    331      *
    332      * @param notifier An instance of DefaultPhoneNotifier,
    333      * @param context Context object from hosting application
    334      * unless unit testing.
    335      * @param ci is CommandsInterface
    336      * @param unitTestMode when true, prevents notifications
    337      * of state change events
    338      * @param subscription is current phone subscription
    339      */
    340     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
    341             boolean unitTestMode, int phoneId) {
    342         mPhoneId = phoneId;
    343         mName = name;
    344         mNotifier = notifier;
    345         mContext = context;
    346         mLooper = Looper.myLooper();
    347         mCi = ci;
    348         mActionDetached = this.getClass().getPackage().getName() + ".action_detached";
    349         mActionAttached = this.getClass().getPackage().getName() + ".action_attached";
    350 
    351         if (Build.IS_DEBUGGABLE) {
    352             mTelephonyTester = new TelephonyTester(this);
    353         }
    354 
    355         setUnitTestMode(unitTestMode);
    356 
    357         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
    358         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
    359         mCi.setOnCallRing(this, EVENT_CALL_RING, null);
    360 
    361         /* "Voice capable" means that this device supports circuit-switched
    362         * (i.e. voice) phone calls over the telephony network, and is allowed
    363         * to display the in-call UI while a cellular voice call is active.
    364         * This will be false on "data only" devices which can't make voice
    365         * calls and don't support any in-call UI.
    366         */
    367         mIsVoiceCapable = mContext.getResources().getBoolean(
    368                 com.android.internal.R.bool.config_voice_capable);
    369 
    370         /**
    371          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
    372          *  to be generated locally. Ideally all ring tones should be loops
    373          * and this wouldn't be necessary. But to minimize changes to upper
    374          * layers it is requested that it be generated by lower layers.
    375          *
    376          * By default old phones won't have the property set but do generate
    377          * the RIL_UNSOL_CALL_RING so the default if there is no property is
    378          * true.
    379          */
    380         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
    381                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
    382         Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
    383 
    384         mCallRingDelay = SystemProperties.getInt(
    385                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
    386         Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
    387 
    388         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) return;
    389 
    390         setPropertiesByCarrier();
    391 
    392         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
    393         mSmsStorageMonitor = new SmsStorageMonitor(this);
    394         mSmsUsageMonitor = new SmsUsageMonitor(context);
    395         mUiccController = UiccController.getInstance();
    396         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
    397 
    398         // Monitor IMS service
    399         IntentFilter filter = new IntentFilter();
    400         filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
    401         filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
    402         mContext.registerReceiver(mImsIntentReceiver, filter);
    403 
    404         mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
    405         mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null);
    406     }
    407 
    408     @Override
    409     public void dispose() {
    410         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
    411             mContext.unregisterReceiver(mImsIntentReceiver);
    412             mCi.unSetOnCallRing(this);
    413             // Must cleanup all connectionS and needs to use sendMessage!
    414             mDcTracker.cleanUpAllConnections(null);
    415             mIsTheCurrentActivePhone = false;
    416             // Dispose the SMS usage and storage monitors
    417             mSmsStorageMonitor.dispose();
    418             mSmsUsageMonitor.dispose();
    419             mUiccController.unregisterForIccChanged(this);
    420             mCi.unregisterForSrvccStateChanged(this);
    421             mCi.unSetOnUnsolOemHookRaw(this);
    422 
    423             if (mTelephonyTester != null) {
    424                 mTelephonyTester.dispose();
    425             }
    426 
    427             ImsPhone imsPhone = mImsPhone;
    428             if (imsPhone != null) {
    429                 imsPhone.unregisterForSilentRedial(this);
    430                 imsPhone.dispose();
    431             }
    432         }
    433     }
    434 
    435     @Override
    436     public void removeReferences() {
    437         mSmsStorageMonitor = null;
    438         mSmsUsageMonitor = null;
    439         mIccRecords.set(null);
    440         mUiccApplication.set(null);
    441         mDcTracker = null;
    442         mUiccController = null;
    443 
    444         ImsPhone imsPhone = mImsPhone;
    445         if (imsPhone != null) {
    446             imsPhone.removeReferences();
    447             mImsPhone = null;
    448         }
    449     }
    450 
    451     /**
    452      * When overridden the derived class needs to call
    453      * super.handleMessage(msg) so this method has a
    454      * a chance to process the message.
    455      *
    456      * @param msg
    457      */
    458     @Override
    459     public void handleMessage(Message msg) {
    460         AsyncResult ar;
    461 
    462         if (!mIsTheCurrentActivePhone) {
    463             Rlog.e(LOG_TAG, "Received message " + msg +
    464                     "[" + msg.what + "] while being destroyed. Ignoring.");
    465             return;
    466         }
    467         switch(msg.what) {
    468             case EVENT_CALL_RING:
    469                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
    470                 ar = (AsyncResult)msg.obj;
    471                 if (ar.exception == null) {
    472                     PhoneConstants.State state = getState();
    473                     if ((!mDoesRilSendMultipleCallRing)
    474                             && ((state == PhoneConstants.State.RINGING) ||
    475                                     (state == PhoneConstants.State.IDLE))) {
    476                         mCallRingContinueToken += 1;
    477                         sendIncomingCallRingNotification(mCallRingContinueToken);
    478                     } else {
    479                         notifyIncomingRing();
    480                     }
    481                 }
    482                 break;
    483 
    484             case EVENT_CALL_RING_CONTINUE:
    485                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
    486                 if (getState() == PhoneConstants.State.RINGING) {
    487                     sendIncomingCallRingNotification(msg.arg1);
    488                 }
    489                 break;
    490 
    491             case EVENT_ICC_CHANGED:
    492                 onUpdateIccAvailability();
    493                 break;
    494 
    495             // handle the select network completion callbacks.
    496             case EVENT_SET_NETWORK_MANUAL_COMPLETE:
    497             case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
    498                 handleSetSelectNetwork((AsyncResult) msg.obj);
    499                 break;
    500 
    501             case EVENT_INITIATE_SILENT_REDIAL:
    502                 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
    503                 ar = (AsyncResult) msg.obj;
    504                 if ((ar.exception == null) && (ar.result != null)) {
    505                     String dialString = (String) ar.result;
    506                     if (TextUtils.isEmpty(dialString)) return;
    507                     try {
    508                         dialInternal(dialString, null, VideoProfile.VideoState.AUDIO_ONLY);
    509                     } catch (CallStateException e) {
    510                         Rlog.e(LOG_TAG, "silent redial failed: " + e);
    511                     }
    512                 }
    513                 break;
    514 
    515             case EVENT_SRVCC_STATE_CHANGED:
    516                 ar = (AsyncResult)msg.obj;
    517                 if (ar.exception == null) {
    518                     handleSrvccStateChanged((int[]) ar.result);
    519                 } else {
    520                     Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception);
    521                 }
    522                 break;
    523 
    524             case EVENT_UNSOL_OEM_HOOK_RAW:
    525                 ar = (AsyncResult)msg.obj;
    526                 if (ar.exception == null) {
    527                     byte[] data = (byte[])ar.result;
    528                     Rlog.d(LOG_TAG, "EVENT_UNSOL_OEM_HOOK_RAW data="
    529                             + IccUtils.bytesToHexString(data));
    530                     mNotifier.notifyOemHookRawEventForSubscriber(getSubId(), data);
    531                 } else {
    532                     Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception);
    533                 }
    534                 break;
    535 
    536             default:
    537                 throw new RuntimeException("unexpected event not handled");
    538         }
    539     }
    540 
    541     private void handleSrvccStateChanged(int[] ret) {
    542         Rlog.d(LOG_TAG, "handleSrvccStateChanged");
    543 
    544         Connection conn = null;
    545         ImsPhone imsPhone = mImsPhone;
    546         Call.SrvccState srvccState = Call.SrvccState.NONE;
    547         if (ret != null && ret.length != 0) {
    548             int state = ret[0];
    549             switch(state) {
    550                 case VoLteServiceState.HANDOVER_STARTED:
    551                     srvccState = Call.SrvccState.STARTED;
    552                     if (imsPhone != null) {
    553                         conn = imsPhone.getHandoverConnection();
    554                     } else {
    555                         Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null");
    556                     }
    557                     break;
    558                 case VoLteServiceState.HANDOVER_COMPLETED:
    559                     srvccState = Call.SrvccState.COMPLETED;
    560                     if (imsPhone != null) {
    561                         imsPhone.notifySrvccState(srvccState);
    562                     } else {
    563                         Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null");
    564                     }
    565                     break;
    566                 case VoLteServiceState.HANDOVER_FAILED:
    567                 case VoLteServiceState.HANDOVER_CANCELED:
    568                     srvccState = Call.SrvccState.FAILED;
    569                     break;
    570 
    571                 default:
    572                     //ignore invalid state
    573                     return;
    574             }
    575 
    576             getCallTracker().notifySrvccState(srvccState, conn);
    577 
    578             VoLteServiceState lteState = new VoLteServiceState(state);
    579             notifyVoLteServiceStateChanged(lteState);
    580         }
    581     }
    582 
    583     // Inherited documentation suffices.
    584     @Override
    585     public Context getContext() {
    586         return mContext;
    587     }
    588 
    589     // Will be called when icc changed
    590     protected abstract void onUpdateIccAvailability();
    591 
    592     /**
    593      * Disables the DNS check (i.e., allows "0.0.0.0").
    594      * Useful for lab testing environment.
    595      * @param b true disables the check, false enables.
    596      */
    597     @Override
    598     public void disableDnsCheck(boolean b) {
    599         mDnsCheckDisabled = b;
    600         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
    601         SharedPreferences.Editor editor = sp.edit();
    602         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
    603         editor.apply();
    604     }
    605 
    606     /**
    607      * Returns true if the DNS check is currently disabled.
    608      */
    609     @Override
    610     public boolean isDnsCheckDisabled() {
    611         return mDnsCheckDisabled;
    612     }
    613 
    614     // Inherited documentation suffices.
    615     @Override
    616     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
    617         checkCorrectThread(h);
    618 
    619         mPreciseCallStateRegistrants.addUnique(h, what, obj);
    620     }
    621 
    622     // Inherited documentation suffices.
    623     @Override
    624     public void unregisterForPreciseCallStateChanged(Handler h) {
    625         mPreciseCallStateRegistrants.remove(h);
    626     }
    627 
    628     /**
    629      * Subclasses of Phone probably want to replace this with a
    630      * version scoped to their packages
    631      */
    632     protected void notifyPreciseCallStateChangedP() {
    633         AsyncResult ar = new AsyncResult(null, this, null);
    634         mPreciseCallStateRegistrants.notifyRegistrants(ar);
    635 
    636         mNotifier.notifyPreciseCallState(this);
    637     }
    638 
    639     @Override
    640     public void registerForHandoverStateChanged(Handler h, int what, Object obj) {
    641         checkCorrectThread(h);
    642         mHandoverRegistrants.addUnique(h, what, obj);
    643     }
    644 
    645     @Override
    646     public void unregisterForHandoverStateChanged(Handler h) {
    647         mHandoverRegistrants.remove(h);
    648     }
    649 
    650     /**
    651      * Subclasses of Phone probably want to replace this with a
    652      * version scoped to their packages
    653      */
    654     public void notifyHandoverStateChanged(Connection cn) {
    655        AsyncResult ar = new AsyncResult(null, cn, null);
    656        mHandoverRegistrants.notifyRegistrants(ar);
    657     }
    658 
    659     public void migrateFrom(PhoneBase from) {
    660         migrate(mHandoverRegistrants, from.mHandoverRegistrants);
    661         migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
    662         migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
    663         migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
    664         migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
    665         migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
    666         migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
    667         migrate(mMmiRegistrants, from.mMmiRegistrants);
    668         migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
    669         migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
    670     }
    671 
    672     public void migrate(RegistrantList to, RegistrantList from) {
    673         from.removeCleared();
    674         for (int i = 0, n = from.size(); i < n; i++) {
    675             to.add((Registrant) from.get(i));
    676         }
    677     }
    678 
    679     // Inherited documentation suffices.
    680     @Override
    681     public void registerForUnknownConnection(Handler h, int what, Object obj) {
    682         checkCorrectThread(h);
    683 
    684         mUnknownConnectionRegistrants.addUnique(h, what, obj);
    685     }
    686 
    687     // Inherited documentation suffices.
    688     @Override
    689     public void unregisterForUnknownConnection(Handler h) {
    690         mUnknownConnectionRegistrants.remove(h);
    691     }
    692 
    693     // Inherited documentation suffices.
    694     @Override
    695     public void registerForNewRingingConnection(
    696             Handler h, int what, Object obj) {
    697         checkCorrectThread(h);
    698 
    699         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
    700     }
    701 
    702     // Inherited documentation suffices.
    703     @Override
    704     public void unregisterForNewRingingConnection(Handler h) {
    705         mNewRingingConnectionRegistrants.remove(h);
    706     }
    707 
    708     // Inherited documentation suffices.
    709     @Override
    710     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
    711         mCi.registerForInCallVoicePrivacyOn(h, what, obj);
    712     }
    713 
    714     // Inherited documentation suffices.
    715     @Override
    716     public void unregisterForInCallVoicePrivacyOn(Handler h){
    717         mCi.unregisterForInCallVoicePrivacyOn(h);
    718     }
    719 
    720     // Inherited documentation suffices.
    721     @Override
    722     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
    723         mCi.registerForInCallVoicePrivacyOff(h, what, obj);
    724     }
    725 
    726     // Inherited documentation suffices.
    727     @Override
    728     public void unregisterForInCallVoicePrivacyOff(Handler h){
    729         mCi.unregisterForInCallVoicePrivacyOff(h);
    730     }
    731 
    732     // Inherited documentation suffices.
    733     @Override
    734     public void registerForIncomingRing(
    735             Handler h, int what, Object obj) {
    736         checkCorrectThread(h);
    737 
    738         mIncomingRingRegistrants.addUnique(h, what, obj);
    739     }
    740 
    741     // Inherited documentation suffices.
    742     @Override
    743     public void unregisterForIncomingRing(Handler h) {
    744         mIncomingRingRegistrants.remove(h);
    745     }
    746 
    747     // Inherited documentation suffices.
    748     @Override
    749     public void registerForDisconnect(Handler h, int what, Object obj) {
    750         checkCorrectThread(h);
    751 
    752         mDisconnectRegistrants.addUnique(h, what, obj);
    753     }
    754 
    755     // Inherited documentation suffices.
    756     @Override
    757     public void unregisterForDisconnect(Handler h) {
    758         mDisconnectRegistrants.remove(h);
    759     }
    760 
    761     // Inherited documentation suffices.
    762     @Override
    763     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
    764         checkCorrectThread(h);
    765 
    766         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
    767     }
    768 
    769     // Inherited documentation suffices.
    770     @Override
    771     public void unregisterForSuppServiceFailed(Handler h) {
    772         mSuppServiceFailedRegistrants.remove(h);
    773     }
    774 
    775     // Inherited documentation suffices.
    776     @Override
    777     public void registerForMmiInitiate(Handler h, int what, Object obj) {
    778         checkCorrectThread(h);
    779 
    780         mMmiRegistrants.addUnique(h, what, obj);
    781     }
    782 
    783     // Inherited documentation suffices.
    784     @Override
    785     public void unregisterForMmiInitiate(Handler h) {
    786         mMmiRegistrants.remove(h);
    787     }
    788 
    789     // Inherited documentation suffices.
    790     @Override
    791     public void registerForMmiComplete(Handler h, int what, Object obj) {
    792         checkCorrectThread(h);
    793 
    794         mMmiCompleteRegistrants.addUnique(h, what, obj);
    795     }
    796 
    797     // Inherited documentation suffices.
    798     @Override
    799     public void unregisterForMmiComplete(Handler h) {
    800         checkCorrectThread(h);
    801 
    802         mMmiCompleteRegistrants.remove(h);
    803     }
    804 
    805     public void registerForSimRecordsLoaded(Handler h, int what, Object obj) {
    806         logUnexpectedCdmaMethodCall("registerForSimRecordsLoaded");
    807     }
    808 
    809     public void unregisterForSimRecordsLoaded(Handler h) {
    810         logUnexpectedCdmaMethodCall("unregisterForSimRecordsLoaded");
    811     }
    812 
    813     @Override
    814     public void setNetworkSelectionModeAutomatic(Message response) {
    815         // wrap the response message in our own message along with
    816         // an empty string (to indicate automatic selection) for the
    817         // operator's id.
    818         NetworkSelectMessage nsm = new NetworkSelectMessage();
    819         nsm.message = response;
    820         nsm.operatorNumeric = "";
    821         nsm.operatorAlphaLong = "";
    822 
    823         Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
    824         mCi.setNetworkSelectionModeAutomatic(msg);
    825     }
    826 
    827     @Override
    828     public void selectNetworkManually(OperatorInfo network, Message response) {
    829         // wrap the response message in our own message along with
    830         // the operator's id.
    831         NetworkSelectMessage nsm = new NetworkSelectMessage();
    832         nsm.message = response;
    833         nsm.operatorNumeric = network.getOperatorNumeric();
    834         nsm.operatorAlphaLong = network.getOperatorAlphaLong();
    835 
    836         Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
    837         mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
    838     }
    839 
    840     /**
    841      * Used to track the settings upon completion of the network change.
    842      */
    843     private void handleSetSelectNetwork(AsyncResult ar) {
    844         // look for our wrapper within the asyncresult, skip the rest if it
    845         // is null.
    846         if (!(ar.userObj instanceof NetworkSelectMessage)) {
    847             Rlog.e(LOG_TAG, "unexpected result from user object.");
    848             return;
    849         }
    850 
    851         NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
    852 
    853         // found the object, now we send off the message we had originally
    854         // attached to the request.
    855         if (nsm.message != null) {
    856             AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
    857             nsm.message.sendToTarget();
    858         }
    859 
    860         // open the shared preferences editor, and write the value.
    861         // nsm.operatorNumeric is "" if we're in automatic.selection.
    862         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
    863         SharedPreferences.Editor editor = sp.edit();
    864         editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
    865         editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong);
    866 
    867         // commit and log the result.
    868         if (!editor.commit()) {
    869             Rlog.e(LOG_TAG, "failed to commit network selection preference");
    870         }
    871     }
    872 
    873     /**
    874      * Method to retrieve the saved operator id from the Shared Preferences
    875      */
    876     private String getSavedNetworkSelection() {
    877         // open the shared preferences and search with our key.
    878         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
    879         return sp.getString(NETWORK_SELECTION_KEY, "");
    880     }
    881 
    882     /**
    883      * Method to restore the previously saved operator id, or reset to
    884      * automatic selection, all depending upon the value in the shared
    885      * preferences.
    886      */
    887     public void restoreSavedNetworkSelection(Message response) {
    888         // retrieve the operator id
    889         String networkSelection = getSavedNetworkSelection();
    890 
    891         // set to auto if the id is empty, otherwise select the network.
    892         if (TextUtils.isEmpty(networkSelection)) {
    893             mCi.setNetworkSelectionModeAutomatic(response);
    894         } else {
    895             mCi.setNetworkSelectionModeManual(networkSelection, response);
    896         }
    897     }
    898 
    899     // Inherited documentation suffices.
    900     @Override
    901     public void setUnitTestMode(boolean f) {
    902         mUnitTestMode = f;
    903     }
    904 
    905     // Inherited documentation suffices.
    906     @Override
    907     public boolean getUnitTestMode() {
    908         return mUnitTestMode;
    909     }
    910 
    911     /**
    912      * To be invoked when a voice call Connection disconnects.
    913      *
    914      * Subclasses of Phone probably want to replace this with a
    915      * version scoped to their packages
    916      */
    917     protected void notifyDisconnectP(Connection cn) {
    918         AsyncResult ar = new AsyncResult(null, cn, null);
    919         mDisconnectRegistrants.notifyRegistrants(ar);
    920     }
    921 
    922     // Inherited documentation suffices.
    923     @Override
    924     public void registerForServiceStateChanged(
    925             Handler h, int what, Object obj) {
    926         checkCorrectThread(h);
    927 
    928         mServiceStateRegistrants.add(h, what, obj);
    929     }
    930 
    931     // Inherited documentation suffices.
    932     @Override
    933     public void unregisterForServiceStateChanged(Handler h) {
    934         mServiceStateRegistrants.remove(h);
    935     }
    936 
    937     // Inherited documentation suffices.
    938     @Override
    939     public void registerForRingbackTone(Handler h, int what, Object obj) {
    940         mCi.registerForRingbackTone(h, what, obj);
    941     }
    942 
    943     // Inherited documentation suffices.
    944     @Override
    945     public void unregisterForRingbackTone(Handler h) {
    946         mCi.unregisterForRingbackTone(h);
    947     }
    948 
    949     // Inherited documentation suffices.
    950     @Override
    951     public void registerForOnHoldTone(Handler h, int what, Object obj) {
    952     }
    953 
    954     // Inherited documentation suffices.
    955     @Override
    956     public void unregisterForOnHoldTone(Handler h) {
    957     }
    958 
    959     // Inherited documentation suffices.
    960     @Override
    961     public void registerForResendIncallMute(Handler h, int what, Object obj) {
    962         mCi.registerForResendIncallMute(h, what, obj);
    963     }
    964 
    965     // Inherited documentation suffices.
    966     @Override
    967     public void unregisterForResendIncallMute(Handler h) {
    968         mCi.unregisterForResendIncallMute(h);
    969     }
    970 
    971     @Override
    972     public void setEchoSuppressionEnabled() {
    973         // no need for regular phone
    974     }
    975 
    976     /**
    977      * Subclasses of Phone probably want to replace this with a
    978      * version scoped to their packages
    979      */
    980     protected void notifyServiceStateChangedP(ServiceState ss) {
    981         AsyncResult ar = new AsyncResult(null, ss, null);
    982         mServiceStateRegistrants.notifyRegistrants(ar);
    983 
    984         mNotifier.notifyServiceState(this);
    985     }
    986 
    987     // Inherited documentation suffices.
    988     @Override
    989     public SimulatedRadioControl getSimulatedRadioControl() {
    990         return mSimulatedRadioControl;
    991     }
    992 
    993     /**
    994      * Verifies the current thread is the same as the thread originally
    995      * used in the initialization of this instance. Throws RuntimeException
    996      * if not.
    997      *
    998      * @exception RuntimeException if the current thread is not
    999      * the thread that originally obtained this PhoneBase instance.
   1000      */
   1001     private void checkCorrectThread(Handler h) {
   1002         if (h.getLooper() != mLooper) {
   1003             throw new RuntimeException(
   1004                     "com.android.internal.telephony.Phone must be used from within one thread");
   1005         }
   1006     }
   1007 
   1008     /**
   1009      * Set the properties by matching the carrier string in
   1010      * a string-array resource
   1011      */
   1012     private void setPropertiesByCarrier() {
   1013         String carrier = SystemProperties.get("ro.carrier");
   1014 
   1015         if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
   1016             return;
   1017         }
   1018 
   1019         CharSequence[] carrierLocales = mContext.
   1020                 getResources().getTextArray(R.array.carrier_properties);
   1021 
   1022         for (int i = 0; i < carrierLocales.length; i+=3) {
   1023             String c = carrierLocales[i].toString();
   1024             if (carrier.equals(c)) {
   1025                 final Locale l = Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-'));
   1026                 final String country = l.getCountry();
   1027                 MccTable.setSystemLocale(mContext, l.getLanguage(), country);
   1028 
   1029                 if (!country.isEmpty()) {
   1030                     try {
   1031                         Settings.Global.getInt(mContext.getContentResolver(),
   1032                                 Settings.Global.WIFI_COUNTRY_CODE);
   1033                     } catch (Settings.SettingNotFoundException e) {
   1034                         // note this is not persisting
   1035                         WifiManager wM = (WifiManager)
   1036                                 mContext.getSystemService(Context.WIFI_SERVICE);
   1037                         wM.setCountryCode(country, false);
   1038                     }
   1039                 }
   1040                 return;
   1041             }
   1042         }
   1043     }
   1044 
   1045     /**
   1046      * Get state
   1047      */
   1048     @Override
   1049     public abstract PhoneConstants.State getState();
   1050 
   1051     /**
   1052      * Retrieves the IccFileHandler of the Phone instance
   1053      */
   1054     public IccFileHandler getIccFileHandler(){
   1055         UiccCardApplication uiccApplication = mUiccApplication.get();
   1056         IccFileHandler fh;
   1057 
   1058         if (uiccApplication == null) {
   1059             Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null");
   1060             fh = null;
   1061         } else {
   1062             fh = uiccApplication.getIccFileHandler();
   1063         }
   1064 
   1065         Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh);
   1066         return fh;
   1067     }
   1068 
   1069     /*
   1070      * Retrieves the Handler of the Phone instance
   1071      */
   1072     public Handler getHandler() {
   1073         return this;
   1074     }
   1075 
   1076     @Override
   1077     public void updatePhoneObject(int voiceRadioTech) {
   1078         // Only the PhoneProxy can update the phone object.
   1079         PhoneFactory.getDefaultPhone().updatePhoneObject(voiceRadioTech);
   1080     }
   1081 
   1082     /**
   1083     * Retrieves the ServiceStateTracker of the phone instance.
   1084     */
   1085     public ServiceStateTracker getServiceStateTracker() {
   1086         return null;
   1087     }
   1088 
   1089     /**
   1090     * Get call tracker
   1091     */
   1092     public CallTracker getCallTracker() {
   1093         return null;
   1094     }
   1095 
   1096     public AppType getCurrentUiccAppType() {
   1097         UiccCardApplication currentApp = mUiccApplication.get();
   1098         if (currentApp != null) {
   1099             return currentApp.getType();
   1100         }
   1101         return AppType.APPTYPE_UNKNOWN;
   1102     }
   1103 
   1104     @Override
   1105     public IccCard getIccCard() {
   1106         return null;
   1107         //throw new Exception("getIccCard Shouldn't be called from PhoneBase");
   1108     }
   1109 
   1110     @Override
   1111     public String getIccSerialNumber() {
   1112         IccRecords r = mIccRecords.get();
   1113         return (r != null) ? r.getIccId() : null;
   1114     }
   1115 
   1116     @Override
   1117     public boolean getIccRecordsLoaded() {
   1118         IccRecords r = mIccRecords.get();
   1119         return (r != null) ? r.getRecordsLoaded() : false;
   1120     }
   1121 
   1122     /**
   1123      * @return all available cell information or null if none.
   1124      */
   1125     @Override
   1126     public List<CellInfo> getAllCellInfo() {
   1127         List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo();
   1128         return privatizeCellInfoList(cellInfoList);
   1129     }
   1130 
   1131     /**
   1132      * Clear CDMA base station lat/long values if location setting is disabled.
   1133      * @param cellInfoList the original cell info list from the RIL
   1134      * @return the original list with CDMA lat/long cleared if necessary
   1135      */
   1136     private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) {
   1137         int mode = Settings.Secure.getInt(getContext().getContentResolver(),
   1138                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
   1139         if (mode == Settings.Secure.LOCATION_MODE_OFF) {
   1140             ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size());
   1141             // clear lat/lon values for location privacy
   1142             for (CellInfo c : cellInfoList) {
   1143                 if (c instanceof CellInfoCdma) {
   1144                     CellInfoCdma cellInfoCdma = (CellInfoCdma) c;
   1145                     CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity();
   1146                     CellIdentityCdma maskedCellIdentity = new CellIdentityCdma(
   1147                             cellIdentity.getNetworkId(),
   1148                             cellIdentity.getSystemId(),
   1149                             cellIdentity.getBasestationId(),
   1150                             Integer.MAX_VALUE, Integer.MAX_VALUE);
   1151                     CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma);
   1152                     privateCellInfoCdma.setCellIdentity(maskedCellIdentity);
   1153                     privateCellInfoList.add(privateCellInfoCdma);
   1154                 } else {
   1155                     privateCellInfoList.add(c);
   1156                 }
   1157             }
   1158             cellInfoList = privateCellInfoList;
   1159         }
   1160         return cellInfoList;
   1161     }
   1162 
   1163     /**
   1164      * {@inheritDoc}
   1165      */
   1166     @Override
   1167     public void setCellInfoListRate(int rateInMillis) {
   1168         mCi.setCellInfoListRate(rateInMillis, null);
   1169     }
   1170 
   1171     @Override
   1172     public boolean getMessageWaitingIndicator() {
   1173         IccRecords r = mIccRecords.get();
   1174         return (r != null) ? r.getVoiceMessageWaiting() : false;
   1175     }
   1176 
   1177     @Override
   1178     public boolean getCallForwardingIndicator() {
   1179         IccRecords r = mIccRecords.get();
   1180         return (r != null) ? r.getVoiceCallForwardingFlag() : false;
   1181     }
   1182 
   1183     /**
   1184      *  Query the status of the CDMA roaming preference
   1185      */
   1186     @Override
   1187     public void queryCdmaRoamingPreference(Message response) {
   1188         mCi.queryCdmaRoamingPreference(response);
   1189     }
   1190 
   1191     /**
   1192      * Get the signal strength
   1193      */
   1194     @Override
   1195     public SignalStrength getSignalStrength() {
   1196         ServiceStateTracker sst = getServiceStateTracker();
   1197         if (sst == null) {
   1198             return new SignalStrength();
   1199         } else {
   1200             return sst.getSignalStrength();
   1201         }
   1202     }
   1203 
   1204     /**
   1205      *  Set the status of the CDMA roaming preference
   1206      */
   1207     @Override
   1208     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
   1209         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
   1210     }
   1211 
   1212     /**
   1213      *  Set the status of the CDMA subscription mode
   1214      */
   1215     @Override
   1216     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
   1217         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
   1218     }
   1219 
   1220     /**
   1221      *  Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
   1222      */
   1223     @Override
   1224     public void setPreferredNetworkType(int networkType, Message response) {
   1225         mCi.setPreferredNetworkType(networkType, response);
   1226     }
   1227 
   1228     @Override
   1229     public void getPreferredNetworkType(Message response) {
   1230         mCi.getPreferredNetworkType(response);
   1231     }
   1232 
   1233     @Override
   1234     public void getSmscAddress(Message result) {
   1235         mCi.getSmscAddress(result);
   1236     }
   1237 
   1238     @Override
   1239     public void setSmscAddress(String address, Message result) {
   1240         mCi.setSmscAddress(address, result);
   1241     }
   1242 
   1243     @Override
   1244     public void setTTYMode(int ttyMode, Message onComplete) {
   1245         mCi.setTTYMode(ttyMode, onComplete);
   1246     }
   1247 
   1248     @Override
   1249     public void queryTTYMode(Message onComplete) {
   1250         mCi.queryTTYMode(onComplete);
   1251     }
   1252 
   1253     @Override
   1254     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
   1255         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1256         logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy");
   1257     }
   1258 
   1259     @Override
   1260     public void getEnhancedVoicePrivacy(Message onComplete) {
   1261         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1262         logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy");
   1263     }
   1264 
   1265     @Override
   1266     public void setBandMode(int bandMode, Message response) {
   1267         mCi.setBandMode(bandMode, response);
   1268     }
   1269 
   1270     @Override
   1271     public void queryAvailableBandMode(Message response) {
   1272         mCi.queryAvailableBandMode(response);
   1273     }
   1274 
   1275     @Override
   1276     public void invokeOemRilRequestRaw(byte[] data, Message response) {
   1277         mCi.invokeOemRilRequestRaw(data, response);
   1278     }
   1279 
   1280     @Override
   1281     public void invokeOemRilRequestStrings(String[] strings, Message response) {
   1282         mCi.invokeOemRilRequestStrings(strings, response);
   1283     }
   1284 
   1285     @Override
   1286     public void nvReadItem(int itemID, Message response) {
   1287         mCi.nvReadItem(itemID, response);
   1288     }
   1289 
   1290     @Override
   1291     public void nvWriteItem(int itemID, String itemValue, Message response) {
   1292         mCi.nvWriteItem(itemID, itemValue, response);
   1293     }
   1294 
   1295     @Override
   1296     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
   1297         mCi.nvWriteCdmaPrl(preferredRoamingList, response);
   1298     }
   1299 
   1300     @Override
   1301     public void nvResetConfig(int resetType, Message response) {
   1302         mCi.nvResetConfig(resetType, response);
   1303     }
   1304 
   1305     @Override
   1306     public void notifyDataActivity() {
   1307         mNotifier.notifyDataActivity(this);
   1308     }
   1309 
   1310     public void notifyMessageWaitingIndicator() {
   1311         // Do not notify voice mail waiting if device doesn't support voice
   1312         if (!mIsVoiceCapable)
   1313             return;
   1314 
   1315         // This function is added to send the notification to DefaultPhoneNotifier.
   1316         mNotifier.notifyMessageWaitingChanged(this);
   1317     }
   1318 
   1319     public void notifyDataConnection(String reason, String apnType,
   1320             PhoneConstants.DataState state) {
   1321         mNotifier.notifyDataConnection(this, reason, apnType, state);
   1322     }
   1323 
   1324     public void notifyDataConnection(String reason, String apnType) {
   1325         mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
   1326     }
   1327 
   1328     public void notifyDataConnection(String reason) {
   1329         String types[] = getActiveApnTypes();
   1330         for (String apnType : types) {
   1331             mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
   1332         }
   1333     }
   1334 
   1335     public void notifyOtaspChanged(int otaspMode) {
   1336         mNotifier.notifyOtaspChanged(this, otaspMode);
   1337     }
   1338 
   1339     public void notifySignalStrength() {
   1340         mNotifier.notifySignalStrength(this);
   1341     }
   1342 
   1343     public void notifyCellInfo(List<CellInfo> cellInfo) {
   1344         mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo));
   1345     }
   1346 
   1347     public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) {
   1348         mNotifier.notifyDataConnectionRealTimeInfo(this, dcRtInfo);
   1349     }
   1350 
   1351     public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) {
   1352         mNotifier.notifyVoLteServiceStateChanged(this, lteState);
   1353     }
   1354 
   1355     /**
   1356      * @return true if a mobile originating emergency call is active
   1357      */
   1358     public boolean isInEmergencyCall() {
   1359         return false;
   1360     }
   1361 
   1362     /**
   1363      * @return true if we are in the emergency call back mode. This is a period where
   1364      * the phone should be using as little power as possible and be ready to receive an
   1365      * incoming call from the emergency operator.
   1366      */
   1367     public boolean isInEcm() {
   1368         return false;
   1369     }
   1370 
   1371     @Override
   1372     public abstract int getPhoneType();
   1373 
   1374     /** @hide */
   1375     @Override
   1376     public int getVoiceMessageCount(){
   1377         return 0;
   1378     }
   1379 
   1380     /**
   1381      * Returns the CDMA ERI icon index to display
   1382      */
   1383     @Override
   1384     public int getCdmaEriIconIndex() {
   1385         logUnexpectedCdmaMethodCall("getCdmaEriIconIndex");
   1386         return -1;
   1387     }
   1388 
   1389     /**
   1390      * Returns the CDMA ERI icon mode,
   1391      * 0 - ON
   1392      * 1 - FLASHING
   1393      */
   1394     @Override
   1395     public int getCdmaEriIconMode() {
   1396         logUnexpectedCdmaMethodCall("getCdmaEriIconMode");
   1397         return -1;
   1398     }
   1399 
   1400     /**
   1401      * Returns the CDMA ERI text,
   1402      */
   1403     @Override
   1404     public String getCdmaEriText() {
   1405         logUnexpectedCdmaMethodCall("getCdmaEriText");
   1406         return "GSM nw, no ERI";
   1407     }
   1408 
   1409     @Override
   1410     public String getCdmaMin() {
   1411         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1412         logUnexpectedCdmaMethodCall("getCdmaMin");
   1413         return null;
   1414     }
   1415 
   1416     @Override
   1417     public boolean isMinInfoReady() {
   1418         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1419         logUnexpectedCdmaMethodCall("isMinInfoReady");
   1420         return false;
   1421     }
   1422 
   1423     @Override
   1424     public String getCdmaPrlVersion(){
   1425         //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1426         logUnexpectedCdmaMethodCall("getCdmaPrlVersion");
   1427         return null;
   1428     }
   1429 
   1430     @Override
   1431     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
   1432         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1433         logUnexpectedCdmaMethodCall("sendBurstDtmf");
   1434     }
   1435 
   1436     @Override
   1437     public void exitEmergencyCallbackMode() {
   1438         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1439         logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode");
   1440     }
   1441 
   1442     @Override
   1443     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
   1444         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1445         logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange");
   1446     }
   1447 
   1448     @Override
   1449     public void unregisterForCdmaOtaStatusChange(Handler h) {
   1450         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1451         logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange");
   1452     }
   1453 
   1454     @Override
   1455     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
   1456         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1457         logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady");
   1458     }
   1459 
   1460     @Override
   1461     public void unregisterForSubscriptionInfoReady(Handler h) {
   1462         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1463         logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
   1464     }
   1465 
   1466     /**
   1467      * Returns true if OTA Service Provisioning needs to be performed.
   1468      * If not overridden return false.
   1469      */
   1470     @Override
   1471     public boolean needsOtaServiceProvisioning() {
   1472         return false;
   1473     }
   1474 
   1475     /**
   1476      * Return true if number is an OTASP number.
   1477      * If not overridden return false.
   1478      */
   1479     @Override
   1480     public  boolean isOtaSpNumber(String dialStr) {
   1481         return false;
   1482     }
   1483 
   1484     @Override
   1485     public void registerForCallWaiting(Handler h, int what, Object obj){
   1486         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1487         logUnexpectedCdmaMethodCall("registerForCallWaiting");
   1488     }
   1489 
   1490     @Override
   1491     public void unregisterForCallWaiting(Handler h){
   1492         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1493         logUnexpectedCdmaMethodCall("unregisterForCallWaiting");
   1494     }
   1495 
   1496     @Override
   1497     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
   1498         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1499         logUnexpectedCdmaMethodCall("registerForEcmTimerReset");
   1500     }
   1501 
   1502     @Override
   1503     public void unregisterForEcmTimerReset(Handler h) {
   1504         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1505         logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset");
   1506     }
   1507 
   1508     @Override
   1509     public void registerForSignalInfo(Handler h, int what, Object obj) {
   1510         mCi.registerForSignalInfo(h, what, obj);
   1511     }
   1512 
   1513     @Override
   1514     public void unregisterForSignalInfo(Handler h) {
   1515         mCi.unregisterForSignalInfo(h);
   1516     }
   1517 
   1518     @Override
   1519     public void registerForDisplayInfo(Handler h, int what, Object obj) {
   1520         mCi.registerForDisplayInfo(h, what, obj);
   1521     }
   1522 
   1523      @Override
   1524     public void unregisterForDisplayInfo(Handler h) {
   1525          mCi.unregisterForDisplayInfo(h);
   1526      }
   1527 
   1528     @Override
   1529     public void registerForNumberInfo(Handler h, int what, Object obj) {
   1530         mCi.registerForNumberInfo(h, what, obj);
   1531     }
   1532 
   1533     @Override
   1534     public void unregisterForNumberInfo(Handler h) {
   1535         mCi.unregisterForNumberInfo(h);
   1536     }
   1537 
   1538     @Override
   1539     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
   1540         mCi.registerForRedirectedNumberInfo(h, what, obj);
   1541     }
   1542 
   1543     @Override
   1544     public void unregisterForRedirectedNumberInfo(Handler h) {
   1545         mCi.unregisterForRedirectedNumberInfo(h);
   1546     }
   1547 
   1548     @Override
   1549     public void registerForLineControlInfo(Handler h, int what, Object obj) {
   1550         mCi.registerForLineControlInfo( h, what, obj);
   1551     }
   1552 
   1553     @Override
   1554     public void unregisterForLineControlInfo(Handler h) {
   1555         mCi.unregisterForLineControlInfo(h);
   1556     }
   1557 
   1558     @Override
   1559     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
   1560         mCi.registerFoT53ClirlInfo(h, what, obj);
   1561     }
   1562 
   1563     @Override
   1564     public void unregisterForT53ClirInfo(Handler h) {
   1565         mCi.unregisterForT53ClirInfo(h);
   1566     }
   1567 
   1568     @Override
   1569     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
   1570         mCi.registerForT53AudioControlInfo( h, what, obj);
   1571     }
   1572 
   1573     @Override
   1574     public void unregisterForT53AudioControlInfo(Handler h) {
   1575         mCi.unregisterForT53AudioControlInfo(h);
   1576     }
   1577 
   1578      @Override
   1579     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
   1580          // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1581          logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse");
   1582      }
   1583 
   1584      @Override
   1585     public void unsetOnEcbModeExitResponse(Handler h){
   1586         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1587          logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
   1588      }
   1589 
   1590     @Override
   1591     public String[] getActiveApnTypes() {
   1592         return mDcTracker.getActiveApnTypes();
   1593     }
   1594 
   1595     @Override
   1596     public String getActiveApnHost(String apnType) {
   1597         return mDcTracker.getActiveApnString(apnType);
   1598     }
   1599 
   1600     @Override
   1601     public LinkProperties getLinkProperties(String apnType) {
   1602         return mDcTracker.getLinkProperties(apnType);
   1603     }
   1604 
   1605     @Override
   1606     public NetworkCapabilities getNetworkCapabilities(String apnType) {
   1607         return mDcTracker.getNetworkCapabilities(apnType);
   1608     }
   1609 
   1610     @Override
   1611     public boolean isDataConnectivityPossible() {
   1612         return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT);
   1613     }
   1614 
   1615     @Override
   1616     public boolean isDataConnectivityPossible(String apnType) {
   1617         return ((mDcTracker != null) &&
   1618                 (mDcTracker.isDataPossible(apnType)));
   1619     }
   1620 
   1621     /**
   1622      * Notify registrants of a new ringing Connection.
   1623      * Subclasses of Phone probably want to replace this with a
   1624      * version scoped to their packages
   1625      */
   1626     public void notifyNewRingingConnectionP(Connection cn) {
   1627         if (!mIsVoiceCapable)
   1628             return;
   1629         AsyncResult ar = new AsyncResult(null, cn, null);
   1630         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
   1631     }
   1632 
   1633     /**
   1634      * Notify registrants of a RING event.
   1635      */
   1636     private void notifyIncomingRing() {
   1637         if (!mIsVoiceCapable)
   1638             return;
   1639         AsyncResult ar = new AsyncResult(null, this, null);
   1640         mIncomingRingRegistrants.notifyRegistrants(ar);
   1641     }
   1642 
   1643     /**
   1644      * Send the incoming call Ring notification if conditions are right.
   1645      */
   1646     private void sendIncomingCallRingNotification(int token) {
   1647         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
   1648                 (token == mCallRingContinueToken)) {
   1649             Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
   1650             notifyIncomingRing();
   1651             sendMessageDelayed(
   1652                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
   1653         } else {
   1654             Rlog.d(LOG_TAG, "Ignoring ring notification request,"
   1655                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
   1656                     + " token=" + token
   1657                     + " mCallRingContinueToken=" + mCallRingContinueToken
   1658                     + " mIsVoiceCapable=" + mIsVoiceCapable);
   1659         }
   1660     }
   1661 
   1662     @Override
   1663     public boolean isCspPlmnEnabled() {
   1664         // This function should be overridden by the class GSMPhone.
   1665         // Not implemented in CDMAPhone.
   1666         logUnexpectedGsmMethodCall("isCspPlmnEnabled");
   1667         return false;
   1668     }
   1669 
   1670     @Override
   1671     public IsimRecords getIsimRecords() {
   1672         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
   1673         return null;
   1674     }
   1675 
   1676     @Override
   1677     public String getMsisdn() {
   1678         logUnexpectedGsmMethodCall("getMsisdn");
   1679         return null;
   1680     }
   1681 
   1682     /**
   1683      * Common error logger method for unexpected calls to CDMA-only methods.
   1684      */
   1685     private static void logUnexpectedCdmaMethodCall(String name)
   1686     {
   1687         Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
   1688                 "called, CDMAPhone inactive.");
   1689     }
   1690 
   1691     @Override
   1692     public PhoneConstants.DataState getDataConnectionState() {
   1693         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
   1694     }
   1695 
   1696     /**
   1697      * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
   1698      */
   1699     private static void logUnexpectedGsmMethodCall(String name) {
   1700         Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
   1701                 "called, GSMPhone inactive.");
   1702     }
   1703 
   1704     // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
   1705     public void notifyCallForwardingIndicator() {
   1706         // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
   1707         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
   1708     }
   1709 
   1710     public void notifyDataConnectionFailed(String reason, String apnType) {
   1711         mNotifier.notifyDataConnectionFailed(this, reason, apnType);
   1712     }
   1713 
   1714     public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
   1715             String failCause) {
   1716         mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause);
   1717     }
   1718 
   1719     /**
   1720      * {@inheritDoc}
   1721      */
   1722     @Override
   1723     public int getLteOnCdmaMode() {
   1724         return mCi.getLteOnCdmaMode();
   1725     }
   1726 
   1727     /**
   1728      * Sets the SIM voice message waiting indicator records.
   1729      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
   1730      * @param countWaiting The number of messages waiting, if known. Use
   1731      *                     -1 to indicate that an unknown number of
   1732      *                      messages are waiting
   1733      */
   1734     @Override
   1735     public void setVoiceMessageWaiting(int line, int countWaiting) {
   1736         IccRecords r = mIccRecords.get();
   1737         if (r != null) {
   1738             r.setVoiceMessageWaiting(line, countWaiting);
   1739         }
   1740     }
   1741 
   1742     /**
   1743      * Gets the USIM service table from the UICC, if present and available.
   1744      * @return an interface to the UsimServiceTable record, or null if not available
   1745      */
   1746     @Override
   1747     public UsimServiceTable getUsimServiceTable() {
   1748         IccRecords r = mIccRecords.get();
   1749         return (r != null) ? r.getUsimServiceTable() : null;
   1750     }
   1751 
   1752     /**
   1753      * Gets the Uicc card corresponding to this phone.
   1754      * @return the UiccCard object corresponding to the phone ID.
   1755      */
   1756     @Override
   1757     public UiccCard getUiccCard() {
   1758         return mUiccController.getUiccCard(mPhoneId);
   1759     }
   1760 
   1761     /**
   1762      * Get P-CSCF address from PCO after data connection is established or modified.
   1763      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
   1764      */
   1765     @Override
   1766     public String[] getPcscfAddress(String apnType) {
   1767         return mDcTracker.getPcscfAddress(apnType);
   1768     }
   1769 
   1770     /**
   1771      * Set IMS registration state
   1772      */
   1773     @Override
   1774     public void setImsRegistrationState(boolean registered) {
   1775         mDcTracker.setImsRegistrationState(registered);
   1776     }
   1777 
   1778     /**
   1779      * Return an instance of a IMS phone
   1780      */
   1781     @Override
   1782     public Phone getImsPhone() {
   1783         return mImsPhone;
   1784     }
   1785 
   1786     @Override
   1787     public ImsPhone relinquishOwnershipOfImsPhone() {
   1788         synchronized (mImsLock) {
   1789             if (mImsPhone == null)
   1790                 return null;
   1791 
   1792             ImsPhone imsPhone = mImsPhone;
   1793             mImsPhone = null;
   1794 
   1795             CallManager.getInstance().unregisterPhone(imsPhone);
   1796             imsPhone.unregisterForSilentRedial(this);
   1797 
   1798             return imsPhone;
   1799         }
   1800     }
   1801 
   1802     @Override
   1803     public void acquireOwnershipOfImsPhone(ImsPhone imsPhone) {
   1804         synchronized (mImsLock) {
   1805             if (imsPhone == null)
   1806                 return;
   1807 
   1808             if (mImsPhone != null) {
   1809                 Rlog.e(LOG_TAG, "acquireOwnershipOfImsPhone: non-null mImsPhone." +
   1810                         " Shouldn't happen - but disposing");
   1811                 mImsPhone.dispose();
   1812                 // Potential GC issue if someone keeps a reference to ImsPhone.
   1813                 // However: this change will make sure that such a reference does
   1814                 // not access functions through NULL pointer.
   1815                 //mImsPhone.removeReferences();
   1816             }
   1817 
   1818             mImsPhone = imsPhone;
   1819 
   1820             mImsServiceReady = true;
   1821             mImsPhone.updateParentPhone(this);
   1822             CallManager.getInstance().registerPhone(mImsPhone);
   1823             mImsPhone.registerForSilentRedial(
   1824                     this, EVENT_INITIATE_SILENT_REDIAL, null);
   1825         }
   1826     }
   1827 
   1828     protected void updateImsPhone() {
   1829         synchronized (mImsLock) {
   1830             Rlog.d(LOG_TAG, "updateImsPhone"
   1831                     + " mImsServiceReady=" + mImsServiceReady);
   1832 
   1833             if (mImsServiceReady && (mImsPhone == null)) {
   1834                 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
   1835                 CallManager.getInstance().registerPhone(mImsPhone);
   1836                 mImsPhone.registerForSilentRedial(
   1837                         this, EVENT_INITIATE_SILENT_REDIAL, null);
   1838             } else if (!mImsServiceReady && (mImsPhone != null)) {
   1839                 CallManager.getInstance().unregisterPhone(mImsPhone);
   1840                 mImsPhone.unregisterForSilentRedial(this);
   1841 
   1842                 mImsPhone.dispose();
   1843                 // Potential GC issue if someone keeps a reference to ImsPhone.
   1844                 // However: this change will make sure that such a reference does
   1845                 // not access functions through NULL pointer.
   1846                 //mImsPhone.removeReferences();
   1847                 mImsPhone = null;
   1848             }
   1849         }
   1850     }
   1851 
   1852     /**
   1853      * Dials a number.
   1854      *
   1855      * @param dialString The number to dial.
   1856      * @param uusInfo The UUSInfo.
   1857      * @param videoState The video state for the call.
   1858      * @return The Connection.
   1859      * @throws CallStateException
   1860      */
   1861     protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState)
   1862             throws CallStateException {
   1863         // dialInternal shall be overriden by GSMPhone and CDMAPhone
   1864         return null;
   1865     }
   1866 
   1867     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1868         pw.println("PhoneBase:");
   1869         pw.println(" mCi=" + mCi);
   1870         pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
   1871         pw.println(" mDcTracker=" + mDcTracker);
   1872         pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
   1873         pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
   1874         pw.println(" mCallRingDelay=" + mCallRingDelay);
   1875         pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
   1876         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
   1877         pw.println(" mIccRecords=" + mIccRecords.get());
   1878         pw.println(" mUiccApplication=" + mUiccApplication.get());
   1879         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
   1880         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
   1881         pw.flush();
   1882         pw.println(" mLooper=" + mLooper);
   1883         pw.println(" mContext=" + mContext);
   1884         pw.println(" mNotifier=" + mNotifier);
   1885         pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
   1886         pw.println(" mUnitTestMode=" + mUnitTestMode);
   1887         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
   1888         pw.println(" getUnitTestMode()=" + getUnitTestMode());
   1889         pw.println(" getState()=" + getState());
   1890         pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
   1891         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
   1892         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
   1893         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
   1894         pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
   1895         pw.flush();
   1896         pw.println(" isInEcm()=" + isInEcm());
   1897         pw.println(" getPhoneName()=" + getPhoneName());
   1898         pw.println(" getPhoneType()=" + getPhoneType());
   1899         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
   1900         pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
   1901         pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
   1902         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
   1903     }
   1904 
   1905     /**
   1906      * Returns the subscription id.
   1907      */
   1908     public long getSubId() {
   1909         return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId);
   1910     }
   1911 
   1912     /**
   1913      * Returns the phone id.
   1914      */
   1915     public int getPhoneId() {
   1916         return mPhoneId;
   1917     }
   1918 
   1919     //Gets Subscription information in the Phone Object
   1920     public Subscription getSubscriptionInfo() {
   1921         return mSubscriptionData;
   1922     }
   1923 
   1924     /**
   1925      * Return the service state of mImsPhone if it is STATE_IN_SERVICE
   1926      * otherwise return the current voice service state
   1927      */
   1928     @Override
   1929     public int getVoicePhoneServiceState() {
   1930         ImsPhone imsPhone = mImsPhone;
   1931         if (imsPhone != null
   1932                 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
   1933             return ServiceState.STATE_IN_SERVICE;
   1934         }
   1935         return getServiceState().getState();
   1936     }
   1937 
   1938     @Override
   1939     public boolean setOperatorBrandOverride(String brand) {
   1940         return false;
   1941     }
   1942 
   1943     @Override
   1944     public boolean isRadioAvailable() {
   1945         return mCi.getRadioState().isAvailable();
   1946     }
   1947 
   1948     @Override
   1949     public void shutdownRadio() {
   1950         getServiceStateTracker().requestShutdown();
   1951     }
   1952 }
   1953