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 RadioState mSimState = RadioState.RADIO_UNAVAILABLE;
     43     protected RadioState mRuimState = RadioState.RADIO_UNAVAILABLE;
     44     protected RadioState mNvState = RadioState.RADIO_UNAVAILABLE;
     45     protected Object mStateMonitor = new Object();
     46 
     47     protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
     48     protected RegistrantList mOnRegistrants = new RegistrantList();
     49     protected RegistrantList mAvailRegistrants = new RegistrantList();
     50     protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
     51     protected RegistrantList mNotAvailRegistrants = new RegistrantList();
     52     protected RegistrantList mSIMReadyRegistrants = new RegistrantList();
     53     protected RegistrantList mSIMLockedRegistrants = new RegistrantList();
     54     protected RegistrantList mRUIMReadyRegistrants = new RegistrantList();
     55     protected RegistrantList mRUIMLockedRegistrants = new RegistrantList();
     56     protected RegistrantList mNVReadyRegistrants = new RegistrantList();
     57     protected RegistrantList mCallStateRegistrants = new RegistrantList();
     58     protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
     59     protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
     60     protected RegistrantList mRadioTechnologyChangedRegistrants = new RegistrantList();
     61     protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
     62     protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
     63     protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
     64     protected Registrant mUnsolOemHookRawRegistrant;
     65     protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
     66     protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
     67     protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
     68     protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
     69     protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
     70     protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
     71     protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
     72     protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
     73     protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
     74     protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
     75     protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
     76     protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
     77     protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
     78     protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
     79     protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
     80     protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
     81 
     82     protected Registrant mGsmSmsRegistrant;
     83     protected Registrant mCdmaSmsRegistrant;
     84     protected Registrant mNITZTimeRegistrant;
     85     protected Registrant mSignalStrengthRegistrant;
     86     protected Registrant mUSSDRegistrant;
     87     protected Registrant mSmsOnSimRegistrant;
     88     protected Registrant mSmsStatusRegistrant;
     89     protected Registrant mSsnRegistrant;
     90     protected Registrant mCatSessionEndRegistrant;
     91     protected Registrant mCatProCmdRegistrant;
     92     protected Registrant mCatEventRegistrant;
     93     protected Registrant mCatCallSetUpRegistrant;
     94     protected Registrant mIccSmsFullRegistrant;
     95     protected Registrant mEmergencyCallbackModeRegistrant;
     96     protected Registrant mRingRegistrant;
     97     protected Registrant mRestrictedStateRegistrant;
     98     protected Registrant mGsmBroadcastSmsRegistrant;
     99 
    100     // Preferred network type received from PhoneFactory.
    101     // This is used when establishing a connection to the
    102     // vendor ril so it starts up in the correct mode.
    103     protected int mPreferredNetworkType;
    104     // CDMA subscription received from PhoneFactory
    105     protected int mCdmaSubscription;
    106     // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
    107     protected int mPhoneType;
    108     // RIL Version
    109     protected int mRilVersion = -1;
    110 
    111     public BaseCommands(Context context) {
    112         mContext = context;  // May be null (if so we won't log statistics)
    113     }
    114 
    115     //***** CommandsInterface implementation
    116 
    117     public RadioState getRadioState() {
    118         return mState;
    119     }
    120 
    121     public RadioState getSimState() {
    122         return mSimState;
    123     }
    124 
    125     public RadioState getRuimState() {
    126         return mRuimState;
    127     }
    128 
    129     public RadioState getNvState() {
    130         return mNvState;
    131     }
    132 
    133 
    134     public void registerForRadioStateChanged(Handler h, int what, Object obj) {
    135         Registrant r = new Registrant (h, what, obj);
    136 
    137         synchronized (mStateMonitor) {
    138             mRadioStateChangedRegistrants.add(r);
    139             r.notifyRegistrant();
    140         }
    141     }
    142 
    143     public void unregisterForRadioStateChanged(Handler h) {
    144         synchronized (mStateMonitor) {
    145             mRadioStateChangedRegistrants.remove(h);
    146         }
    147     }
    148 
    149     public void registerForOn(Handler h, int what, Object obj) {
    150         Registrant r = new Registrant (h, what, obj);
    151 
    152         synchronized (mStateMonitor) {
    153             mOnRegistrants.add(r);
    154 
    155             if (mState.isOn()) {
    156                 r.notifyRegistrant(new AsyncResult(null, null, null));
    157             }
    158         }
    159     }
    160     public void unregisterForOn(Handler h) {
    161         synchronized (mStateMonitor) {
    162             mOnRegistrants.remove(h);
    163         }
    164     }
    165 
    166 
    167     public void registerForAvailable(Handler h, int what, Object obj) {
    168         Registrant r = new Registrant (h, what, obj);
    169 
    170         synchronized (mStateMonitor) {
    171             mAvailRegistrants.add(r);
    172 
    173             if (mState.isAvailable()) {
    174                 r.notifyRegistrant(new AsyncResult(null, null, null));
    175             }
    176         }
    177     }
    178 
    179     public void unregisterForAvailable(Handler h) {
    180         synchronized(mStateMonitor) {
    181             mAvailRegistrants.remove(h);
    182         }
    183     }
    184 
    185     public void registerForNotAvailable(Handler h, int what, Object obj) {
    186         Registrant r = new Registrant (h, what, obj);
    187 
    188         synchronized (mStateMonitor) {
    189             mNotAvailRegistrants.add(r);
    190 
    191             if (!mState.isAvailable()) {
    192                 r.notifyRegistrant(new AsyncResult(null, null, null));
    193             }
    194         }
    195     }
    196 
    197     public void unregisterForNotAvailable(Handler h) {
    198         synchronized (mStateMonitor) {
    199             mNotAvailRegistrants.remove(h);
    200         }
    201     }
    202 
    203     public void registerForOffOrNotAvailable(Handler h, int what, Object obj) {
    204         Registrant r = new Registrant (h, what, obj);
    205 
    206         synchronized (mStateMonitor) {
    207             mOffOrNotAvailRegistrants.add(r);
    208 
    209             if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) {
    210                 r.notifyRegistrant(new AsyncResult(null, null, null));
    211             }
    212         }
    213     }
    214     public void unregisterForOffOrNotAvailable(Handler h) {
    215         synchronized(mStateMonitor) {
    216             mOffOrNotAvailRegistrants.remove(h);
    217         }
    218     }
    219 
    220 
    221     /** Any transition into SIM_READY */
    222     public void registerForSIMReady(Handler h, int what, Object obj) {
    223         Registrant r = new Registrant (h, what, obj);
    224 
    225         synchronized (mStateMonitor) {
    226             mSIMReadyRegistrants.add(r);
    227 
    228             if (mSimState.isSIMReady()) {
    229                 r.notifyRegistrant(new AsyncResult(null, null, null));
    230             }
    231         }
    232     }
    233 
    234     public void unregisterForSIMReady(Handler h) {
    235         synchronized (mStateMonitor) {
    236             mSIMReadyRegistrants.remove(h);
    237         }
    238     }
    239 
    240     /** Any transition into RUIM_READY */
    241     public void registerForRUIMReady(Handler h, int what, Object obj) {
    242         Registrant r = new Registrant (h, what, obj);
    243 
    244         synchronized (mStateMonitor) {
    245             mRUIMReadyRegistrants.add(r);
    246 
    247             if (mRuimState.isRUIMReady()) {
    248                 r.notifyRegistrant(new AsyncResult(null, null, null));
    249             }
    250         }
    251     }
    252 
    253     public void unregisterForRUIMReady(Handler h) {
    254         synchronized(mStateMonitor) {
    255             mRUIMReadyRegistrants.remove(h);
    256         }
    257     }
    258 
    259     /** Any transition into NV_READY */
    260     public void registerForNVReady(Handler h, int what, Object obj) {
    261         Registrant r = new Registrant (h, what, obj);
    262 
    263         synchronized (mStateMonitor) {
    264             mNVReadyRegistrants.add(r);
    265 
    266             if (mNvState.isNVReady()) {
    267                 r.notifyRegistrant(new AsyncResult(null, null, null));
    268             }
    269         }
    270     }
    271 
    272     public void unregisterForNVReady(Handler h) {
    273         synchronized (mStateMonitor) {
    274             mNVReadyRegistrants.remove(h);
    275         }
    276     }
    277 
    278     public void registerForSIMLockedOrAbsent(Handler h, int what, Object obj) {
    279         Registrant r = new Registrant (h, what, obj);
    280 
    281         synchronized (mStateMonitor) {
    282             mSIMLockedRegistrants.add(r);
    283 
    284             if (mSimState == RadioState.SIM_LOCKED_OR_ABSENT) {
    285                 r.notifyRegistrant(new AsyncResult(null, null, null));
    286             }
    287         }
    288     }
    289 
    290     public void unregisterForSIMLockedOrAbsent(Handler h) {
    291         synchronized (mStateMonitor) {
    292             mSIMLockedRegistrants.remove(h);
    293         }
    294     }
    295 
    296     public void registerForRUIMLockedOrAbsent(Handler h, int what, Object obj) {
    297         Registrant r = new Registrant (h, what, obj);
    298 
    299         synchronized (mStateMonitor) {
    300             mRUIMLockedRegistrants.add(r);
    301 
    302             if (mRuimState == RadioState.RUIM_LOCKED_OR_ABSENT) {
    303                 r.notifyRegistrant(new AsyncResult(null, null, null));
    304             }
    305         }
    306     }
    307 
    308     public void unregisterForRUIMLockedOrAbsent(Handler h) {
    309         synchronized (mStateMonitor) {
    310             mRUIMLockedRegistrants.remove(h);
    311         }
    312     }
    313 
    314     public void registerForCallStateChanged(Handler h, int what, Object obj) {
    315         Registrant r = new Registrant (h, what, obj);
    316 
    317         mCallStateRegistrants.add(r);
    318     }
    319 
    320     public void unregisterForCallStateChanged(Handler h) {
    321         mCallStateRegistrants.remove(h);
    322     }
    323 
    324     public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
    325         Registrant r = new Registrant (h, what, obj);
    326 
    327         mVoiceNetworkStateRegistrants.add(r);
    328     }
    329 
    330     public void unregisterForVoiceNetworkStateChanged(Handler h) {
    331         mVoiceNetworkStateRegistrants.remove(h);
    332     }
    333 
    334     public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
    335         Registrant r = new Registrant (h, what, obj);
    336 
    337         mDataNetworkStateRegistrants.add(r);
    338     }
    339 
    340     public void unregisterForDataNetworkStateChanged(Handler h) {
    341         mDataNetworkStateRegistrants.remove(h);
    342     }
    343 
    344     public void registerForRadioTechnologyChanged(Handler h, int what, Object obj) {
    345         Registrant r = new Registrant (h, what, obj);
    346         mRadioTechnologyChangedRegistrants.add(r);
    347     }
    348 
    349     public void unregisterForRadioTechnologyChanged(Handler h) {
    350         mRadioTechnologyChangedRegistrants.remove(h);
    351     }
    352 
    353     public void registerForIccStatusChanged(Handler h, int what, Object obj) {
    354         Registrant r = new Registrant (h, what, obj);
    355         mIccStatusChangedRegistrants.add(r);
    356     }
    357 
    358     public void unregisterForIccStatusChanged(Handler h) {
    359         mIccStatusChangedRegistrants.remove(h);
    360     }
    361 
    362     public void setOnNewGsmSms(Handler h, int what, Object obj) {
    363         mGsmSmsRegistrant = new Registrant (h, what, obj);
    364     }
    365 
    366     public void unSetOnNewGsmSms(Handler h) {
    367         mGsmSmsRegistrant.clear();
    368     }
    369 
    370     public void setOnNewCdmaSms(Handler h, int what, Object obj) {
    371         mCdmaSmsRegistrant = new Registrant (h, what, obj);
    372     }
    373 
    374     public void unSetOnNewCdmaSms(Handler h) {
    375         mCdmaSmsRegistrant.clear();
    376     }
    377 
    378     public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
    379         mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
    380     }
    381 
    382     public void unSetOnNewGsmBroadcastSms(Handler h) {
    383         mGsmBroadcastSmsRegistrant.clear();
    384     }
    385 
    386     public void setOnSmsOnSim(Handler h, int what, Object obj) {
    387         mSmsOnSimRegistrant = new Registrant (h, what, obj);
    388     }
    389 
    390     public void unSetOnSmsOnSim(Handler h) {
    391         mSmsOnSimRegistrant.clear();
    392     }
    393 
    394     public void setOnSmsStatus(Handler h, int what, Object obj) {
    395         mSmsStatusRegistrant = new Registrant (h, what, obj);
    396     }
    397 
    398     public void unSetOnSmsStatus(Handler h) {
    399         mSmsStatusRegistrant.clear();
    400     }
    401 
    402     public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
    403         mSignalStrengthRegistrant = new Registrant (h, what, obj);
    404     }
    405 
    406     public void unSetOnSignalStrengthUpdate(Handler h) {
    407         mSignalStrengthRegistrant.clear();
    408     }
    409 
    410     public void setOnNITZTime(Handler h, int what, Object obj) {
    411         mNITZTimeRegistrant = new Registrant (h, what, obj);
    412     }
    413 
    414     public void unSetOnNITZTime(Handler h) {
    415         mNITZTimeRegistrant.clear();
    416     }
    417 
    418     public void setOnUSSD(Handler h, int what, Object obj) {
    419         mUSSDRegistrant = new Registrant (h, what, obj);
    420     }
    421 
    422     public void unSetOnUSSD(Handler h) {
    423         mUSSDRegistrant.clear();
    424     }
    425 
    426     public void setOnSuppServiceNotification(Handler h, int what, Object obj) {
    427         mSsnRegistrant = new Registrant (h, what, obj);
    428     }
    429 
    430     public void unSetOnSuppServiceNotification(Handler h) {
    431         mSsnRegistrant.clear();
    432     }
    433 
    434     public void setOnCatSessionEnd(Handler h, int what, Object obj) {
    435         mCatSessionEndRegistrant = new Registrant (h, what, obj);
    436     }
    437 
    438     public void unSetOnCatSessionEnd(Handler h) {
    439         mCatSessionEndRegistrant.clear();
    440     }
    441 
    442     public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
    443         mCatProCmdRegistrant = new Registrant (h, what, obj);
    444     }
    445 
    446     public void unSetOnCatProactiveCmd(Handler h) {
    447         mCatProCmdRegistrant.clear();
    448     }
    449 
    450     public void setOnCatEvent(Handler h, int what, Object obj) {
    451         mCatEventRegistrant = new Registrant (h, what, obj);
    452     }
    453 
    454     public void unSetOnCatEvent(Handler h) {
    455         mCatEventRegistrant.clear();
    456     }
    457 
    458     public void setOnCatCallSetUp(Handler h, int what, Object obj) {
    459         mCatCallSetUpRegistrant = new Registrant (h, what, obj);
    460     }
    461 
    462     public void unSetOnCatCallSetUp(Handler h) {
    463         mCatCallSetUpRegistrant.clear();
    464     }
    465 
    466     public void setOnIccSmsFull(Handler h, int what, Object obj) {
    467         mIccSmsFullRegistrant = new Registrant (h, what, obj);
    468     }
    469 
    470     public void unSetOnIccSmsFull(Handler h) {
    471         mIccSmsFullRegistrant.clear();
    472     }
    473 
    474     public void registerForIccRefresh(Handler h, int what, Object obj) {
    475         Registrant r = new Registrant (h, what, obj);
    476         mIccRefreshRegistrants.add(r);
    477     }
    478     public void setOnIccRefresh(Handler h, int what, Object obj) {
    479         registerForIccRefresh(h, what, obj);
    480     }
    481 
    482     public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
    483         mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
    484     }
    485 
    486     public void unregisterForIccRefresh(Handler h) {
    487         mIccRefreshRegistrants.remove(h);
    488     }
    489     public void unsetOnIccRefresh(Handler h) {
    490         unregisterForIccRefresh(h);
    491     }
    492 
    493     public void setOnCallRing(Handler h, int what, Object obj) {
    494         mRingRegistrant = new Registrant (h, what, obj);
    495     }
    496 
    497     public void unSetOnCallRing(Handler h) {
    498         mRingRegistrant.clear();
    499     }
    500 
    501     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj) {
    502         Registrant r = new Registrant (h, what, obj);
    503         mVoicePrivacyOnRegistrants.add(r);
    504     }
    505 
    506     public void unregisterForInCallVoicePrivacyOn(Handler h){
    507         mVoicePrivacyOnRegistrants.remove(h);
    508     }
    509 
    510     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj) {
    511         Registrant r = new Registrant (h, what, obj);
    512         mVoicePrivacyOffRegistrants.add(r);
    513     }
    514 
    515     public void unregisterForInCallVoicePrivacyOff(Handler h){
    516         mVoicePrivacyOffRegistrants.remove(h);
    517     }
    518 
    519     public void setOnRestrictedStateChanged(Handler h, int what, Object obj) {
    520         mRestrictedStateRegistrant = new Registrant (h, what, obj);
    521     }
    522 
    523     public void unSetOnRestrictedStateChanged(Handler h) {
    524         mRestrictedStateRegistrant.clear();
    525     }
    526 
    527     public void registerForDisplayInfo(Handler h, int what, Object obj) {
    528         Registrant r = new Registrant (h, what, obj);
    529         mDisplayInfoRegistrants.add(r);
    530     }
    531 
    532     public void unregisterForDisplayInfo(Handler h) {
    533         mDisplayInfoRegistrants.remove(h);
    534     }
    535 
    536     public void registerForCallWaitingInfo(Handler h, int what, Object obj) {
    537         Registrant r = new Registrant (h, what, obj);
    538         mCallWaitingInfoRegistrants.add(r);
    539     }
    540 
    541     public void unregisterForCallWaitingInfo(Handler h) {
    542         mCallWaitingInfoRegistrants.remove(h);
    543     }
    544 
    545     public void registerForSignalInfo(Handler h, int what, Object obj) {
    546         Registrant r = new Registrant (h, what, obj);
    547         mSignalInfoRegistrants.add(r);
    548     }
    549 
    550     public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) {
    551         mUnsolOemHookRawRegistrant = new Registrant (h, what, obj);
    552     }
    553 
    554     public void unSetOnUnsolOemHookRaw(Handler h) {
    555         mUnsolOemHookRawRegistrant.clear();
    556     }
    557 
    558     public void unregisterForSignalInfo(Handler h) {
    559         mSignalInfoRegistrants.remove(h);
    560     }
    561 
    562     public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
    563         Registrant r = new Registrant (h, what, obj);
    564         mOtaProvisionRegistrants.add(r);
    565     }
    566 
    567     public void unregisterForCdmaOtaProvision(Handler h){
    568         mOtaProvisionRegistrants.remove(h);
    569     }
    570 
    571     public void registerForNumberInfo(Handler h,int what, Object obj) {
    572         Registrant r = new Registrant (h, what, obj);
    573         mNumberInfoRegistrants.add(r);
    574     }
    575 
    576     public void unregisterForNumberInfo(Handler h){
    577         mNumberInfoRegistrants.remove(h);
    578     }
    579 
    580      public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
    581         Registrant r = new Registrant (h, what, obj);
    582         mRedirNumInfoRegistrants.add(r);
    583     }
    584 
    585     public void unregisterForRedirectedNumberInfo(Handler h) {
    586         mRedirNumInfoRegistrants.remove(h);
    587     }
    588 
    589     public void registerForLineControlInfo(Handler h, int what, Object obj) {
    590         Registrant r = new Registrant (h, what, obj);
    591         mLineControlInfoRegistrants.add(r);
    592     }
    593 
    594     public void unregisterForLineControlInfo(Handler h) {
    595         mLineControlInfoRegistrants.remove(h);
    596     }
    597 
    598     public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
    599         Registrant r = new Registrant (h, what, obj);
    600         mT53ClirInfoRegistrants.add(r);
    601     }
    602 
    603     public void unregisterForT53ClirInfo(Handler h) {
    604         mT53ClirInfoRegistrants.remove(h);
    605     }
    606 
    607     public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
    608         Registrant r = new Registrant (h, what, obj);
    609         mT53AudCntrlInfoRegistrants.add(r);
    610     }
    611 
    612     public void unregisterForT53AudioControlInfo(Handler h) {
    613         mT53AudCntrlInfoRegistrants.remove(h);
    614     }
    615 
    616     public void registerForRingbackTone(Handler h, int what, Object obj) {
    617         Registrant r = new Registrant (h, what, obj);
    618         mRingbackToneRegistrants.add(r);
    619     }
    620 
    621     public void unregisterForRingbackTone(Handler h) {
    622         mRingbackToneRegistrants.remove(h);
    623     }
    624 
    625     public void registerForResendIncallMute(Handler h, int what, Object obj) {
    626         Registrant r = new Registrant (h, what, obj);
    627         mResendIncallMuteRegistrants.add(r);
    628     }
    629 
    630     public void unregisterForResendIncallMute(Handler h) {
    631         mResendIncallMuteRegistrants.remove(h);
    632     }
    633 
    634     @Override
    635     public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
    636         Registrant r = new Registrant (h, what, obj);
    637         mCdmaSubscriptionChangedRegistrants.add(r);
    638     }
    639 
    640     @Override
    641     public void unregisterForCdmaSubscriptionChanged(Handler h) {
    642         mCdmaSubscriptionChangedRegistrants.remove(h);
    643     }
    644 
    645     @Override
    646     public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
    647         Registrant r = new Registrant (h, what, obj);
    648         mCdmaPrlChangedRegistrants.add(r);
    649     }
    650 
    651     @Override
    652     public void unregisterForCdmaPrlChanged(Handler h) {
    653         mCdmaPrlChangedRegistrants.remove(h);
    654     }
    655 
    656     @Override
    657     public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
    658         Registrant r = new Registrant (h, what, obj);
    659         mExitEmergencyCallbackModeRegistrants.add(r);
    660     }
    661 
    662     @Override
    663     public void unregisterForExitEmergencyCallbackMode(Handler h) {
    664         mExitEmergencyCallbackModeRegistrants.remove(h);
    665     }
    666 
    667     /**
    668      * {@inheritDoc}
    669      */
    670     @Override
    671     public void registerForRilConnected(Handler h, int what, Object obj) {
    672         Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
    673         Registrant r = new Registrant (h, what, obj);
    674         mRilConnectedRegistrants.add(r);
    675         if (mRilVersion != -1) {
    676             Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
    677             r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null));
    678         }
    679     }
    680 
    681     @Override
    682     public void unregisterForRilConnected(Handler h) {
    683         mRilConnectedRegistrants.remove(h);
    684     }
    685 
    686     /**
    687      * {@inheritDoc}
    688      */
    689     @Override
    690     public void setCurrentPreferredNetworkType() {
    691     }
    692 
    693     //***** Protected Methods
    694     /**
    695      * Store new RadioState and send notification based on the changes
    696      *
    697      * This function is called only by RIL.java when receiving unsolicited
    698      * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
    699      *
    700      * RadioState has 5 values : RADIO_OFF, RADIO_UNAVAILABLE, SIM_NOT_READY,
    701      * SIM_LOCKED_OR_ABSENT, and SIM_READY.
    702      *
    703      * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
    704      */
    705     protected void setRadioState(RadioState newState) {
    706         RadioState oldState;
    707 
    708         synchronized (mStateMonitor) {
    709             if (false) {
    710                 Log.v(LOG_TAG, "setRadioState old: " + mState
    711                     + " new " + newState);
    712             }
    713 
    714             oldState = mState;
    715             mState = newState;
    716 
    717             if (oldState == mState) {
    718                 // no state transition
    719                 return;
    720             }
    721 
    722             // FIXME: Use Constants or Enums
    723             if(mState.getType() == 0) {
    724                 mSimState = mState;
    725                 mRuimState = mState;
    726                 mNvState = mState;
    727             }
    728             else if (mState.getType() == 1) {
    729                 mSimState = mState;
    730             }
    731             else if (mState.getType() == 2) {
    732                 mRuimState = mState;
    733             }
    734             else if (mState.getType() == 3) {
    735                 mNvState = mState;
    736             }
    737 
    738             mRadioStateChangedRegistrants.notifyRegistrants();
    739 
    740             if (mState.isAvailable() && !oldState.isAvailable()) {
    741                 Log.d(LOG_TAG,"Notifying: radio available");
    742                 mAvailRegistrants.notifyRegistrants();
    743                 onRadioAvailable();
    744             }
    745 
    746             if (!mState.isAvailable() && oldState.isAvailable()) {
    747                 Log.d(LOG_TAG,"Notifying: radio not available");
    748                 mNotAvailRegistrants.notifyRegistrants();
    749             }
    750 
    751             if (mState.isSIMReady() && !oldState.isSIMReady()) {
    752                 Log.d(LOG_TAG,"Notifying: SIM ready");
    753                 mSIMReadyRegistrants.notifyRegistrants();
    754             }
    755 
    756             if (mState == RadioState.SIM_LOCKED_OR_ABSENT) {
    757                 Log.d(LOG_TAG,"Notifying: SIM locked or absent");
    758                 mSIMLockedRegistrants.notifyRegistrants();
    759             }
    760 
    761             if (mState.isRUIMReady() && !oldState.isRUIMReady()) {
    762                 Log.d(LOG_TAG,"Notifying: RUIM ready");
    763                 mRUIMReadyRegistrants.notifyRegistrants();
    764             }
    765 
    766             if (mState == RadioState.RUIM_LOCKED_OR_ABSENT) {
    767                 Log.d(LOG_TAG,"Notifying: RUIM locked or absent");
    768                 mRUIMLockedRegistrants.notifyRegistrants();
    769             }
    770             if (mState.isNVReady() && !oldState.isNVReady()) {
    771                 Log.d(LOG_TAG,"Notifying: NV ready");
    772                 mNVReadyRegistrants.notifyRegistrants();
    773             }
    774 
    775             if (mState.isOn() && !oldState.isOn()) {
    776                 Log.d(LOG_TAG,"Notifying: Radio On");
    777                 mOnRegistrants.notifyRegistrants();
    778             }
    779 
    780             if ((!mState.isOn() || !mState.isAvailable())
    781                 && !((!oldState.isOn() || !oldState.isAvailable()))
    782             ) {
    783                 Log.d(LOG_TAG,"Notifying: radio off or not available");
    784                 mOffOrNotAvailRegistrants.notifyRegistrants();
    785             }
    786 
    787             /* Radio Technology Change events
    788              * NOTE: isGsm and isCdma have no common states in RADIO_OFF or RADIO_UNAVAILABLE; the
    789              *   current phone is determined by mPhoneType
    790              * NOTE: at startup no phone have been created and the RIL determines the mPhoneType
    791              *   looking based on the networkMode set by the PhoneFactory in the constructor
    792              */
    793 
    794             if (mState.isGsm() && oldState.isCdma()) {
    795                 Log.d(LOG_TAG,"Notifying: radio technology change CDMA to GSM");
    796                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
    797             }
    798 
    799             if (mState.isGsm() && !oldState.isOn() && (mPhoneType == Phone.PHONE_TYPE_CDMA)) {
    800                 Log.d(LOG_TAG,"Notifying: radio technology change CDMA OFF to GSM");
    801                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
    802             }
    803 
    804             if (mState.isCdma() && oldState.isGsm()) {
    805                 Log.d(LOG_TAG,"Notifying: radio technology change GSM to CDMA");
    806                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
    807             }
    808 
    809             if (mState.isCdma() && !oldState.isOn() && (mPhoneType == Phone.PHONE_TYPE_GSM)) {
    810                 Log.d(LOG_TAG,"Notifying: radio technology change GSM OFF to CDMA");
    811                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
    812             }
    813         }
    814     }
    815 
    816     protected void onRadioAvailable() {
    817     }
    818 
    819     /**
    820      * The contents of the /proc/cmdline file
    821      */
    822     private static String getProcCmdLine()
    823     {
    824         String cmdline = "";
    825         FileInputStream is = null;
    826         try {
    827             is = new FileInputStream("/proc/cmdline");
    828             byte [] buffer = new byte[2048];
    829             int count = is.read(buffer);
    830             if (count > 0) {
    831                 cmdline = new String(buffer, 0, count);
    832             }
    833         } catch (IOException e) {
    834             Log.d(LOG_TAG, "No /proc/cmdline exception=" + e);
    835         } finally {
    836             if (is != null) {
    837                 try {
    838                     is.close();
    839                 } catch (IOException e) {
    840                 }
    841             }
    842         }
    843         Log.d(LOG_TAG, "/proc/cmdline=" + cmdline);
    844         return cmdline;
    845     }
    846 
    847     /**
    848      * {@inheritDoc}
    849      */
    850     @Override
    851     public int getLteOnCdmaMode() {
    852         return getLteOnCdmaModeStatic();
    853     }
    854 
    855     /** Kernel command line */
    856     private static final String sKernelCmdLine = getProcCmdLine();
    857 
    858     /** Pattern for selecting the product type from the kernel command line */
    859     private static final Pattern sProductTypePattern =
    860         Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
    861 
    862     /** The ProductType used for LTE on CDMA devices */
    863     private static final String sLteOnCdmaProductType =
    864         SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
    865 
    866     /**
    867      * Return if the current radio is LTE on CDMA. This
    868      * is a tri-state return value as for a period of time
    869      * the mode may be unknown.
    870      *
    871      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
    872      * or {@link Phone#LTE_ON_CDMA_TRUE}
    873      */
    874     public static int getLteOnCdmaModeStatic() {
    875         int retVal;
    876         int curVal;
    877         String productType = "";
    878 
    879         curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
    880                     Phone.LTE_ON_CDMA_UNKNOWN);
    881         retVal = curVal;
    882         if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) {
    883             Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
    884             if (matcher.find()) {
    885                 productType = matcher.group(1);
    886                 if (sLteOnCdmaProductType.equals(productType)) {
    887                     retVal = Phone.LTE_ON_CDMA_TRUE;
    888                 } else {
    889                     retVal = Phone.LTE_ON_CDMA_FALSE;
    890                 }
    891             } else {
    892                 retVal = Phone.LTE_ON_CDMA_FALSE;
    893             }
    894         }
    895 
    896         Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
    897                 " product_type='" + productType +
    898                 "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
    899         return retVal;
    900     }
    901 }
    902