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