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;
18
19
20import android.content.Context;
21import android.os.RegistrantList;
22import android.os.Registrant;
23import android.os.Handler;
24import android.os.AsyncResult;
25import android.os.SystemProperties;
26import android.util.Log;
27
28import java.io.FileInputStream;
29import java.io.IOException;
30import java.util.regex.Matcher;
31import java.util.regex.Pattern;
32
33/**
34 * {@hide}
35 */
36public 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