Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2006 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 
     20 import android.content.Context;
     21 import android.os.RegistrantList;
     22 import android.os.Registrant;
     23 import android.os.Handler;
     24 import android.os.AsyncResult;
     25 import android.os.SystemProperties;
     26 import android.util.Log;
     27 
     28 import java.io.FileInputStream;
     29 import java.io.IOException;
     30 import java.util.regex.Matcher;
     31 import java.util.regex.Pattern;
     32 
     33 /**
     34  * {@hide}
     35  */
     36 public abstract class BaseCommands implements CommandsInterface {
     37     static final String LOG_TAG = "RILB";
     38 
     39     //***** Instance Variables
     40     protected Context mContext;
     41     protected RadioState mState = RadioState.RADIO_UNAVAILABLE;
     42     protected Object mStateMonitor = new Object();
     43 
     44     protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
     45     protected RegistrantList mOnRegistrants = new RegistrantList();
     46     protected RegistrantList mAvailRegistrants = new RegistrantList();
     47     protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
     48     protected RegistrantList mNotAvailRegistrants = new RegistrantList();
     49     protected RegistrantList mCallStateRegistrants = new RegistrantList();
     50     protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
     51     protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
     52     protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
     53     protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
     54     protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
     55     protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
     56     protected Registrant mUnsolOemHookRawRegistrant;
     57     protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
     58     protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
     59     protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
     60     protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
     61     protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
     62     protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
     63     protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
     64     protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
     65     protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
     66     protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
     67     protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
     68     protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
     69     protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
     70     protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
     71     protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
     72     protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
     73 
     74     protected Registrant mGsmSmsRegistrant;
     75     protected Registrant mCdmaSmsRegistrant;
     76     protected Registrant mNITZTimeRegistrant;
     77     protected Registrant mSignalStrengthRegistrant;
     78     protected Registrant mUSSDRegistrant;
     79     protected Registrant mSmsOnSimRegistrant;
     80     protected Registrant mSmsStatusRegistrant;
     81     protected Registrant mSsnRegistrant;
     82     protected Registrant mCatSessionEndRegistrant;
     83     protected Registrant mCatProCmdRegistrant;
     84     protected Registrant mCatEventRegistrant;
     85     protected Registrant mCatCallSetUpRegistrant;
     86     protected Registrant mIccSmsFullRegistrant;
     87     protected Registrant mEmergencyCallbackModeRegistrant;
     88     protected Registrant mRingRegistrant;
     89     protected Registrant mRestrictedStateRegistrant;
     90     protected Registrant mGsmBroadcastSmsRegistrant;
     91 
     92     // Preferred network type received from PhoneFactory.
     93     // This is used when establishing a connection to the
     94     // vendor ril so it starts up in the correct mode.
     95     protected int mPreferredNetworkType;
     96     // CDMA subscription received from PhoneFactory
     97     protected int mCdmaSubscription;
     98     // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
     99     protected int mPhoneType;
    100     // RIL Version
    101     protected int mRilVersion = -1;
    102 
    103     public BaseCommands(Context context) {
    104         mContext = context;  // May be null (if so we won't log statistics)
    105     }
    106 
    107     //***** CommandsInterface implementation
    108 
    109     public RadioState getRadioState() {
    110         return mState;
    111     }
    112 
    113     public void registerForRadioStateChanged(Handler h, int what, Object obj) {
    114         Registrant r = new Registrant (h, what, obj);
    115 
    116         synchronized (mStateMonitor) {
    117             mRadioStateChangedRegistrants.add(r);
    118             r.notifyRegistrant();
    119         }
    120     }
    121 
    122     public void unregisterForRadioStateChanged(Handler h) {
    123         synchronized (mStateMonitor) {
    124             mRadioStateChangedRegistrants.remove(h);
    125         }
    126     }
    127 
    128     public void registerForOn(Handler h, int what, Object obj) {
    129         Registrant r = new Registrant (h, what, obj);
    130 
    131         synchronized (mStateMonitor) {
    132             mOnRegistrants.add(r);
    133 
    134             if (mState.isOn()) {
    135                 r.notifyRegistrant(new AsyncResult(null, null, null));
    136             }
    137         }
    138     }
    139     public void unregisterForOn(Handler h) {
    140         synchronized (mStateMonitor) {
    141             mOnRegistrants.remove(h);
    142         }
    143     }
    144 
    145 
    146     public void registerForAvailable(Handler h, int what, Object obj) {
    147         Registrant r = new Registrant (h, what, obj);
    148 
    149         synchronized (mStateMonitor) {
    150             mAvailRegistrants.add(r);
    151 
    152             if (mState.isAvailable()) {
    153                 r.notifyRegistrant(new AsyncResult(null, null, null));
    154             }
    155         }
    156     }
    157 
    158     public void unregisterForAvailable(Handler h) {
    159         synchronized(mStateMonitor) {
    160             mAvailRegistrants.remove(h);
    161         }
    162     }
    163 
    164     public void registerForNotAvailable(Handler h, int what, Object obj) {
    165         Registrant r = new Registrant (h, what, obj);
    166 
    167         synchronized (mStateMonitor) {
    168             mNotAvailRegistrants.add(r);
    169 
    170             if (!mState.isAvailable()) {
    171                 r.notifyRegistrant(new AsyncResult(null, null, null));
    172             }
    173         }
    174     }
    175 
    176     public void unregisterForNotAvailable(Handler h) {
    177         synchronized (mStateMonitor) {
    178             mNotAvailRegistrants.remove(h);
    179         }
    180     }
    181 
    182     public void registerForOffOrNotAvailable(Handler h, int what, Object obj) {
    183         Registrant r = new Registrant (h, what, obj);
    184 
    185         synchronized (mStateMonitor) {
    186             mOffOrNotAvailRegistrants.add(r);
    187 
    188             if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) {
    189                 r.notifyRegistrant(new AsyncResult(null, null, null));
    190             }
    191         }
    192     }
    193     public void unregisterForOffOrNotAvailable(Handler h) {
    194         synchronized(mStateMonitor) {
    195             mOffOrNotAvailRegistrants.remove(h);
    196         }
    197     }
    198 
    199     public void registerForCallStateChanged(Handler h, int what, Object obj) {
    200         Registrant r = new Registrant (h, what, obj);
    201 
    202         mCallStateRegistrants.add(r);
    203     }
    204 
    205     public void unregisterForCallStateChanged(Handler h) {
    206         mCallStateRegistrants.remove(h);
    207     }
    208 
    209     public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
    210         Registrant r = new Registrant (h, what, obj);
    211 
    212         mVoiceNetworkStateRegistrants.add(r);
    213     }
    214 
    215     public void unregisterForVoiceNetworkStateChanged(Handler h) {
    216         mVoiceNetworkStateRegistrants.remove(h);
    217     }
    218 
    219     public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
    220         Registrant r = new Registrant (h, what, obj);
    221 
    222         mDataNetworkStateRegistrants.add(r);
    223     }
    224 
    225     public void unregisterForDataNetworkStateChanged(Handler h) {
    226         mDataNetworkStateRegistrants.remove(h);
    227     }
    228 
    229     public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
    230         Registrant r = new Registrant (h, what, obj);
    231         mVoiceRadioTechChangedRegistrants.add(r);
    232     }
    233 
    234     public void unregisterForVoiceRadioTechChanged(Handler h) {
    235         mVoiceRadioTechChangedRegistrants.remove(h);
    236     }
    237 
    238     public void registerForIccStatusChanged(Handler h, int what, Object obj) {
    239         Registrant r = new Registrant (h, what, obj);
    240         mIccStatusChangedRegistrants.add(r);
    241     }
    242 
    243     public void unregisterForIccStatusChanged(Handler h) {
    244         mIccStatusChangedRegistrants.remove(h);
    245     }
    246 
    247     public void setOnNewGsmSms(Handler h, int what, Object obj) {
    248         mGsmSmsRegistrant = new Registrant (h, what, obj);
    249     }
    250 
    251     public void unSetOnNewGsmSms(Handler h) {
    252         mGsmSmsRegistrant.clear();
    253     }
    254 
    255     public void setOnNewCdmaSms(Handler h, int what, Object obj) {
    256         mCdmaSmsRegistrant = new Registrant (h, what, obj);
    257     }
    258 
    259     public void unSetOnNewCdmaSms(Handler h) {
    260         mCdmaSmsRegistrant.clear();
    261     }
    262 
    263     public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
    264         mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
    265     }
    266 
    267     public void unSetOnNewGsmBroadcastSms(Handler h) {
    268         mGsmBroadcastSmsRegistrant.clear();
    269     }
    270 
    271     public void setOnSmsOnSim(Handler h, int what, Object obj) {
    272         mSmsOnSimRegistrant = new Registrant (h, what, obj);
    273     }
    274 
    275     public void unSetOnSmsOnSim(Handler h) {
    276         mSmsOnSimRegistrant.clear();
    277     }
    278 
    279     public void setOnSmsStatus(Handler h, int what, Object obj) {
    280         mSmsStatusRegistrant = new Registrant (h, what, obj);
    281     }
    282 
    283     public void unSetOnSmsStatus(Handler h) {
    284         mSmsStatusRegistrant.clear();
    285     }
    286 
    287     public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
    288         mSignalStrengthRegistrant = new Registrant (h, what, obj);
    289     }
    290 
    291     public void unSetOnSignalStrengthUpdate(Handler h) {
    292         mSignalStrengthRegistrant.clear();
    293     }
    294 
    295     public void setOnNITZTime(Handler h, int what, Object obj) {
    296         mNITZTimeRegistrant = new Registrant (h, what, obj);
    297     }
    298 
    299     public void unSetOnNITZTime(Handler h) {
    300         mNITZTimeRegistrant.clear();
    301     }
    302 
    303     public void setOnUSSD(Handler h, int what, Object obj) {
    304         mUSSDRegistrant = new Registrant (h, what, obj);
    305     }
    306 
    307     public void unSetOnUSSD(Handler h) {
    308         mUSSDRegistrant.clear();
    309     }
    310 
    311     public void setOnSuppServiceNotification(Handler h, int what, Object obj) {
    312         mSsnRegistrant = new Registrant (h, what, obj);
    313     }
    314 
    315     public void unSetOnSuppServiceNotification(Handler h) {
    316         mSsnRegistrant.clear();
    317     }
    318 
    319     public void setOnCatSessionEnd(Handler h, int what, Object obj) {
    320         mCatSessionEndRegistrant = new Registrant (h, what, obj);
    321     }
    322 
    323     public void unSetOnCatSessionEnd(Handler h) {
    324         mCatSessionEndRegistrant.clear();
    325     }
    326 
    327     public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
    328         mCatProCmdRegistrant = new Registrant (h, what, obj);
    329     }
    330 
    331     public void unSetOnCatProactiveCmd(Handler h) {
    332         mCatProCmdRegistrant.clear();
    333     }
    334 
    335     public void setOnCatEvent(Handler h, int what, Object obj) {
    336         mCatEventRegistrant = new Registrant (h, what, obj);
    337     }
    338 
    339     public void unSetOnCatEvent(Handler h) {
    340         mCatEventRegistrant.clear();
    341     }
    342 
    343     public void setOnCatCallSetUp(Handler h, int what, Object obj) {
    344         mCatCallSetUpRegistrant = new Registrant (h, what, obj);
    345     }
    346 
    347     public void unSetOnCatCallSetUp(Handler h) {
    348         mCatCallSetUpRegistrant.clear();
    349     }
    350 
    351     public void setOnIccSmsFull(Handler h, int what, Object obj) {
    352         mIccSmsFullRegistrant = new Registrant (h, what, obj);
    353     }
    354 
    355     public void unSetOnIccSmsFull(Handler h) {
    356         mIccSmsFullRegistrant.clear();
    357     }
    358 
    359     public void registerForIccRefresh(Handler h, int what, Object obj) {
    360         Registrant r = new Registrant (h, what, obj);
    361         mIccRefreshRegistrants.add(r);
    362     }
    363     public void setOnIccRefresh(Handler h, int what, Object obj) {
    364         registerForIccRefresh(h, what, obj);
    365     }
    366 
    367     public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
    368         mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
    369     }
    370 
    371     public void unregisterForIccRefresh(Handler h) {
    372         mIccRefreshRegistrants.remove(h);
    373     }
    374     public void unsetOnIccRefresh(Handler h) {
    375         unregisterForIccRefresh(h);
    376     }
    377 
    378     public void setOnCallRing(Handler h, int what, Object obj) {
    379         mRingRegistrant = new Registrant (h, what, obj);
    380     }
    381 
    382     public void unSetOnCallRing(Handler h) {
    383         mRingRegistrant.clear();
    384     }
    385 
    386     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj) {
    387         Registrant r = new Registrant (h, what, obj);
    388         mVoicePrivacyOnRegistrants.add(r);
    389     }
    390 
    391     public void unregisterForInCallVoicePrivacyOn(Handler h){
    392         mVoicePrivacyOnRegistrants.remove(h);
    393     }
    394 
    395     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj) {
    396         Registrant r = new Registrant (h, what, obj);
    397         mVoicePrivacyOffRegistrants.add(r);
    398     }
    399 
    400     public void unregisterForInCallVoicePrivacyOff(Handler h){
    401         mVoicePrivacyOffRegistrants.remove(h);
    402     }
    403 
    404     public void setOnRestrictedStateChanged(Handler h, int what, Object obj) {
    405         mRestrictedStateRegistrant = new Registrant (h, what, obj);
    406     }
    407 
    408     public void unSetOnRestrictedStateChanged(Handler h) {
    409         mRestrictedStateRegistrant.clear();
    410     }
    411 
    412     public void registerForDisplayInfo(Handler h, int what, Object obj) {
    413         Registrant r = new Registrant (h, what, obj);
    414         mDisplayInfoRegistrants.add(r);
    415     }
    416 
    417     public void unregisterForDisplayInfo(Handler h) {
    418         mDisplayInfoRegistrants.remove(h);
    419     }
    420 
    421     public void registerForCallWaitingInfo(Handler h, int what, Object obj) {
    422         Registrant r = new Registrant (h, what, obj);
    423         mCallWaitingInfoRegistrants.add(r);
    424     }
    425 
    426     public void unregisterForCallWaitingInfo(Handler h) {
    427         mCallWaitingInfoRegistrants.remove(h);
    428     }
    429 
    430     public void registerForSignalInfo(Handler h, int what, Object obj) {
    431         Registrant r = new Registrant (h, what, obj);
    432         mSignalInfoRegistrants.add(r);
    433     }
    434 
    435     public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) {
    436         mUnsolOemHookRawRegistrant = new Registrant (h, what, obj);
    437     }
    438 
    439     public void unSetOnUnsolOemHookRaw(Handler h) {
    440         mUnsolOemHookRawRegistrant.clear();
    441     }
    442 
    443     public void unregisterForSignalInfo(Handler h) {
    444         mSignalInfoRegistrants.remove(h);
    445     }
    446 
    447     public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
    448         Registrant r = new Registrant (h, what, obj);
    449         mOtaProvisionRegistrants.add(r);
    450     }
    451 
    452     public void unregisterForCdmaOtaProvision(Handler h){
    453         mOtaProvisionRegistrants.remove(h);
    454     }
    455 
    456     public void registerForNumberInfo(Handler h,int what, Object obj) {
    457         Registrant r = new Registrant (h, what, obj);
    458         mNumberInfoRegistrants.add(r);
    459     }
    460 
    461     public void unregisterForNumberInfo(Handler h){
    462         mNumberInfoRegistrants.remove(h);
    463     }
    464 
    465      public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
    466         Registrant r = new Registrant (h, what, obj);
    467         mRedirNumInfoRegistrants.add(r);
    468     }
    469 
    470     public void unregisterForRedirectedNumberInfo(Handler h) {
    471         mRedirNumInfoRegistrants.remove(h);
    472     }
    473 
    474     public void registerForLineControlInfo(Handler h, int what, Object obj) {
    475         Registrant r = new Registrant (h, what, obj);
    476         mLineControlInfoRegistrants.add(r);
    477     }
    478 
    479     public void unregisterForLineControlInfo(Handler h) {
    480         mLineControlInfoRegistrants.remove(h);
    481     }
    482 
    483     public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
    484         Registrant r = new Registrant (h, what, obj);
    485         mT53ClirInfoRegistrants.add(r);
    486     }
    487 
    488     public void unregisterForT53ClirInfo(Handler h) {
    489         mT53ClirInfoRegistrants.remove(h);
    490     }
    491 
    492     public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
    493         Registrant r = new Registrant (h, what, obj);
    494         mT53AudCntrlInfoRegistrants.add(r);
    495     }
    496 
    497     public void unregisterForT53AudioControlInfo(Handler h) {
    498         mT53AudCntrlInfoRegistrants.remove(h);
    499     }
    500 
    501     public void registerForRingbackTone(Handler h, int what, Object obj) {
    502         Registrant r = new Registrant (h, what, obj);
    503         mRingbackToneRegistrants.add(r);
    504     }
    505 
    506     public void unregisterForRingbackTone(Handler h) {
    507         mRingbackToneRegistrants.remove(h);
    508     }
    509 
    510     public void registerForResendIncallMute(Handler h, int what, Object obj) {
    511         Registrant r = new Registrant (h, what, obj);
    512         mResendIncallMuteRegistrants.add(r);
    513     }
    514 
    515     public void unregisterForResendIncallMute(Handler h) {
    516         mResendIncallMuteRegistrants.remove(h);
    517     }
    518 
    519     @Override
    520     public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
    521         Registrant r = new Registrant (h, what, obj);
    522         mCdmaSubscriptionChangedRegistrants.add(r);
    523     }
    524 
    525     @Override
    526     public void unregisterForCdmaSubscriptionChanged(Handler h) {
    527         mCdmaSubscriptionChangedRegistrants.remove(h);
    528     }
    529 
    530     @Override
    531     public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
    532         Registrant r = new Registrant (h, what, obj);
    533         mCdmaPrlChangedRegistrants.add(r);
    534     }
    535 
    536     @Override
    537     public void unregisterForCdmaPrlChanged(Handler h) {
    538         mCdmaPrlChangedRegistrants.remove(h);
    539     }
    540 
    541     @Override
    542     public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
    543         Registrant r = new Registrant (h, what, obj);
    544         mExitEmergencyCallbackModeRegistrants.add(r);
    545     }
    546 
    547     @Override
    548     public void unregisterForExitEmergencyCallbackMode(Handler h) {
    549         mExitEmergencyCallbackModeRegistrants.remove(h);
    550     }
    551 
    552     /**
    553      * {@inheritDoc}
    554      */
    555     @Override
    556     public void registerForRilConnected(Handler h, int what, Object obj) {
    557         Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
    558         Registrant r = new Registrant (h, what, obj);
    559         mRilConnectedRegistrants.add(r);
    560         if (mRilVersion != -1) {
    561             Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
    562             r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null));
    563         }
    564     }
    565 
    566     @Override
    567     public void unregisterForRilConnected(Handler h) {
    568         mRilConnectedRegistrants.remove(h);
    569     }
    570 
    571     /**
    572      * {@inheritDoc}
    573      */
    574     @Override
    575     public void setCurrentPreferredNetworkType() {
    576     }
    577 
    578     //***** Protected Methods
    579     /**
    580      * Store new RadioState and send notification based on the changes
    581      *
    582      * This function is called only by RIL.java when receiving unsolicited
    583      * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
    584      *
    585      * RadioState has 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON.
    586      *
    587      * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
    588      */
    589     protected void setRadioState(RadioState newState) {
    590         RadioState oldState;
    591 
    592         synchronized (mStateMonitor) {
    593             if (false) {
    594                 Log.v(LOG_TAG, "setRadioState old: " + mState
    595                     + " new " + newState);
    596             }
    597 
    598             oldState = mState;
    599             mState = newState;
    600 
    601             if (oldState == mState) {
    602                 // no state transition
    603                 return;
    604             }
    605 
    606             mRadioStateChangedRegistrants.notifyRegistrants();
    607 
    608             if (mState.isAvailable() && !oldState.isAvailable()) {
    609                 Log.d(LOG_TAG,"Notifying: radio available");
    610                 mAvailRegistrants.notifyRegistrants();
    611                 onRadioAvailable();
    612             }
    613 
    614             if (!mState.isAvailable() && oldState.isAvailable()) {
    615                 Log.d(LOG_TAG,"Notifying: radio not available");
    616                 mNotAvailRegistrants.notifyRegistrants();
    617             }
    618 
    619             if (mState.isOn() && !oldState.isOn()) {
    620                 Log.d(LOG_TAG,"Notifying: Radio On");
    621                 mOnRegistrants.notifyRegistrants();
    622             }
    623 
    624             if ((!mState.isOn() || !mState.isAvailable())
    625                 && !((!oldState.isOn() || !oldState.isAvailable()))
    626             ) {
    627                 Log.d(LOG_TAG,"Notifying: radio off or not available");
    628                 mOffOrNotAvailRegistrants.notifyRegistrants();
    629             }
    630         }
    631     }
    632 
    633     protected void onRadioAvailable() {
    634     }
    635 
    636     /**
    637      * The contents of the /proc/cmdline file
    638      */
    639     private static String getProcCmdLine()
    640     {
    641         String cmdline = "";
    642         FileInputStream is = null;
    643         try {
    644             is = new FileInputStream("/proc/cmdline");
    645             byte [] buffer = new byte[2048];
    646             int count = is.read(buffer);
    647             if (count > 0) {
    648                 cmdline = new String(buffer, 0, count);
    649             }
    650         } catch (IOException e) {
    651             Log.d(LOG_TAG, "No /proc/cmdline exception=" + e);
    652         } finally {
    653             if (is != null) {
    654                 try {
    655                     is.close();
    656                 } catch (IOException e) {
    657                 }
    658             }
    659         }
    660         Log.d(LOG_TAG, "/proc/cmdline=" + cmdline);
    661         return cmdline;
    662     }
    663 
    664     /**
    665      * {@inheritDoc}
    666      */
    667     @Override
    668     public int getLteOnCdmaMode() {
    669         return getLteOnCdmaModeStatic();
    670     }
    671 
    672     /** Kernel command line */
    673     private static final String sKernelCmdLine = getProcCmdLine();
    674 
    675     /** Pattern for selecting the product type from the kernel command line */
    676     private static final Pattern sProductTypePattern =
    677         Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
    678 
    679     /** The ProductType used for LTE on CDMA devices */
    680     private static final String sLteOnCdmaProductType =
    681         SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
    682 
    683     /**
    684      * Return if the current radio is LTE on CDMA. This
    685      * is a tri-state return value as for a period of time
    686      * the mode may be unknown.
    687      *
    688      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
    689      * or {@link Phone#LTE_ON_CDMA_TRUE}
    690      */
    691     public static int getLteOnCdmaModeStatic() {
    692         int retVal;
    693         int curVal;
    694         String productType = "";
    695 
    696         curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
    697                     Phone.LTE_ON_CDMA_UNKNOWN);
    698         retVal = curVal;
    699         if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) {
    700             Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
    701             if (matcher.find()) {
    702                 productType = matcher.group(1);
    703                 if (sLteOnCdmaProductType.equals(productType)) {
    704                     retVal = Phone.LTE_ON_CDMA_TRUE;
    705                 } else {
    706                     retVal = Phone.LTE_ON_CDMA_FALSE;
    707                 }
    708             } else {
    709                 retVal = Phone.LTE_ON_CDMA_FALSE;
    710             }
    711         }
    712 
    713         Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
    714                 " product_type='" + productType +
    715                 "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
    716         return retVal;
    717     }
    718 
    719     @Override
    720     public void testingEmergencyCall() {}
    721 }
    722