CDMAPhone.java revision d6c5d527d3fa73dafc6e7cd36e4d6922b6d31845
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
17package com.android.internal.telephony.cdma;
18
19import android.content.Context;
20import android.os.AsyncResult;
21import android.os.Handler;
22import android.os.Looper;
23import android.os.Message;
24import android.os.Registrant;
25import android.os.RegistrantList;
26import android.os.SystemProperties;
27import android.provider.Settings;
28import android.telephony.CellLocation;
29import android.telephony.PhoneNumberUtils;
30import android.telephony.ServiceState;
31import android.text.TextUtils;
32import android.util.Log;
33
34import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
35
36import com.android.internal.telephony.CallStateException;
37import com.android.internal.telephony.CommandsInterface;
38import com.android.internal.telephony.Connection;
39import com.android.internal.telephony.DataConnection;
40import com.android.internal.telephony.IccCard;
41import com.android.internal.telephony.IccFileHandler;
42import com.android.internal.telephony.IccPhoneBookInterfaceManager;
43import com.android.internal.telephony.IccSmsInterfaceManager;
44import com.android.internal.telephony.MmiCode;
45import com.android.internal.telephony.Phone;
46import com.android.internal.telephony.PhoneBase;
47import com.android.internal.telephony.PhoneNotifier;
48import com.android.internal.telephony.PhoneProxy;
49import com.android.internal.telephony.PhoneSubInfo;
50import com.android.internal.telephony.RILConstants;
51
52import java.util.ArrayList;
53import java.util.List;
54
55/**
56 * {@hide}
57 */
58public class CDMAPhone extends PhoneBase {
59    static final String LOG_TAG = "CDMA";
60    private static final boolean LOCAL_DEBUG = true;
61
62    //***** Instance Variables
63    CdmaCallTracker mCT;
64    CdmaSMSDispatcher mSMS;
65    CdmaServiceStateTracker mSST;
66    CdmaDataConnectionTracker mDataConnection;
67    RuimFileHandler mRuimFileHandler;
68    RuimRecords mRuimRecords;
69    RuimCard mRuimCard;
70    MyHandler h;
71    RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager;
72    RuimSmsInterfaceManager mRuimSmsInterfaceManager;
73    PhoneSubInfo mSubInfo;
74
75    protected RegistrantList mNvLoadedRegistrants = new RegistrantList();
76    private String mEsn;
77    private String mMeid;
78
79    Registrant mPostDialHandler;
80
81
82    //***** Constructors
83    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
84        this(context,ci,notifier, false);
85    }
86
87    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
88            boolean unitTestMode) {
89        super(notifier, context, unitTestMode);
90
91        h = new MyHandler();
92        mCM = ci;
93
94        mCM.setPhoneType(RILConstants.CDMA_PHONE);
95        mCT = new CdmaCallTracker(this);
96        mSST = new CdmaServiceStateTracker (this);
97        mSMS = new CdmaSMSDispatcher(this);
98        mIccFileHandler = new RuimFileHandler(this);
99        mRuimRecords = new RuimRecords(this);
100        mDataConnection = new CdmaDataConnectionTracker (this);
101        mRuimCard = new RuimCard(this);
102        mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this);
103        mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this);
104        mSubInfo = new PhoneSubInfo(this);
105
106        mCM.registerForAvailable(h, EVENT_RADIO_AVAILABLE, null);
107        mRuimRecords.registerForRecordsLoaded(h, EVENT_RUIM_RECORDS_LOADED, null);
108        mCM.registerForOffOrNotAvailable(h, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
109        mCM.registerForOn(h, EVENT_RADIO_ON, null);
110        mCM.setOnSuppServiceNotification(h, EVENT_SSN, null);
111        mCM.setOnCallRing(h, EVENT_CALL_RING, null);
112        mSST.registerForNetworkAttach(h, EVENT_REGISTERED_TO_NETWORK, null);
113        mCM.registerForNVReady(h, EVENT_NV_READY, null);
114
115        //Change the system setting
116        Settings.Secure.putInt(mContext.getContentResolver(),
117                Settings.Secure.CURRENT_ACTIVE_PHONE, RILConstants.CDMA_PHONE);
118    }
119
120    public void dispose() {
121        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
122
123            //Unregister from all former registered events
124            mRuimRecords.unregisterForRecordsLoaded(h); //EVENT_RUIM_RECORDS_LOADED
125            mCM.unregisterForAvailable(h); //EVENT_RADIO_AVAILABLE
126            mCM.unregisterForOffOrNotAvailable(h); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
127            mCM.unregisterForOn(h); //EVENT_RADIO_ON
128            mCM.unregisterForNVReady(h); //EVENT_NV_READY
129            mSST.unregisterForNetworkAttach(h); //EVENT_REGISTERED_TO_NETWORK
130            mCM.unSetOnSuppServiceNotification(h);
131            mCM.unSetOnCallRing(h);
132
133            //Force all referenced classes to unregister their former registered events
134            mCT.dispose();
135            mDataConnection.dispose();
136            mSST.dispose();
137            mSMS.dispose();
138            mIccFileHandler.dispose(); // instance of RuimFileHandler
139            mRuimRecords.dispose();
140            mRuimCard.dispose();
141            mRuimPhoneBookInterfaceManager.dispose();
142            mRuimSmsInterfaceManager.dispose();
143            mSubInfo.dispose();
144        }
145    }
146
147    public void removeReferences() {
148            this.mRuimPhoneBookInterfaceManager = null;
149            this.mRuimSmsInterfaceManager = null;
150            this.mSMS = null;
151            this.mSubInfo = null;
152            this.mRuimRecords = null;
153            this.mIccFileHandler = null;
154            this.mRuimCard = null;
155            this.mDataConnection = null;
156            this.mCT = null;
157            this.mSST = null;
158    }
159
160    protected void finalize() {
161        if(LOCAL_DEBUG) Log.d(LOG_TAG, "CDMAPhone finalized");
162    }
163
164
165    //***** Overridden from Phone
166    public ServiceState getServiceState() {
167        return mSST.ss;
168    }
169
170    public Phone.State
171    getState() {
172        return mCT.state;
173    }
174
175    public String
176    getPhoneName() {
177        return "CDMA";
178    }
179
180    public boolean canTransfer() {
181        Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
182        return false;
183    }
184
185    public CdmaCall
186    getRingingCall() {
187        return mCT.ringingCall;
188    }
189
190    public void setMute(boolean muted) {
191        mCT.setMute(muted);
192    }
193
194    public boolean getMute() {
195        return mCT.getMute();
196    }
197
198    public void conference() throws CallStateException {
199        // three way calls in CDMA will be handled by feature codes
200        Log.e(LOG_TAG, "conference: not possible in CDMA");
201    }
202
203    public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
204        this.mCM.setPreferredVoicePrivacy(enable, onComplete);
205    }
206
207    public void getEnhancedVoicePrivacy(Message onComplete) {
208        this.mCM.getPreferredVoicePrivacy(onComplete);
209    }
210
211    public void clearDisconnected() {
212        mCT.clearDisconnected();
213    }
214
215    public DataActivityState getDataActivityState() {
216        DataActivityState ret = DataActivityState.NONE;
217
218        if (mSST.getCurrentCdmaDataConnectionState() != ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
219
220            switch (mDataConnection.getActivity()) {
221                case DATAIN:
222                    ret = DataActivityState.DATAIN;
223                break;
224
225                case DATAOUT:
226                    ret = DataActivityState.DATAOUT;
227                break;
228
229                case DATAINANDOUT:
230                    ret = DataActivityState.DATAINANDOUT;
231                break;
232            }
233        }
234        return ret;
235    }
236
237    /*package*/ void
238    notifySignalStrength() {
239        mNotifier.notifySignalStrength(this);
240    }
241
242    public Connection
243    dial (String dialString) throws CallStateException {
244        // Need to make sure dialString gets parsed properly
245        String newDialString = PhoneNumberUtils.stripSeparators(dialString);
246
247        if (!mCT.foregroundCall.isIdle()) {
248            FeatureCode fc = FeatureCode.newFromDialString(newDialString, this);
249            if (fc != null) {
250                //mMmiRegistrants.notifyRegistrants(new AsyncResult(null, fc, null));
251                fc.processCode();
252            } else {
253                FeatureCode digits = new FeatureCode(this);
254                // use dial number as poundString
255                digits.poundString = newDialString;
256                digits.processCode();
257            }
258            return null;
259        } else {
260            return mCT.dial(newDialString);
261        }
262    }
263
264
265    public int getSignalStrengthASU() {
266        return mSST.rssi == 99 ? -1 : mSST.rssi;
267    }
268
269    public boolean
270    getMessageWaitingIndicator() {
271        return mRuimRecords.getVoiceMessageWaiting();
272    }
273
274    public List<? extends MmiCode>
275    getPendingMmiCodes() {
276        Log.e(LOG_TAG, "method getPendingMmiCodes is NOT supported in CDMA!");
277        return null;
278    }
279
280    public void registerForSuppServiceNotification(
281            Handler h, int what, Object obj) {
282        Log.e(LOG_TAG, "method registerForSuppServiceNotification is NOT supported in CDMA!");
283    }
284
285    public CdmaCall getBackgroundCall() {
286        return mCT.backgroundCall;
287    }
288
289    public String getGateway(String apnType) {
290        return mDataConnection.getGateway();
291    }
292
293    public boolean handleInCallMmiCommands(String dialString) {
294        Log.e(LOG_TAG, "method handleInCallMmiCommands is NOT supported in CDMA!");
295        return false;
296    }
297
298    public int enableApnType(String type) {
299        // This request is mainly used to enable MMS APN
300        // In CDMA there is no need to enable/disable a different APN for MMS
301        Log.d(LOG_TAG, "Request to enableApnType("+type+")");
302        if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
303            return Phone.APN_ALREADY_ACTIVE;
304        } else {
305            return Phone.APN_REQUEST_FAILED;
306        }
307    }
308
309    public int disableApnType(String type) {
310        // This request is mainly used to disable MMS APN
311        // In CDMA there is no need to enable/disable a different APN for MMS
312        Log.d(LOG_TAG, "Request to disableApnType("+type+")");
313        if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
314            return Phone.APN_REQUEST_STARTED;
315        } else {
316            return Phone.APN_REQUEST_FAILED;
317        }
318    }
319
320    public String getActiveApn() {
321        Log.d(LOG_TAG, "Request to getActiveApn()");
322        return null;
323    }
324
325    public void
326    setNetworkSelectionModeAutomatic(Message response) {
327        Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!");
328    }
329
330    public void unregisterForSuppServiceNotification(Handler h) {
331        Log.e(LOG_TAG, "method unregisterForSuppServiceNotification is NOT supported in CDMA!");
332    }
333
334    public void
335    acceptCall() throws CallStateException {
336        mCT.acceptCall();
337    }
338
339    public void
340    rejectCall() throws CallStateException {
341        mCT.rejectCall();
342    }
343
344    public void
345    switchHoldingAndActive() throws CallStateException {
346        mCT.switchWaitingOrHoldingAndActive();
347    }
348
349    public String getLine1Number() {
350        return mRuimRecords.getMdnNumber();
351    }
352
353    public void getCallWaiting(Message onComplete) {
354        mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
355    }
356
357    public void
358    setRadioPower(boolean power) {
359        mSST.setRadioPower(power);
360    }
361
362    public String getEsn() {
363        return mEsn;
364    }
365
366    public String getMeid() {
367        return mMeid;
368    }
369
370    //returns MEID in CDMA
371    public String getDeviceId() {
372        return getMeid();
373    }
374
375    public String getDeviceSvn() {
376        Log.d(LOG_TAG, "getDeviceSvn(): return 0");
377        return "0";
378    }
379
380    public String getSubscriberId() {
381        Log.e(LOG_TAG, "method getSubscriberId for IMSI is NOT supported in CDMA!");
382        return null;
383    }
384
385    public boolean canConference() {
386        Log.e(LOG_TAG, "canConference: not possible in CDMA");
387        return false;
388    }
389
390    public String getInterfaceName(String apnType) {
391        return mDataConnection.getInterfaceName();
392    }
393
394    public CellLocation getCellLocation() {
395        return mSST.cellLoc;
396    }
397
398    public boolean disableDataConnectivity() {
399        return mDataConnection.setDataEnabled(false);
400    }
401
402    public CdmaCall getForegroundCall() {
403        return mCT.foregroundCall;
404    }
405
406    public void
407    selectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo network,
408            Message response) {
409        Log.e(LOG_TAG, "selectNetworkManually: not possible in CDMA");
410    }
411
412    public void setOnPostDialCharacter(Handler h, int what, Object obj) {
413        Log.e(LOG_TAG, "setOnPostDialCharacter: not possible in CDMA");
414    }
415
416    public boolean handlePinMmi(String dialString) {
417        Log.e(LOG_TAG, "method handlePinMmi is NOT supported in CDMA!");
418        return false;
419    }
420
421    public boolean isDataConnectivityPossible() {
422        boolean noData = mDataConnection.getDataEnabled() &&
423                getDataConnectionState() == DataState.DISCONNECTED;
424        return !noData && getIccCard().getState() == IccCard.State.READY &&
425                getServiceState().getState() == ServiceState.STATE_IN_SERVICE &&
426                (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming());
427    }
428
429    public void setLine1Number(String alphaTag, String number, Message onComplete) {
430        Log.e(LOG_TAG, "setLine1Number: not possible in CDMA");
431    }
432
433    public String[] getDnsServers(String apnType) {
434        return mDataConnection.getDnsServers();
435    }
436
437    public IccCard getIccCard() {
438        return mRuimCard;
439    }
440
441    public String getIccSerialNumber() {
442        return mRuimRecords.iccid;
443    }
444
445    public void setCallWaiting(boolean enable, Message onComplete) {
446        Log.e(LOG_TAG, "method setCallWaiting is NOT supported in CDMA!");
447    }
448
449    public void updateServiceLocation(Message response) {
450        mSST.getLacAndCid(response);
451    }
452
453    public void setDataRoamingEnabled(boolean enable) {
454        mDataConnection.setDataOnRoamingEnabled(enable);
455    }
456
457    public String getIpAddress(String apnType) {
458        return mDataConnection.getIpAddress();
459    }
460
461    public void
462    getNeighboringCids(Message response) {
463        // WINK:TODO: implement after Cupcake merge
464        mCM.getNeighboringCids(response); // workaround.
465    }
466
467    public DataState getDataConnectionState() {
468        DataState ret = DataState.DISCONNECTED;
469
470        if ((SystemProperties.get("adb.connected", "").length() > 0)
471                && (SystemProperties.get("android.net.use-adb-networking", "")
472                        .length() > 0)) {
473            // We're connected to an ADB host and we have USB networking
474            // turned on. No matter what the radio state is,
475            // we report data connected
476
477            ret = DataState.CONNECTED;
478        } else if (mSST.getCurrentCdmaDataConnectionState()
479                == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
480            // If we're out of service, open TCP sockets may still work
481            // but no data will flow
482            ret = DataState.DISCONNECTED;
483        } else {
484            switch (mDataConnection.getState()) {
485                case FAILED:
486                case IDLE:
487                    ret = DataState.DISCONNECTED;
488                break;
489
490                case CONNECTED:
491                case DISCONNECTING:
492                    if ( mCT.state != Phone.State.IDLE
493                            && !mSST.isConcurrentVoiceAndData()) {
494                        ret = DataState.SUSPENDED;
495                    } else {
496                        ret = DataState.CONNECTED;
497                    }
498                break;
499
500                case INITING:
501                case CONNECTING:
502                case SCANNING:
503                    ret = DataState.CONNECTING;
504                break;
505            }
506        }
507
508        return ret;
509    }
510
511    public void sendUssdResponse(String ussdMessge) {
512        Log.e(LOG_TAG, "sendUssdResponse: not possible in CDMA");
513    }
514
515    public void sendDtmf(char c) {
516        if (!PhoneNumberUtils.is12Key(c)) {
517            Log.e(LOG_TAG,
518                    "sendDtmf called with invalid character '" + c + "'");
519        } else {
520            if (mCT.state ==  Phone.State.OFFHOOK) {
521                mCM.sendDtmf(c, null);
522            }
523        }
524    }
525
526    public void startDtmf(char c) {
527        if (!PhoneNumberUtils.is12Key(c)) {
528            Log.e(LOG_TAG,
529                    "startDtmf called with invalid character '" + c + "'");
530        } else {
531            mCM.startDtmf(c, null);
532        }
533    }
534
535    public void stopDtmf() {
536        mCM.stopDtmf(null);
537    }
538
539    public void getAvailableNetworks(Message response) {
540        Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
541    }
542
543    public String[] getActiveApnTypes() {
544        String[] result;
545        Log.d(LOG_TAG, "Request to getActiveApn()");
546        result = new String[1];
547        result[0] = Phone.APN_TYPE_DEFAULT;
548        return result;
549    }
550
551    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
552        Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
553    }
554
555    public void enableLocationUpdates() {
556        mSST.enableLocationUpdates();
557    }
558
559    /**
560     * @deprecated
561     */
562    public void getPdpContextList(Message response) {
563        getDataCallList(response);
564    }
565
566    public void getDataCallList(Message response) {
567        mCM.getDataCallList(response);
568    }
569
570    public boolean getDataRoamingEnabled() {
571        return mDataConnection.getDataOnRoamingEnabled();
572    }
573
574    public List<DataConnection> getCurrentDataConnectionList () {
575        return mDataConnection.getAllDataConnections();
576    }
577
578    public void setVoiceMailNumber(String alphaTag,
579                                   String voiceMailNumber,
580                                   Message onComplete) {
581        //mSIMRecords.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
582        //TODO: Where do we have to store this value has to be clarified with QC
583    }
584
585    public String getVoiceMailNumber() {
586        //TODO: Where can we get this value has to be clarified with QC
587        //return mSIMRecords.getVoiceMailNumber();
588//      throw new RuntimeException();
589        return "12345";
590    }
591
592    public String getVoiceMailAlphaTag() {
593        // TODO: Where can we get this value has to be clarified with QC.
594        String ret = "";//TODO: Remove = "", if we know where to get this value.
595
596        //ret = mSIMRecords.getVoiceMailAlphaTag();
597
598        if (ret == null || ret.length() == 0) {
599            return mContext.getText(
600                com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
601        }
602
603        return ret;
604    }
605
606    public boolean enableDataConnectivity() {
607        return mDataConnection.setDataEnabled(true);
608    }
609
610    public void disableLocationUpdates() {
611        mSST.disableLocationUpdates();
612    }
613
614    public boolean getIccRecordsLoaded() {
615        return mRuimRecords.getRecordsLoaded();
616    }
617
618    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
619        Log.e(LOG_TAG, "getCallForwardingOption: not possible in CDMA");
620    }
621
622    public void setCallForwardingOption(int commandInterfaceCFAction,
623            int commandInterfaceCFReason,
624            String dialingNumber,
625            int timerSeconds,
626            Message onComplete) {
627        Log.e(LOG_TAG, "setCallForwardingOption: not possible in CDMA");
628    }
629
630    public void
631    getOutgoingCallerIdDisplay(Message onComplete) {
632        Log.e(LOG_TAG, "getOutgoingCallerIdDisplay: not possible in CDMA");
633    }
634
635    public boolean
636    getCallForwardingIndicator() {
637        Log.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
638        return false;
639    }
640
641    public void explicitCallTransfer() {
642        Log.e(LOG_TAG, "explicitCallTransfer: not possible in CDMA");
643    }
644
645    public String getLine1AlphaTag() {
646        Log.e(LOG_TAG, "getLine1AlphaTag: not possible in CDMA");
647        return null;
648    }
649
650    /**
651     * Notify any interested party of a Phone state change.
652     */
653    /*package*/ void notifyPhoneStateChanged() {
654        mNotifier.notifyPhoneState(this);
655    }
656
657    /**
658     * Notifies registrants (ie, activities in the Phone app) about
659     * changes to call state (including Phone and Connection changes).
660     */
661    /*package*/ void notifyCallStateChanged() {
662        /* we'd love it if this was package-scoped*/
663        super.notifyCallStateChangedP();
664    }
665
666     void notifyServiceStateChanged(ServiceState ss) {
667         super.notifyServiceStateChangedP(ss);
668     }
669
670     void notifyLocationChanged() {
671         mNotifier.notifyCellLocation(this);
672     }
673
674    /*package*/ void notifyNewRingingConnection(Connection c) {
675        /* we'd love it if this was package-scoped*/
676        super.notifyNewRingingConnectionP(c);
677    }
678
679    /**
680     * Notifiy registrants of a RING event.
681     */
682    void notifyIncomingRing() {
683        AsyncResult ar = new AsyncResult(null, this, null);
684        mIncomingRingRegistrants.notifyRegistrants(ar);
685    }
686
687    /*package*/ void notifyDisconnect(Connection cn) {
688        mDisconnectRegistrants.notifyResult(cn);
689    }
690
691    void notifyUnknownConnection() {
692        mUnknownConnectionRegistrants.notifyResult(this);
693    }
694
695    /*package*/ void
696    updateMessageWaitingIndicator(boolean mwi) {
697        // this also calls notifyMessageWaitingIndicator()
698        mRuimRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
699    }
700
701    public void
702    notifyMessageWaitingIndicator() {
703        mNotifier.notifyMessageWaitingChanged(this);
704    }
705
706    /**
707     * Removes the given FC from the pending list and notifies
708     * registrants that it is complete.
709     * @param fc FC that is done
710     */
711    /*package*/ void onFeatureCodeDone(FeatureCode fc) {
712        /* Only notify complete if it's on the pending list.
713         * Otherwise, it's already been handled (eg, previously canceled).
714         * The exception is cancellation of an incoming USSD-REQUEST, which is
715         * not on the list.
716         */
717         mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, fc, null));
718    }
719
720    //***** Inner Classes
721    class MyHandler extends Handler {
722        MyHandler() {
723        }
724
725        MyHandler(Looper l) {
726            super(l);
727        }
728
729        public void handleMessage(Message msg) {
730            AsyncResult ar;
731            Message     onComplete;
732
733            switch(msg.what) {
734                case EVENT_RADIO_AVAILABLE: {
735                    mCM.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
736
737                    mCM.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
738                }
739                break;
740
741                case EVENT_GET_BASEBAND_VERSION_DONE:{
742                    ar = (AsyncResult)msg.obj;
743
744                    if (ar.exception != null) {
745                        break;
746                    }
747
748                    if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
749                    setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result);
750                }
751                break;
752
753                case EVENT_GET_DEVICE_IDENTITY_DONE:{
754                    ar = (AsyncResult)msg.obj;
755
756                    if (ar.exception != null) {
757                        break;
758                    }
759                    String[] respId = (String[])ar.result;
760                    mEsn  =  respId[2];
761                    mMeid =  respId[3];
762                }
763                break;
764
765                case EVENT_RUIM_RECORDS_LOADED:{
766                    Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received");
767                }
768                break;
769
770                case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:{
771                    Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received");
772                }
773                break;
774
775                case EVENT_RADIO_ON:{
776                    Log.d(LOG_TAG, "Event EVENT_RADIO_ON Received");
777                }
778                break;
779
780                case EVENT_SSN:{
781                    Log.d(LOG_TAG, "Event EVENT_SSN Received");
782                }
783                break;
784
785                case EVENT_CALL_RING:{
786                    Log.d(LOG_TAG, "Event EVENT_CALL_RING Received");
787                }
788                break;
789
790                case EVENT_REGISTERED_TO_NETWORK:{
791                    Log.d(LOG_TAG, "Event EVENT_REGISTERED_TO_NETWORK Received");
792                }
793                break;
794
795                case EVENT_NV_READY:{
796                    Log.d(LOG_TAG, "Event EVENT_NV_READY Received");
797                    //Inform the Service State Tracker
798                    mNvLoadedRegistrants.notifyRegistrants();
799                }
800                break;
801
802                default:{
803                    throw new RuntimeException("unexpected event not handled");
804                }
805            }
806        }
807    }
808
809     /**
810      * Retrieves the PhoneSubInfo of the CDMAPhone
811      */
812     public PhoneSubInfo getPhoneSubInfo(){
813        return mSubInfo;
814     }
815
816     /**
817      * Retrieves the IccSmsInterfaceManager of the CDMAPhone
818      */
819     public IccSmsInterfaceManager getIccSmsInterfaceManager(){
820         return mRuimSmsInterfaceManager;
821     }
822
823     /**
824      * Retrieves the IccPhoneBookInterfaceManager of the CDMAPhone
825      */
826     public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
827         return mRuimPhoneBookInterfaceManager;
828     }
829
830    public void registerForNvLoaded(Handler h, int what, Object obj) {
831        Registrant r = new Registrant (h, what, obj);
832        mNvLoadedRegistrants.add(r);
833    }
834
835    public void unregisterForNvLoaded(Handler h) {
836        mNvLoadedRegistrants.remove(h);
837    }
838
839     // override for allowing access from other classes of this package
840     /**
841      * {@inheritDoc}
842      */
843     public final void setSystemProperty(String property, String value) {
844         super.setSystemProperty(property, value);
845     }
846
847     /**
848      * {@inheritDoc}
849      */
850     public Handler getHandler(){
851         return h;
852     }
853
854     /**
855      * {@inheritDoc}
856      */
857     public IccFileHandler getIccFileHandler(){
858         return this.mIccFileHandler;
859     }
860
861     /**
862      * Set the TTY mode of the CDMAPhone
863      */
864     public void setTTYModeEnabled(boolean enable, Message onComplete) {
865         this.mCM.setTTYModeEnabled(enable, onComplete);
866}
867
868     /**
869      * Queries the TTY mode of the CDMAPhone
870      */
871     public void queryTTYModeEnabled(Message onComplete) {
872         this.mCM.queryTTYModeEnabled(onComplete);
873     }
874
875     /**
876      * Activate or deactivate cell broadcast SMS.
877      *
878      * @param activate
879      *            0 = activate, 1 = deactivate
880      * @param response
881      *            Callback message is empty on completion
882      */
883     public void activateCellBroadcastSms(int activate, Message response) {
884         mSMS.activateCellBroadcastSms(activate, response);
885     }
886
887     /**
888      * Query the current configuration of cdma cell broadcast SMS.
889      *
890      * @param response
891      *            Callback message is empty on completion
892      */
893     public void getCellBroadcastSmsConfig(Message response){
894         mSMS.getCellBroadcastSmsConfig(response);
895     }
896
897     /**
898      * Configure cdma cell broadcast SMS.
899      *
900      * @param response
901      *            Callback message is empty on completion
902      */
903     public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
904         mSMS.setCellBroadcastConfig(configValuesArray, response);
905     }
906}
907