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