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.Context;
     20 import android.content.SharedPreferences;
     21 import android.net.LinkCapabilities;
     22 import android.net.LinkProperties;
     23 import android.net.wifi.WifiManager;
     24 import android.os.AsyncResult;
     25 import android.os.Build;
     26 import android.os.Handler;
     27 import android.os.Looper;
     28 import android.os.Message;
     29 import android.os.RegistrantList;
     30 import android.os.SystemProperties;
     31 import android.preference.PreferenceManager;
     32 import android.provider.Settings;
     33 import android.telephony.CellInfo;
     34 import android.telephony.ServiceState;
     35 import android.telephony.SignalStrength;
     36 import android.text.TextUtils;
     37 import android.telephony.Rlog;
     38 
     39 import com.android.internal.R;
     40 import com.android.internal.telephony.dataconnection.DcTrackerBase;
     41 import com.android.internal.telephony.test.SimulatedRadioControl;
     42 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
     43 import com.android.internal.telephony.uicc.IccFileHandler;
     44 import com.android.internal.telephony.uicc.IccRecords;
     45 import com.android.internal.telephony.uicc.IsimRecords;
     46 import com.android.internal.telephony.uicc.UiccCardApplication;
     47 import com.android.internal.telephony.uicc.UiccController;
     48 import com.android.internal.telephony.uicc.UsimServiceTable;
     49 import java.io.FileDescriptor;
     50 import java.io.PrintWriter;
     51 import java.util.List;
     52 import java.util.concurrent.atomic.AtomicReference;
     53 
     54 
     55 /**
     56  * (<em>Not for SDK use</em>)
     57  * A base implementation for the com.android.internal.telephony.Phone interface.
     58  *
     59  * Note that implementations of Phone.java are expected to be used
     60  * from a single application thread. This should be the same thread that
     61  * originally called PhoneFactory to obtain the interface.
     62  *
     63  *  {@hide}
     64  *
     65  */
     66 
     67 public abstract class PhoneBase extends Handler implements Phone {
     68     private static final String LOG_TAG = "PhoneBase";
     69 
     70     // Key used to read and write the saved network selection numeric value
     71     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
     72     // Key used to read and write the saved network selection operator name
     73     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
     74 
     75 
     76     // Key used to read/write "disable data connection on boot" pref (used for testing)
     77     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
     78 
     79     /* Event Constants */
     80     protected static final int EVENT_RADIO_AVAILABLE             = 1;
     81     /** Supplementary Service Notification received. */
     82     protected static final int EVENT_SSN                         = 2;
     83     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
     84     protected static final int EVENT_MMI_DONE                    = 4;
     85     protected static final int EVENT_RADIO_ON                    = 5;
     86     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
     87     protected static final int EVENT_USSD                        = 7;
     88     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
     89     protected static final int EVENT_GET_IMEI_DONE               = 9;
     90     protected static final int EVENT_GET_IMEISV_DONE             = 10;
     91     protected static final int EVENT_GET_SIM_STATUS_DONE         = 11;
     92     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
     93     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
     94     protected static final int EVENT_CALL_RING                   = 14;
     95     protected static final int EVENT_CALL_RING_CONTINUE          = 15;
     96 
     97     // Used to intercept the carrier selection calls so that
     98     // we can save the values.
     99     protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE    = 16;
    100     protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17;
    101     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
    102     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
    103     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
    104     // Events for CDMA support
    105     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
    106     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
    107     protected static final int EVENT_NV_READY                       = 23;
    108     protected static final int EVENT_SET_ENHANCED_VP                = 24;
    109     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
    110     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
    111     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
    112     // other
    113     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
    114     protected static final int EVENT_NEW_ICC_SMS                    = 29;
    115     protected static final int EVENT_ICC_RECORD_EVENTS              = 30;
    116     protected static final int EVENT_ICC_CHANGED                    = 31;
    117 
    118     // Key used to read/write current CLIR setting
    119     public static final String CLIR_KEY = "clir_key";
    120 
    121     // Key used to read/write "disable DNS server check" pref (used for testing)
    122     public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
    123 
    124     /* Instance Variables */
    125     public CommandsInterface mCi;
    126     boolean mDnsCheckDisabled;
    127     public DcTrackerBase mDcTracker;
    128     boolean mDoesRilSendMultipleCallRing;
    129     int mCallRingContinueToken;
    130     int mCallRingDelay;
    131     public boolean mIsTheCurrentActivePhone = true;
    132     boolean mIsVoiceCapable = true;
    133     protected UiccController mUiccController = null;
    134     public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
    135     public SmsStorageMonitor mSmsStorageMonitor;
    136     public SmsUsageMonitor mSmsUsageMonitor;
    137     protected AtomicReference<UiccCardApplication> mUiccApplication =
    138             new AtomicReference<UiccCardApplication>();
    139     public SMSDispatcher mSMS;
    140 
    141     private TelephonyTester mTelephonyTester;
    142     private final String mName;
    143     private final String mActionDetached;
    144     private final String mActionAttached;
    145 
    146     @Override
    147     public String getPhoneName() {
    148         return mName;
    149     }
    150 
    151     /**
    152      * Return the ActionDetached string. When this action is received by components
    153      * they are to simulate detaching from the network.
    154      *
    155      * @return com.android.internal.telephony.{mName}.action_detached
    156      *          {mName} is GSM, CDMA ...
    157      */
    158     public String getActionDetached() {
    159         return mActionDetached;
    160     }
    161 
    162     /**
    163      * Return the ActionAttached string. When this action is received by components
    164      * they are to simulate attaching to the network.
    165      *
    166      * @return com.android.internal.telephony.{mName}.action_detached
    167      *          {mName} is GSM, CDMA ...
    168      */
    169     public String getActionAttached() {
    170         return mActionAttached;
    171     }
    172 
    173     /**
    174      * Set a system property, unless we're in unit test mode
    175      */
    176     public void setSystemProperty(String property, String value) {
    177         if(getUnitTestMode()) {
    178             return;
    179         }
    180         SystemProperties.set(property, value);
    181     }
    182 
    183 
    184     protected final RegistrantList mPreciseCallStateRegistrants
    185             = new RegistrantList();
    186 
    187     protected final RegistrantList mNewRingingConnectionRegistrants
    188             = new RegistrantList();
    189 
    190     protected final RegistrantList mIncomingRingRegistrants
    191             = new RegistrantList();
    192 
    193     protected final RegistrantList mDisconnectRegistrants
    194             = new RegistrantList();
    195 
    196     protected final RegistrantList mServiceStateRegistrants
    197             = new RegistrantList();
    198 
    199     protected final RegistrantList mMmiCompleteRegistrants
    200             = new RegistrantList();
    201 
    202     protected final RegistrantList mMmiRegistrants
    203             = new RegistrantList();
    204 
    205     protected final RegistrantList mUnknownConnectionRegistrants
    206             = new RegistrantList();
    207 
    208     protected final RegistrantList mSuppServiceFailedRegistrants
    209             = new RegistrantList();
    210 
    211     protected Looper mLooper; /* to insure registrants are in correct thread*/
    212 
    213     protected final Context mContext;
    214 
    215     /**
    216      * PhoneNotifier is an abstraction for all system-wide
    217      * state change notification. DefaultPhoneNotifier is
    218      * used here unless running we're inside a unit test.
    219      */
    220     protected PhoneNotifier mNotifier;
    221 
    222     protected SimulatedRadioControl mSimulatedRadioControl;
    223 
    224     boolean mUnitTestMode;
    225 
    226     /**
    227      * Constructs a PhoneBase in normal (non-unit test) mode.
    228      *
    229      * @param notifier An instance of DefaultPhoneNotifier,
    230      * @param context Context object from hosting application
    231      * unless unit testing.
    232      * @param ci the CommandsInterface
    233      */
    234     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci) {
    235         this(name, notifier, context, ci, false);
    236     }
    237 
    238     /**
    239      * Constructs a PhoneBase in normal (non-unit test) mode.
    240      *
    241      * @param notifier An instance of DefaultPhoneNotifier,
    242      * @param context Context object from hosting application
    243      * unless unit testing.
    244      * @param ci is CommandsInterface
    245      * @param unitTestMode when true, prevents notifications
    246      * of state change events
    247      */
    248     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
    249             boolean unitTestMode) {
    250         mName = name;
    251         mNotifier = notifier;
    252         mContext = context;
    253         mLooper = Looper.myLooper();
    254         mCi = ci;
    255         mActionDetached = this.getClass().getPackage().getName() + ".action_detached";
    256         mActionAttached = this.getClass().getPackage().getName() + ".action_attached";
    257 
    258         if (Build.IS_DEBUGGABLE) {
    259             mTelephonyTester = new TelephonyTester(this);
    260         }
    261 
    262         setPropertiesByCarrier();
    263 
    264         setUnitTestMode(unitTestMode);
    265 
    266         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
    267         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
    268         mCi.setOnCallRing(this, EVENT_CALL_RING, null);
    269 
    270         /* "Voice capable" means that this device supports circuit-switched
    271         * (i.e. voice) phone calls over the telephony network, and is allowed
    272         * to display the in-call UI while a cellular voice call is active.
    273         * This will be false on "data only" devices which can't make voice
    274         * calls and don't support any in-call UI.
    275         */
    276         mIsVoiceCapable = mContext.getResources().getBoolean(
    277                 com.android.internal.R.bool.config_voice_capable);
    278 
    279         /**
    280          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
    281          *  to be generated locally. Ideally all ring tones should be loops
    282          * and this wouldn't be necessary. But to minimize changes to upper
    283          * layers it is requested that it be generated by lower layers.
    284          *
    285          * By default old phones won't have the property set but do generate
    286          * the RIL_UNSOL_CALL_RING so the default if there is no property is
    287          * true.
    288          */
    289         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
    290                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
    291         Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
    292 
    293         mCallRingDelay = SystemProperties.getInt(
    294                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
    295         Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
    296 
    297         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
    298         mSmsStorageMonitor = new SmsStorageMonitor(this);
    299         mSmsUsageMonitor = new SmsUsageMonitor(context);
    300         mUiccController = UiccController.getInstance();
    301         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
    302     }
    303 
    304     @Override
    305     public void dispose() {
    306         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
    307             mCi.unSetOnCallRing(this);
    308             // Must cleanup all connectionS and needs to use sendMessage!
    309             mDcTracker.cleanUpAllConnections(null);
    310             mIsTheCurrentActivePhone = false;
    311             // Dispose the SMS usage and storage monitors
    312             mSmsStorageMonitor.dispose();
    313             mSmsUsageMonitor.dispose();
    314             mUiccController.unregisterForIccChanged(this);
    315 
    316             if (mTelephonyTester != null) {
    317                 mTelephonyTester.dispose();
    318             }
    319         }
    320     }
    321 
    322     @Override
    323     public void removeReferences() {
    324         mSmsStorageMonitor = null;
    325         mSmsUsageMonitor = null;
    326         mSMS = null;
    327         mIccRecords.set(null);
    328         mUiccApplication.set(null);
    329         mDcTracker = null;
    330         mUiccController = null;
    331     }
    332 
    333     /**
    334      * When overridden the derived class needs to call
    335      * super.handleMessage(msg) so this method has a
    336      * a chance to process the message.
    337      *
    338      * @param msg
    339      */
    340     @Override
    341     public void handleMessage(Message msg) {
    342         AsyncResult ar;
    343 
    344         switch(msg.what) {
    345             case EVENT_CALL_RING:
    346                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
    347                 ar = (AsyncResult)msg.obj;
    348                 if (ar.exception == null) {
    349                     PhoneConstants.State state = getState();
    350                     if ((!mDoesRilSendMultipleCallRing)
    351                             && ((state == PhoneConstants.State.RINGING) ||
    352                                     (state == PhoneConstants.State.IDLE))) {
    353                         mCallRingContinueToken += 1;
    354                         sendIncomingCallRingNotification(mCallRingContinueToken);
    355                     } else {
    356                         notifyIncomingRing();
    357                     }
    358                 }
    359                 break;
    360 
    361             case EVENT_CALL_RING_CONTINUE:
    362                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
    363                 if (getState() == PhoneConstants.State.RINGING) {
    364                     sendIncomingCallRingNotification(msg.arg1);
    365                 }
    366                 break;
    367 
    368             case EVENT_ICC_CHANGED:
    369                 onUpdateIccAvailability();
    370                 break;
    371 
    372             default:
    373                 throw new RuntimeException("unexpected event not handled");
    374         }
    375     }
    376 
    377     // Inherited documentation suffices.
    378     @Override
    379     public Context getContext() {
    380         return mContext;
    381     }
    382 
    383     // Will be called when icc changed
    384     protected abstract void onUpdateIccAvailability();
    385 
    386     /**
    387      * Disables the DNS check (i.e., allows "0.0.0.0").
    388      * Useful for lab testing environment.
    389      * @param b true disables the check, false enables.
    390      */
    391     @Override
    392     public void disableDnsCheck(boolean b) {
    393         mDnsCheckDisabled = b;
    394         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
    395         SharedPreferences.Editor editor = sp.edit();
    396         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
    397         editor.apply();
    398     }
    399 
    400     /**
    401      * Returns true if the DNS check is currently disabled.
    402      */
    403     @Override
    404     public boolean isDnsCheckDisabled() {
    405         return mDnsCheckDisabled;
    406     }
    407 
    408     // Inherited documentation suffices.
    409     @Override
    410     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
    411         checkCorrectThread(h);
    412 
    413         mPreciseCallStateRegistrants.addUnique(h, what, obj);
    414     }
    415 
    416     // Inherited documentation suffices.
    417     @Override
    418     public void unregisterForPreciseCallStateChanged(Handler h) {
    419         mPreciseCallStateRegistrants.remove(h);
    420     }
    421 
    422     /**
    423      * Subclasses of Phone probably want to replace this with a
    424      * version scoped to their packages
    425      */
    426     protected void notifyPreciseCallStateChangedP() {
    427         AsyncResult ar = new AsyncResult(null, this, null);
    428         mPreciseCallStateRegistrants.notifyRegistrants(ar);
    429     }
    430 
    431     // Inherited documentation suffices.
    432     @Override
    433     public void registerForUnknownConnection(Handler h, int what, Object obj) {
    434         checkCorrectThread(h);
    435 
    436         mUnknownConnectionRegistrants.addUnique(h, what, obj);
    437     }
    438 
    439     // Inherited documentation suffices.
    440     @Override
    441     public void unregisterForUnknownConnection(Handler h) {
    442         mUnknownConnectionRegistrants.remove(h);
    443     }
    444 
    445     // Inherited documentation suffices.
    446     @Override
    447     public void registerForNewRingingConnection(
    448             Handler h, int what, Object obj) {
    449         checkCorrectThread(h);
    450 
    451         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
    452     }
    453 
    454     // Inherited documentation suffices.
    455     @Override
    456     public void unregisterForNewRingingConnection(Handler h) {
    457         mNewRingingConnectionRegistrants.remove(h);
    458     }
    459 
    460     // Inherited documentation suffices.
    461     @Override
    462     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
    463         mCi.registerForInCallVoicePrivacyOn(h,what,obj);
    464     }
    465 
    466     // Inherited documentation suffices.
    467     @Override
    468     public void unregisterForInCallVoicePrivacyOn(Handler h){
    469         mCi.unregisterForInCallVoicePrivacyOn(h);
    470     }
    471 
    472     // Inherited documentation suffices.
    473     @Override
    474     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
    475         mCi.registerForInCallVoicePrivacyOff(h,what,obj);
    476     }
    477 
    478     // Inherited documentation suffices.
    479     @Override
    480     public void unregisterForInCallVoicePrivacyOff(Handler h){
    481         mCi.unregisterForInCallVoicePrivacyOff(h);
    482     }
    483 
    484     // Inherited documentation suffices.
    485     @Override
    486     public void registerForIncomingRing(
    487             Handler h, int what, Object obj) {
    488         checkCorrectThread(h);
    489 
    490         mIncomingRingRegistrants.addUnique(h, what, obj);
    491     }
    492 
    493     // Inherited documentation suffices.
    494     @Override
    495     public void unregisterForIncomingRing(Handler h) {
    496         mIncomingRingRegistrants.remove(h);
    497     }
    498 
    499     // Inherited documentation suffices.
    500     @Override
    501     public void registerForDisconnect(Handler h, int what, Object obj) {
    502         checkCorrectThread(h);
    503 
    504         mDisconnectRegistrants.addUnique(h, what, obj);
    505     }
    506 
    507     // Inherited documentation suffices.
    508     @Override
    509     public void unregisterForDisconnect(Handler h) {
    510         mDisconnectRegistrants.remove(h);
    511     }
    512 
    513     // Inherited documentation suffices.
    514     @Override
    515     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
    516         checkCorrectThread(h);
    517 
    518         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
    519     }
    520 
    521     // Inherited documentation suffices.
    522     @Override
    523     public void unregisterForSuppServiceFailed(Handler h) {
    524         mSuppServiceFailedRegistrants.remove(h);
    525     }
    526 
    527     // Inherited documentation suffices.
    528     @Override
    529     public void registerForMmiInitiate(Handler h, int what, Object obj) {
    530         checkCorrectThread(h);
    531 
    532         mMmiRegistrants.addUnique(h, what, obj);
    533     }
    534 
    535     // Inherited documentation suffices.
    536     @Override
    537     public void unregisterForMmiInitiate(Handler h) {
    538         mMmiRegistrants.remove(h);
    539     }
    540 
    541     // Inherited documentation suffices.
    542     @Override
    543     public void registerForMmiComplete(Handler h, int what, Object obj) {
    544         checkCorrectThread(h);
    545 
    546         mMmiCompleteRegistrants.addUnique(h, what, obj);
    547     }
    548 
    549     // Inherited documentation suffices.
    550     @Override
    551     public void unregisterForMmiComplete(Handler h) {
    552         checkCorrectThread(h);
    553 
    554         mMmiCompleteRegistrants.remove(h);
    555     }
    556 
    557     /**
    558      * Method to retrieve the saved operator id from the Shared Preferences
    559      */
    560     private String getSavedNetworkSelection() {
    561         // open the shared preferences and search with our key.
    562         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
    563         return sp.getString(NETWORK_SELECTION_KEY, "");
    564     }
    565 
    566     /**
    567      * Method to restore the previously saved operator id, or reset to
    568      * automatic selection, all depending upon the value in the shared
    569      * preferences.
    570      */
    571     public void restoreSavedNetworkSelection(Message response) {
    572         // retrieve the operator id
    573         String networkSelection = getSavedNetworkSelection();
    574 
    575         // set to auto if the id is empty, otherwise select the network.
    576         if (TextUtils.isEmpty(networkSelection)) {
    577             mCi.setNetworkSelectionModeAutomatic(response);
    578         } else {
    579             mCi.setNetworkSelectionModeManual(networkSelection, response);
    580         }
    581     }
    582 
    583     // Inherited documentation suffices.
    584     @Override
    585     public void setUnitTestMode(boolean f) {
    586         mUnitTestMode = f;
    587     }
    588 
    589     // Inherited documentation suffices.
    590     @Override
    591     public boolean getUnitTestMode() {
    592         return mUnitTestMode;
    593     }
    594 
    595     /**
    596      * To be invoked when a voice call Connection disconnects.
    597      *
    598      * Subclasses of Phone probably want to replace this with a
    599      * version scoped to their packages
    600      */
    601     protected void notifyDisconnectP(Connection cn) {
    602         AsyncResult ar = new AsyncResult(null, cn, null);
    603         mDisconnectRegistrants.notifyRegistrants(ar);
    604     }
    605 
    606     // Inherited documentation suffices.
    607     @Override
    608     public void registerForServiceStateChanged(
    609             Handler h, int what, Object obj) {
    610         checkCorrectThread(h);
    611 
    612         mServiceStateRegistrants.add(h, what, obj);
    613     }
    614 
    615     // Inherited documentation suffices.
    616     @Override
    617     public void unregisterForServiceStateChanged(Handler h) {
    618         mServiceStateRegistrants.remove(h);
    619     }
    620 
    621     // Inherited documentation suffices.
    622     @Override
    623     public void registerForRingbackTone(Handler h, int what, Object obj) {
    624         mCi.registerForRingbackTone(h,what,obj);
    625     }
    626 
    627     // Inherited documentation suffices.
    628     @Override
    629     public void unregisterForRingbackTone(Handler h) {
    630         mCi.unregisterForRingbackTone(h);
    631     }
    632 
    633     // Inherited documentation suffices.
    634     @Override
    635     public void registerForResendIncallMute(Handler h, int what, Object obj) {
    636         mCi.registerForResendIncallMute(h,what,obj);
    637     }
    638 
    639     // Inherited documentation suffices.
    640     @Override
    641     public void unregisterForResendIncallMute(Handler h) {
    642         mCi.unregisterForResendIncallMute(h);
    643     }
    644 
    645     @Override
    646     public void setEchoSuppressionEnabled(boolean enabled) {
    647         // no need for regular phone
    648     }
    649 
    650     /**
    651      * Subclasses of Phone probably want to replace this with a
    652      * version scoped to their packages
    653      */
    654     protected void notifyServiceStateChangedP(ServiceState ss) {
    655         AsyncResult ar = new AsyncResult(null, ss, null);
    656         mServiceStateRegistrants.notifyRegistrants(ar);
    657 
    658         mNotifier.notifyServiceState(this);
    659     }
    660 
    661     // Inherited documentation suffices.
    662     @Override
    663     public SimulatedRadioControl getSimulatedRadioControl() {
    664         return mSimulatedRadioControl;
    665     }
    666 
    667     /**
    668      * Verifies the current thread is the same as the thread originally
    669      * used in the initialization of this instance. Throws RuntimeException
    670      * if not.
    671      *
    672      * @exception RuntimeException if the current thread is not
    673      * the thread that originally obtained this PhoneBase instance.
    674      */
    675     private void checkCorrectThread(Handler h) {
    676         if (h.getLooper() != mLooper) {
    677             throw new RuntimeException(
    678                     "com.android.internal.telephony.Phone must be used from within one thread");
    679         }
    680     }
    681 
    682     /**
    683      * Set the properties by matching the carrier string in
    684      * a string-array resource
    685      */
    686     private void setPropertiesByCarrier() {
    687         String carrier = SystemProperties.get("ro.carrier");
    688 
    689         if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
    690             return;
    691         }
    692 
    693         CharSequence[] carrierLocales = mContext.
    694                 getResources().getTextArray(R.array.carrier_properties);
    695 
    696         for (int i = 0; i < carrierLocales.length; i+=3) {
    697             String c = carrierLocales[i].toString();
    698             if (carrier.equals(c)) {
    699                 String l = carrierLocales[i+1].toString();
    700 
    701                 String language = l.substring(0, 2);
    702                 String country = "";
    703                 if (l.length() >=5) {
    704                     country = l.substring(3, 5);
    705                 }
    706                 MccTable.setSystemLocale(mContext, language, country);
    707 
    708                 if (!country.isEmpty()) {
    709                     try {
    710                         Settings.Global.getInt(mContext.getContentResolver(),
    711                                 Settings.Global.WIFI_COUNTRY_CODE);
    712                     } catch (Settings.SettingNotFoundException e) {
    713                         // note this is not persisting
    714                         WifiManager wM = (WifiManager)
    715                                 mContext.getSystemService(Context.WIFI_SERVICE);
    716                         wM.setCountryCode(country, false);
    717                     }
    718                 }
    719                 return;
    720             }
    721         }
    722     }
    723 
    724     /**
    725      * Get state
    726      */
    727     @Override
    728     public abstract PhoneConstants.State getState();
    729 
    730     /**
    731      * Retrieves the IccFileHandler of the Phone instance
    732      */
    733     public IccFileHandler getIccFileHandler(){
    734         UiccCardApplication uiccApplication = mUiccApplication.get();
    735         if (uiccApplication == null) return null;
    736         return uiccApplication.getIccFileHandler();
    737     }
    738 
    739     /*
    740      * Retrieves the Handler of the Phone instance
    741      */
    742     public Handler getHandler() {
    743         return this;
    744     }
    745 
    746     /**
    747     * Retrieves the ServiceStateTracker of the phone instance.
    748     */
    749     public ServiceStateTracker getServiceStateTracker() {
    750         return null;
    751     }
    752 
    753     /**
    754     * Get call tracker
    755     */
    756     public CallTracker getCallTracker() {
    757         return null;
    758     }
    759 
    760     public AppType getCurrentUiccAppType() {
    761         UiccCardApplication currentApp = mUiccApplication.get();
    762         if (currentApp != null) {
    763             return currentApp.getType();
    764         }
    765         return AppType.APPTYPE_UNKNOWN;
    766     }
    767 
    768     @Override
    769     public IccCard getIccCard() {
    770         return null;
    771         //throw new Exception("getIccCard Shouldn't be called from PhoneBase");
    772     }
    773 
    774     @Override
    775     public String getIccSerialNumber() {
    776         IccRecords r = mIccRecords.get();
    777         return (r != null) ? r.getIccId() : null;
    778     }
    779 
    780     @Override
    781     public boolean getIccRecordsLoaded() {
    782         IccRecords r = mIccRecords.get();
    783         return (r != null) ? r.getRecordsLoaded() : false;
    784     }
    785 
    786     /**
    787      * @return all available cell information or null if none.
    788      */
    789     @Override
    790     public List<CellInfo> getAllCellInfo() {
    791         return getServiceStateTracker().getAllCellInfo();
    792     }
    793 
    794     /**
    795      * {@inheritDoc}
    796      */
    797     @Override
    798     public void setCellInfoListRate(int rateInMillis) {
    799         mCi.setCellInfoListRate(rateInMillis, null);
    800     }
    801 
    802     @Override
    803     public boolean getMessageWaitingIndicator() {
    804         IccRecords r = mIccRecords.get();
    805         return (r != null) ? r.getVoiceMessageWaiting() : false;
    806     }
    807 
    808     @Override
    809     public boolean getCallForwardingIndicator() {
    810         IccRecords r = mIccRecords.get();
    811         return (r != null) ? r.getVoiceCallForwardingFlag() : false;
    812     }
    813 
    814     /**
    815      *  Query the status of the CDMA roaming preference
    816      */
    817     @Override
    818     public void queryCdmaRoamingPreference(Message response) {
    819         mCi.queryCdmaRoamingPreference(response);
    820     }
    821 
    822     /**
    823      * Get the signal strength
    824      */
    825     @Override
    826     public SignalStrength getSignalStrength() {
    827         ServiceStateTracker sst = getServiceStateTracker();
    828         if (sst == null) {
    829             return new SignalStrength();
    830         } else {
    831             return sst.getSignalStrength();
    832         }
    833     }
    834 
    835     /**
    836      *  Set the status of the CDMA roaming preference
    837      */
    838     @Override
    839     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
    840         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
    841     }
    842 
    843     /**
    844      *  Set the status of the CDMA subscription mode
    845      */
    846     @Override
    847     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
    848         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
    849     }
    850 
    851     /**
    852      *  Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
    853      */
    854     @Override
    855     public void setPreferredNetworkType(int networkType, Message response) {
    856         mCi.setPreferredNetworkType(networkType, response);
    857     }
    858 
    859     @Override
    860     public void getPreferredNetworkType(Message response) {
    861         mCi.getPreferredNetworkType(response);
    862     }
    863 
    864     @Override
    865     public void getSmscAddress(Message result) {
    866         mCi.getSmscAddress(result);
    867     }
    868 
    869     @Override
    870     public void setSmscAddress(String address, Message result) {
    871         mCi.setSmscAddress(address, result);
    872     }
    873 
    874     @Override
    875     public void setTTYMode(int ttyMode, Message onComplete) {
    876         mCi.setTTYMode(ttyMode, onComplete);
    877     }
    878 
    879     @Override
    880     public void queryTTYMode(Message onComplete) {
    881         mCi.queryTTYMode(onComplete);
    882     }
    883 
    884     @Override
    885     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
    886         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
    887         logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy");
    888     }
    889 
    890     @Override
    891     public void getEnhancedVoicePrivacy(Message onComplete) {
    892         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
    893         logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy");
    894     }
    895 
    896     @Override
    897     public void setBandMode(int bandMode, Message response) {
    898         mCi.setBandMode(bandMode, response);
    899     }
    900 
    901     @Override
    902     public void queryAvailableBandMode(Message response) {
    903         mCi.queryAvailableBandMode(response);
    904     }
    905 
    906     @Override
    907     public void invokeOemRilRequestRaw(byte[] data, Message response) {
    908         mCi.invokeOemRilRequestRaw(data, response);
    909     }
    910 
    911     @Override
    912     public void invokeOemRilRequestStrings(String[] strings, Message response) {
    913         mCi.invokeOemRilRequestStrings(strings, response);
    914     }
    915 
    916     @Override
    917     public void notifyDataActivity() {
    918         mNotifier.notifyDataActivity(this);
    919     }
    920 
    921     public void notifyMessageWaitingIndicator() {
    922         // Do not notify voice mail waiting if device doesn't support voice
    923         if (!mIsVoiceCapable)
    924             return;
    925 
    926         // This function is added to send the notification to DefaultPhoneNotifier.
    927         mNotifier.notifyMessageWaitingChanged(this);
    928     }
    929 
    930     public void notifyDataConnection(String reason, String apnType,
    931             PhoneConstants.DataState state) {
    932         mNotifier.notifyDataConnection(this, reason, apnType, state);
    933     }
    934 
    935     public void notifyDataConnection(String reason, String apnType) {
    936         mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
    937     }
    938 
    939     public void notifyDataConnection(String reason) {
    940         String types[] = getActiveApnTypes();
    941         for (String apnType : types) {
    942             mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
    943         }
    944     }
    945 
    946     public void notifyOtaspChanged(int otaspMode) {
    947         mNotifier.notifyOtaspChanged(this, otaspMode);
    948     }
    949 
    950     public void notifySignalStrength() {
    951         mNotifier.notifySignalStrength(this);
    952     }
    953 
    954     public void notifyCellInfo(List<CellInfo> cellInfo) {
    955         mNotifier.notifyCellInfo(this, cellInfo);
    956     }
    957 
    958     /**
    959      * @return true if a mobile originating emergency call is active
    960      */
    961     public boolean isInEmergencyCall() {
    962         return false;
    963     }
    964 
    965     /**
    966      * @return true if we are in the emergency call back mode. This is a period where
    967      * the phone should be using as little power as possible and be ready to receive an
    968      * incoming call from the emergency operator.
    969      */
    970     public boolean isInEcm() {
    971         return false;
    972     }
    973 
    974     @Override
    975     public abstract int getPhoneType();
    976 
    977     /** @hide */
    978     @Override
    979     public int getVoiceMessageCount(){
    980         return 0;
    981     }
    982 
    983     /**
    984      * Returns the CDMA ERI icon index to display
    985      */
    986     @Override
    987     public int getCdmaEriIconIndex() {
    988         logUnexpectedCdmaMethodCall("getCdmaEriIconIndex");
    989         return -1;
    990     }
    991 
    992     /**
    993      * Returns the CDMA ERI icon mode,
    994      * 0 - ON
    995      * 1 - FLASHING
    996      */
    997     @Override
    998     public int getCdmaEriIconMode() {
    999         logUnexpectedCdmaMethodCall("getCdmaEriIconMode");
   1000         return -1;
   1001     }
   1002 
   1003     /**
   1004      * Returns the CDMA ERI text,
   1005      */
   1006     @Override
   1007     public String getCdmaEriText() {
   1008         logUnexpectedCdmaMethodCall("getCdmaEriText");
   1009         return "GSM nw, no ERI";
   1010     }
   1011 
   1012     @Override
   1013     public String getCdmaMin() {
   1014         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1015         logUnexpectedCdmaMethodCall("getCdmaMin");
   1016         return null;
   1017     }
   1018 
   1019     @Override
   1020     public boolean isMinInfoReady() {
   1021         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1022         logUnexpectedCdmaMethodCall("isMinInfoReady");
   1023         return false;
   1024     }
   1025 
   1026     @Override
   1027     public String getCdmaPrlVersion(){
   1028         //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1029         logUnexpectedCdmaMethodCall("getCdmaPrlVersion");
   1030         return null;
   1031     }
   1032 
   1033     @Override
   1034     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
   1035         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1036         logUnexpectedCdmaMethodCall("sendBurstDtmf");
   1037     }
   1038 
   1039     @Override
   1040     public void exitEmergencyCallbackMode() {
   1041         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1042         logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode");
   1043     }
   1044 
   1045     @Override
   1046     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
   1047         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1048         logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange");
   1049     }
   1050 
   1051     @Override
   1052     public void unregisterForCdmaOtaStatusChange(Handler h) {
   1053         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1054         logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange");
   1055     }
   1056 
   1057     @Override
   1058     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
   1059         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1060         logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady");
   1061     }
   1062 
   1063     @Override
   1064     public void unregisterForSubscriptionInfoReady(Handler h) {
   1065         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1066         logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
   1067     }
   1068 
   1069     /**
   1070      * Returns true if OTA Service Provisioning needs to be performed.
   1071      * If not overridden return false.
   1072      */
   1073     @Override
   1074     public boolean needsOtaServiceProvisioning() {
   1075         return false;
   1076     }
   1077 
   1078     /**
   1079      * Return true if number is an OTASP number.
   1080      * If not overridden return false.
   1081      */
   1082     @Override
   1083     public  boolean isOtaSpNumber(String dialStr) {
   1084         return false;
   1085     }
   1086 
   1087     @Override
   1088     public void registerForCallWaiting(Handler h, int what, Object obj){
   1089         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1090         logUnexpectedCdmaMethodCall("registerForCallWaiting");
   1091     }
   1092 
   1093     @Override
   1094     public void unregisterForCallWaiting(Handler h){
   1095         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1096         logUnexpectedCdmaMethodCall("unregisterForCallWaiting");
   1097     }
   1098 
   1099     @Override
   1100     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
   1101         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1102         logUnexpectedCdmaMethodCall("registerForEcmTimerReset");
   1103     }
   1104 
   1105     @Override
   1106     public void unregisterForEcmTimerReset(Handler h) {
   1107         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1108         logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset");
   1109     }
   1110 
   1111     @Override
   1112     public void registerForSignalInfo(Handler h, int what, Object obj) {
   1113         mCi.registerForSignalInfo(h, what, obj);
   1114     }
   1115 
   1116     @Override
   1117     public void unregisterForSignalInfo(Handler h) {
   1118         mCi.unregisterForSignalInfo(h);
   1119     }
   1120 
   1121     @Override
   1122     public void registerForDisplayInfo(Handler h, int what, Object obj) {
   1123         mCi.registerForDisplayInfo(h, what, obj);
   1124     }
   1125 
   1126      @Override
   1127     public void unregisterForDisplayInfo(Handler h) {
   1128          mCi.unregisterForDisplayInfo(h);
   1129      }
   1130 
   1131     @Override
   1132     public void registerForNumberInfo(Handler h, int what, Object obj) {
   1133         mCi.registerForNumberInfo(h, what, obj);
   1134     }
   1135 
   1136     @Override
   1137     public void unregisterForNumberInfo(Handler h) {
   1138         mCi.unregisterForNumberInfo(h);
   1139     }
   1140 
   1141     @Override
   1142     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
   1143         mCi.registerForRedirectedNumberInfo(h, what, obj);
   1144     }
   1145 
   1146     @Override
   1147     public void unregisterForRedirectedNumberInfo(Handler h) {
   1148         mCi.unregisterForRedirectedNumberInfo(h);
   1149     }
   1150 
   1151     @Override
   1152     public void registerForLineControlInfo(Handler h, int what, Object obj) {
   1153         mCi.registerForLineControlInfo( h, what, obj);
   1154     }
   1155 
   1156     @Override
   1157     public void unregisterForLineControlInfo(Handler h) {
   1158         mCi.unregisterForLineControlInfo(h);
   1159     }
   1160 
   1161     @Override
   1162     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
   1163         mCi.registerFoT53ClirlInfo(h, what, obj);
   1164     }
   1165 
   1166     @Override
   1167     public void unregisterForT53ClirInfo(Handler h) {
   1168         mCi.unregisterForT53ClirInfo(h);
   1169     }
   1170 
   1171     @Override
   1172     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
   1173         mCi.registerForT53AudioControlInfo( h, what, obj);
   1174     }
   1175 
   1176     @Override
   1177     public void unregisterForT53AudioControlInfo(Handler h) {
   1178         mCi.unregisterForT53AudioControlInfo(h);
   1179     }
   1180 
   1181      @Override
   1182     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
   1183          // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1184          logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse");
   1185      }
   1186 
   1187      @Override
   1188     public void unsetOnEcbModeExitResponse(Handler h){
   1189         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
   1190          logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
   1191      }
   1192 
   1193     @Override
   1194     public String[] getActiveApnTypes() {
   1195         return mDcTracker.getActiveApnTypes();
   1196     }
   1197 
   1198     @Override
   1199     public String getActiveApnHost(String apnType) {
   1200         return mDcTracker.getActiveApnString(apnType);
   1201     }
   1202 
   1203     @Override
   1204     public LinkProperties getLinkProperties(String apnType) {
   1205         return mDcTracker.getLinkProperties(apnType);
   1206     }
   1207 
   1208     @Override
   1209     public LinkCapabilities getLinkCapabilities(String apnType) {
   1210         return mDcTracker.getLinkCapabilities(apnType);
   1211     }
   1212 
   1213     @Override
   1214     public int enableApnType(String type) {
   1215         return mDcTracker.enableApnType(type);
   1216     }
   1217 
   1218     @Override
   1219     public int disableApnType(String type) {
   1220         return mDcTracker.disableApnType(type);
   1221     }
   1222 
   1223     @Override
   1224     public boolean isDataConnectivityPossible() {
   1225         return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT);
   1226     }
   1227 
   1228     @Override
   1229     public boolean isDataConnectivityPossible(String apnType) {
   1230         return ((mDcTracker != null) &&
   1231                 (mDcTracker.isDataPossible(apnType)));
   1232     }
   1233 
   1234     /**
   1235      * Notify registrants of a new ringing Connection.
   1236      * Subclasses of Phone probably want to replace this with a
   1237      * version scoped to their packages
   1238      */
   1239     protected void notifyNewRingingConnectionP(Connection cn) {
   1240         if (!mIsVoiceCapable)
   1241             return;
   1242         AsyncResult ar = new AsyncResult(null, cn, null);
   1243         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
   1244     }
   1245 
   1246     /**
   1247      * Notify registrants of a RING event.
   1248      */
   1249     private void notifyIncomingRing() {
   1250         if (!mIsVoiceCapable)
   1251             return;
   1252         AsyncResult ar = new AsyncResult(null, this, null);
   1253         mIncomingRingRegistrants.notifyRegistrants(ar);
   1254     }
   1255 
   1256     /**
   1257      * Send the incoming call Ring notification if conditions are right.
   1258      */
   1259     private void sendIncomingCallRingNotification(int token) {
   1260         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
   1261                 (token == mCallRingContinueToken)) {
   1262             Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
   1263             notifyIncomingRing();
   1264             sendMessageDelayed(
   1265                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
   1266         } else {
   1267             Rlog.d(LOG_TAG, "Ignoring ring notification request,"
   1268                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
   1269                     + " token=" + token
   1270                     + " mCallRingContinueToken=" + mCallRingContinueToken
   1271                     + " mIsVoiceCapable=" + mIsVoiceCapable);
   1272         }
   1273     }
   1274 
   1275     @Override
   1276     public boolean isCspPlmnEnabled() {
   1277         // This function should be overridden by the class GSMPhone.
   1278         // Not implemented in CDMAPhone.
   1279         logUnexpectedGsmMethodCall("isCspPlmnEnabled");
   1280         return false;
   1281     }
   1282 
   1283     @Override
   1284     public IsimRecords getIsimRecords() {
   1285         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
   1286         return null;
   1287     }
   1288 
   1289     @Override
   1290     public void requestIsimAuthentication(String nonce, Message result) {
   1291         Rlog.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
   1292     }
   1293 
   1294     @Override
   1295     public String getMsisdn() {
   1296         logUnexpectedGsmMethodCall("getMsisdn");
   1297         return null;
   1298     }
   1299 
   1300     /**
   1301      * Common error logger method for unexpected calls to CDMA-only methods.
   1302      */
   1303     private static void logUnexpectedCdmaMethodCall(String name)
   1304     {
   1305         Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
   1306                 "called, CDMAPhone inactive.");
   1307     }
   1308 
   1309     @Override
   1310     public PhoneConstants.DataState getDataConnectionState() {
   1311         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
   1312     }
   1313 
   1314     /**
   1315      * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
   1316      */
   1317     private static void logUnexpectedGsmMethodCall(String name) {
   1318         Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
   1319                 "called, GSMPhone inactive.");
   1320     }
   1321 
   1322     // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
   1323     public void notifyCallForwardingIndicator() {
   1324         // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
   1325         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
   1326     }
   1327 
   1328     public void notifyDataConnectionFailed(String reason, String apnType) {
   1329         mNotifier.notifyDataConnectionFailed(this, reason, apnType);
   1330     }
   1331 
   1332     /**
   1333      * {@inheritDoc}
   1334      */
   1335     @Override
   1336     public int getLteOnCdmaMode() {
   1337         return mCi.getLteOnCdmaMode();
   1338     }
   1339 
   1340     /**
   1341      * Sets the SIM voice message waiting indicator records.
   1342      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
   1343      * @param countWaiting The number of messages waiting, if known. Use
   1344      *                     -1 to indicate that an unknown number of
   1345      *                      messages are waiting
   1346      */
   1347     @Override
   1348     public void setVoiceMessageWaiting(int line, int countWaiting) {
   1349         IccRecords r = mIccRecords.get();
   1350         if (r != null) {
   1351             r.setVoiceMessageWaiting(line, countWaiting);
   1352         }
   1353     }
   1354 
   1355     /**
   1356      * Gets the USIM service table from the UICC, if present and available.
   1357      * @return an interface to the UsimServiceTable record, or null if not available
   1358      */
   1359     @Override
   1360     public UsimServiceTable getUsimServiceTable() {
   1361         IccRecords r = mIccRecords.get();
   1362         return (r != null) ? r.getUsimServiceTable() : null;
   1363     }
   1364 
   1365     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1366         pw.println("PhoneBase:");
   1367         pw.println(" mCi=" + mCi);
   1368         pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
   1369         pw.println(" mDcTracker=" + mDcTracker);
   1370         pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
   1371         pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
   1372         pw.println(" mCallRingDelay=" + mCallRingDelay);
   1373         pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
   1374         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
   1375         pw.println(" mIccRecords=" + mIccRecords.get());
   1376         pw.println(" mUiccApplication=" + mUiccApplication.get());
   1377         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
   1378         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
   1379         pw.println(" mSMS=" + mSMS);
   1380         pw.flush();
   1381         pw.println(" mLooper=" + mLooper);
   1382         pw.println(" mContext=" + mContext);
   1383         pw.println(" mNotifier=" + mNotifier);
   1384         pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
   1385         pw.println(" mUnitTestMode=" + mUnitTestMode);
   1386         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
   1387         pw.println(" getUnitTestMode()=" + getUnitTestMode());
   1388         pw.println(" getState()=" + getState());
   1389         pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
   1390         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
   1391         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
   1392         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
   1393         pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
   1394         pw.flush();
   1395         pw.println(" isInEcm()=" + isInEcm());
   1396         pw.println(" getPhoneName()=" + getPhoneName());
   1397         pw.println(" getPhoneType()=" + getPhoneType());
   1398         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
   1399         pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
   1400         pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
   1401         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
   1402     }
   1403 }
   1404