PhoneBase.java revision 5b81adc82a53b3064f4baa3acfeabef31586588a
1/*
2 * Copyright (C) 2007 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
19import android.app.ActivityManagerNative;
20import android.app.IActivityManager;
21import android.content.Context;
22import android.content.res.Configuration;
23import android.content.SharedPreferences;
24import android.net.LinkCapabilities;
25import android.net.LinkProperties;
26import android.net.wifi.WifiManager;
27import android.os.AsyncResult;
28import android.os.Handler;
29import android.os.Looper;
30import android.os.Message;
31import android.os.RegistrantList;
32import android.os.SystemProperties;
33import android.preference.PreferenceManager;
34import android.provider.Settings;
35import android.telephony.ServiceState;
36import android.text.TextUtils;
37import android.util.Log;
38
39import com.android.internal.R;
40import com.android.internal.telephony.gsm.UsimServiceTable;
41import com.android.internal.telephony.ims.IsimRecords;
42import com.android.internal.telephony.test.SimulatedRadioControl;
43import com.android.internal.telephony.gsm.SIMRecords;
44
45import java.io.FileDescriptor;
46import java.io.PrintWriter;
47import java.util.Locale;
48import java.util.concurrent.atomic.AtomicReference;
49
50
51/**
52 * (<em>Not for SDK use</em>)
53 * A base implementation for the com.android.internal.telephony.Phone interface.
54 *
55 * Note that implementations of Phone.java are expected to be used
56 * from a single application thread. This should be the same thread that
57 * originally called PhoneFactory to obtain the interface.
58 *
59 *  {@hide}
60 *
61 */
62
63public abstract class PhoneBase extends Handler implements Phone {
64    private static final String LOG_TAG = "PHONE";
65    private static final boolean LOCAL_DEBUG = true;
66
67    // Key used to read and write the saved network selection numeric value
68    public static final String NETWORK_SELECTION_KEY = "network_selection_key";
69    // Key used to read and write the saved network selection operator name
70    public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
71
72
73    // Key used to read/write "disable data connection on boot" pref (used for testing)
74    public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
75
76    /* Event Constants */
77    protected static final int EVENT_RADIO_AVAILABLE             = 1;
78    /** Supplementary Service Notification received. */
79    protected static final int EVENT_SSN                         = 2;
80    protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
81    protected static final int EVENT_MMI_DONE                    = 4;
82    protected static final int EVENT_RADIO_ON                    = 5;
83    protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
84    protected static final int EVENT_USSD                        = 7;
85    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
86    protected static final int EVENT_GET_IMEI_DONE               = 9;
87    protected static final int EVENT_GET_IMEISV_DONE             = 10;
88    protected static final int EVENT_GET_SIM_STATUS_DONE         = 11;
89    protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
90    protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
91    protected static final int EVENT_CALL_RING                   = 14;
92    protected static final int EVENT_CALL_RING_CONTINUE          = 15;
93
94    // Used to intercept the carrier selection calls so that
95    // we can save the values.
96    protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE    = 16;
97    protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17;
98    protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
99    protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
100    protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
101    // Events for CDMA support
102    protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
103    protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
104    protected static final int EVENT_NV_READY                       = 23;
105    protected static final int EVENT_SET_ENHANCED_VP                = 24;
106    protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
107    protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
108    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
109    // other
110    protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
111    protected static final int EVENT_NEW_ICC_SMS                    = 29;
112    protected static final int EVENT_ICC_RECORD_EVENTS              = 30;
113
114    // Key used to read/write current CLIR setting
115    public static final String CLIR_KEY = "clir_key";
116
117    // Key used to read/write "disable DNS server check" pref (used for testing)
118    public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
119
120    /* Instance Variables */
121    public CommandsInterface mCM;
122    boolean mDnsCheckDisabled;
123    public DataConnectionTracker mDataConnectionTracker;
124    boolean mDoesRilSendMultipleCallRing;
125    int mCallRingContinueToken;
126    int mCallRingDelay;
127    public boolean mIsTheCurrentActivePhone = true;
128    boolean mIsVoiceCapable = true;
129    public IccRecords mIccRecords;
130    protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>();
131    public SmsStorageMonitor mSmsStorageMonitor;
132    public SmsUsageMonitor mSmsUsageMonitor;
133    public SMSDispatcher mSMS;
134
135    /**
136     * Set a system property, unless we're in unit test mode
137     */
138    public void
139    setSystemProperty(String property, String value) {
140        if(getUnitTestMode()) {
141            return;
142        }
143        SystemProperties.set(property, value);
144    }
145
146
147    protected final RegistrantList mPreciseCallStateRegistrants
148            = new RegistrantList();
149
150    protected final RegistrantList mNewRingingConnectionRegistrants
151            = new RegistrantList();
152
153    protected final RegistrantList mIncomingRingRegistrants
154            = new RegistrantList();
155
156    protected final RegistrantList mDisconnectRegistrants
157            = new RegistrantList();
158
159    protected final RegistrantList mServiceStateRegistrants
160            = new RegistrantList();
161
162    protected final RegistrantList mMmiCompleteRegistrants
163            = new RegistrantList();
164
165    protected final RegistrantList mMmiRegistrants
166            = new RegistrantList();
167
168    protected final RegistrantList mUnknownConnectionRegistrants
169            = new RegistrantList();
170
171    protected final RegistrantList mSuppServiceFailedRegistrants
172            = new RegistrantList();
173
174    protected Looper mLooper; /* to insure registrants are in correct thread*/
175
176    protected final Context mContext;
177
178    /**
179     * PhoneNotifier is an abstraction for all system-wide
180     * state change notification. DefaultPhoneNotifier is
181     * used here unless running we're inside a unit test.
182     */
183    protected PhoneNotifier mNotifier;
184
185    protected SimulatedRadioControl mSimulatedRadioControl;
186
187    boolean mUnitTestMode;
188
189    /**
190     * Constructs a PhoneBase in normal (non-unit test) mode.
191     *
192     * @param context Context object from hosting application
193     * @param notifier An instance of DefaultPhoneNotifier,
194     * unless unit testing.
195     */
196    protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci) {
197        this(notifier, context, ci, false);
198    }
199
200    /**
201     * Constructs a PhoneBase in normal (non-unit test) mode.
202     *
203     * @param context Context object from hosting application
204     * @param notifier An instance of DefaultPhoneNotifier,
205     * unless unit testing.
206     * @param unitTestMode when true, prevents notifications
207     * of state change events
208     */
209    protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci,
210            boolean unitTestMode) {
211        this.mNotifier = notifier;
212        this.mContext = context;
213        mLooper = Looper.myLooper();
214        mCM = ci;
215
216        setPropertiesByCarrier();
217
218        setUnitTestMode(unitTestMode);
219
220        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
221        mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
222        mCM.setOnCallRing(this, EVENT_CALL_RING, null);
223
224        /* "Voice capable" means that this device supports circuit-switched
225        * (i.e. voice) phone calls over the telephony network, and is allowed
226        * to display the in-call UI while a cellular voice call is active.
227        * This will be false on "data only" devices which can't make voice
228        * calls and don't support any in-call UI.
229        */
230        mIsVoiceCapable = mContext.getResources().getBoolean(
231                com.android.internal.R.bool.config_voice_capable);
232
233        /**
234         *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
235         *  to be generated locally. Ideally all ring tones should be loops
236         * and this wouldn't be necessary. But to minimize changes to upper
237         * layers it is requested that it be generated by lower layers.
238         *
239         * By default old phones won't have the property set but do generate
240         * the RIL_UNSOL_CALL_RING so the default if there is no property is
241         * true.
242         */
243        mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
244                TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
245        Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
246
247        mCallRingDelay = SystemProperties.getInt(
248                TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
249        Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
250
251        // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
252        mSmsStorageMonitor = new SmsStorageMonitor(this);
253        mSmsUsageMonitor = new SmsUsageMonitor(context);
254    }
255
256    public void dispose() {
257        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
258            mCM.unSetOnCallRing(this);
259            // Must cleanup all connectionS and needs to use sendMessage!
260            mDataConnectionTracker.cleanUpAllConnections(null);
261            mIsTheCurrentActivePhone = false;
262            // Dispose the SMS usage and storage monitors
263            mSmsStorageMonitor.dispose();
264            mSmsUsageMonitor.dispose();
265        }
266    }
267
268    public void removeReferences() {
269        mSmsStorageMonitor = null;
270        mSmsUsageMonitor = null;
271        mSMS = null;
272        mIccRecords = null;
273        mIccCard.set(null);
274        mDataConnectionTracker = null;
275    }
276
277    /**
278     * When overridden the derived class needs to call
279     * super.handleMessage(msg) so this method has a
280     * a chance to process the message.
281     *
282     * @param msg
283     */
284    @Override
285    public void handleMessage(Message msg) {
286        AsyncResult ar;
287
288        switch(msg.what) {
289            case EVENT_CALL_RING:
290                Log.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
291                ar = (AsyncResult)msg.obj;
292                if (ar.exception == null) {
293                    PhoneConstants.State state = getState();
294                    if ((!mDoesRilSendMultipleCallRing)
295                            && ((state == PhoneConstants.State.RINGING) ||
296                                    (state == PhoneConstants.State.IDLE))) {
297                        mCallRingContinueToken += 1;
298                        sendIncomingCallRingNotification(mCallRingContinueToken);
299                    } else {
300                        notifyIncomingRing();
301                    }
302                }
303                break;
304
305            case EVENT_CALL_RING_CONTINUE:
306                Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
307                if (getState() == PhoneConstants.State.RINGING) {
308                    sendIncomingCallRingNotification(msg.arg1);
309                }
310                break;
311
312            default:
313                throw new RuntimeException("unexpected event not handled");
314        }
315    }
316
317    // Inherited documentation suffices.
318    public Context getContext() {
319        return mContext;
320    }
321
322    /**
323     * Disables the DNS check (i.e., allows "0.0.0.0").
324     * Useful for lab testing environment.
325     * @param b true disables the check, false enables.
326     */
327    public void disableDnsCheck(boolean b) {
328        mDnsCheckDisabled = b;
329        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
330        SharedPreferences.Editor editor = sp.edit();
331        editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
332        editor.apply();
333    }
334
335    /**
336     * Returns true if the DNS check is currently disabled.
337     */
338    public boolean isDnsCheckDisabled() {
339        return mDnsCheckDisabled;
340    }
341
342    // Inherited documentation suffices.
343    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
344        checkCorrectThread(h);
345
346        mPreciseCallStateRegistrants.addUnique(h, what, obj);
347    }
348
349    // Inherited documentation suffices.
350    public void unregisterForPreciseCallStateChanged(Handler h) {
351        mPreciseCallStateRegistrants.remove(h);
352    }
353
354    /**
355     * Subclasses of Phone probably want to replace this with a
356     * version scoped to their packages
357     */
358    protected void notifyPreciseCallStateChangedP() {
359        AsyncResult ar = new AsyncResult(null, this, null);
360        mPreciseCallStateRegistrants.notifyRegistrants(ar);
361    }
362
363    // Inherited documentation suffices.
364    public void registerForUnknownConnection(Handler h, int what, Object obj) {
365        checkCorrectThread(h);
366
367        mUnknownConnectionRegistrants.addUnique(h, what, obj);
368    }
369
370    // Inherited documentation suffices.
371    public void unregisterForUnknownConnection(Handler h) {
372        mUnknownConnectionRegistrants.remove(h);
373    }
374
375    // Inherited documentation suffices.
376    public void registerForNewRingingConnection(
377            Handler h, int what, Object obj) {
378        checkCorrectThread(h);
379
380        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
381    }
382
383    // Inherited documentation suffices.
384    public void unregisterForNewRingingConnection(Handler h) {
385        mNewRingingConnectionRegistrants.remove(h);
386    }
387
388    // Inherited documentation suffices.
389    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
390        mCM.registerForInCallVoicePrivacyOn(h,what,obj);
391    }
392
393    // Inherited documentation suffices.
394    public void unregisterForInCallVoicePrivacyOn(Handler h){
395        mCM.unregisterForInCallVoicePrivacyOn(h);
396    }
397
398    // Inherited documentation suffices.
399    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
400        mCM.registerForInCallVoicePrivacyOff(h,what,obj);
401    }
402
403    // Inherited documentation suffices.
404    public void unregisterForInCallVoicePrivacyOff(Handler h){
405        mCM.unregisterForInCallVoicePrivacyOff(h);
406    }
407
408    // Inherited documentation suffices.
409    public void registerForIncomingRing(
410            Handler h, int what, Object obj) {
411        checkCorrectThread(h);
412
413        mIncomingRingRegistrants.addUnique(h, what, obj);
414    }
415
416    // Inherited documentation suffices.
417    public void unregisterForIncomingRing(Handler h) {
418        mIncomingRingRegistrants.remove(h);
419    }
420
421    // Inherited documentation suffices.
422    public void registerForDisconnect(Handler h, int what, Object obj) {
423        checkCorrectThread(h);
424
425        mDisconnectRegistrants.addUnique(h, what, obj);
426    }
427
428    // Inherited documentation suffices.
429    public void unregisterForDisconnect(Handler h) {
430        mDisconnectRegistrants.remove(h);
431    }
432
433    // Inherited documentation suffices.
434    public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
435        checkCorrectThread(h);
436
437        mSuppServiceFailedRegistrants.addUnique(h, what, obj);
438    }
439
440    // Inherited documentation suffices.
441    public void unregisterForSuppServiceFailed(Handler h) {
442        mSuppServiceFailedRegistrants.remove(h);
443    }
444
445    // Inherited documentation suffices.
446    public void registerForMmiInitiate(Handler h, int what, Object obj) {
447        checkCorrectThread(h);
448
449        mMmiRegistrants.addUnique(h, what, obj);
450    }
451
452    // Inherited documentation suffices.
453    public void unregisterForMmiInitiate(Handler h) {
454        mMmiRegistrants.remove(h);
455    }
456
457    // Inherited documentation suffices.
458    public void registerForMmiComplete(Handler h, int what, Object obj) {
459        checkCorrectThread(h);
460
461        mMmiCompleteRegistrants.addUnique(h, what, obj);
462    }
463
464    // Inherited documentation suffices.
465    public void unregisterForMmiComplete(Handler h) {
466        checkCorrectThread(h);
467
468        mMmiCompleteRegistrants.remove(h);
469    }
470
471    /**
472     * Method to retrieve the saved operator id from the Shared Preferences
473     */
474    private String getSavedNetworkSelection() {
475        // open the shared preferences and search with our key.
476        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
477        return sp.getString(NETWORK_SELECTION_KEY, "");
478    }
479
480    /**
481     * Method to restore the previously saved operator id, or reset to
482     * automatic selection, all depending upon the value in the shared
483     * preferences.
484     */
485    public void restoreSavedNetworkSelection(Message response) {
486        // retrieve the operator id
487        String networkSelection = getSavedNetworkSelection();
488
489        // set to auto if the id is empty, otherwise select the network.
490        if (TextUtils.isEmpty(networkSelection)) {
491            mCM.setNetworkSelectionModeAutomatic(response);
492        } else {
493            mCM.setNetworkSelectionModeManual(networkSelection, response);
494        }
495    }
496
497    // Inherited documentation suffices.
498    public void setUnitTestMode(boolean f) {
499        mUnitTestMode = f;
500    }
501
502    // Inherited documentation suffices.
503    public boolean getUnitTestMode() {
504        return mUnitTestMode;
505    }
506
507    /**
508     * To be invoked when a voice call Connection disconnects.
509     *
510     * Subclasses of Phone probably want to replace this with a
511     * version scoped to their packages
512     */
513    protected void notifyDisconnectP(Connection cn) {
514        AsyncResult ar = new AsyncResult(null, cn, null);
515        mDisconnectRegistrants.notifyRegistrants(ar);
516    }
517
518    // Inherited documentation suffices.
519    public void registerForServiceStateChanged(
520            Handler h, int what, Object obj) {
521        checkCorrectThread(h);
522
523        mServiceStateRegistrants.add(h, what, obj);
524    }
525
526    // Inherited documentation suffices.
527    public void unregisterForServiceStateChanged(Handler h) {
528        mServiceStateRegistrants.remove(h);
529    }
530
531    // Inherited documentation suffices.
532    public void registerForRingbackTone(Handler h, int what, Object obj) {
533        mCM.registerForRingbackTone(h,what,obj);
534    }
535
536    // Inherited documentation suffices.
537    public void unregisterForRingbackTone(Handler h) {
538        mCM.unregisterForRingbackTone(h);
539    }
540
541    // Inherited documentation suffices.
542    public void registerForResendIncallMute(Handler h, int what, Object obj) {
543        mCM.registerForResendIncallMute(h,what,obj);
544    }
545
546    // Inherited documentation suffices.
547    public void unregisterForResendIncallMute(Handler h) {
548        mCM.unregisterForResendIncallMute(h);
549    }
550
551    public void setEchoSuppressionEnabled(boolean enabled) {
552        // no need for regular phone
553    }
554
555    /**
556     * Subclasses of Phone probably want to replace this with a
557     * version scoped to their packages
558     */
559    protected void notifyServiceStateChangedP(ServiceState ss) {
560        AsyncResult ar = new AsyncResult(null, ss, null);
561        mServiceStateRegistrants.notifyRegistrants(ar);
562
563        mNotifier.notifyServiceState(this);
564    }
565
566    /* package */void
567    notifySignalStrength() {
568        mNotifier.notifySignalStrength(this);
569    }
570
571    // Inherited documentation suffices.
572    public SimulatedRadioControl getSimulatedRadioControl() {
573        return mSimulatedRadioControl;
574    }
575
576    /**
577     * Verifies the current thread is the same as the thread originally
578     * used in the initialization of this instance. Throws RuntimeException
579     * if not.
580     *
581     * @exception RuntimeException if the current thread is not
582     * the thread that originally obtained this PhoneBase instance.
583     */
584    private void checkCorrectThread(Handler h) {
585        if (h.getLooper() != mLooper) {
586            throw new RuntimeException(
587                    "com.android.internal.telephony.Phone must be used from within one thread");
588        }
589    }
590
591    /**
592     * Set the properties by matching the carrier string in
593     * a string-array resource
594     */
595    private void setPropertiesByCarrier() {
596        String carrier = SystemProperties.get("ro.carrier");
597
598        if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
599            return;
600        }
601
602        CharSequence[] carrierLocales = mContext.
603                getResources().getTextArray(R.array.carrier_properties);
604
605        for (int i = 0; i < carrierLocales.length; i+=3) {
606            String c = carrierLocales[i].toString();
607            if (carrier.equals(c)) {
608                String l = carrierLocales[i+1].toString();
609
610                String language = l.substring(0, 2);
611                String country = "";
612                if (l.length() >=5) {
613                    country = l.substring(3, 5);
614                }
615                MccTable.setSystemLocale(mContext, language, country);
616
617                if (!country.isEmpty()) {
618                    try {
619                        Settings.Secure.getInt(mContext.getContentResolver(),
620                                Settings.Secure.WIFI_COUNTRY_CODE);
621                    } catch (Settings.SettingNotFoundException e) {
622                        // note this is not persisting
623                        WifiManager wM = (WifiManager)
624                                mContext.getSystemService(Context.WIFI_SERVICE);
625                        wM.setCountryCode(country, false);
626                    }
627                }
628                return;
629            }
630        }
631    }
632
633    /**
634     * Get state
635     */
636    public abstract PhoneConstants.State getState();
637
638    /**
639     * Retrieves the IccFileHandler of the Phone instance
640     */
641    public IccFileHandler getIccFileHandler(){
642        IccCard iccCard = mIccCard.get();
643        if (iccCard == null) return null;
644        return iccCard.getIccFileHandler();
645    }
646
647    /*
648     * Retrieves the Handler of the Phone instance
649     */
650    public Handler getHandler() {
651        return this;
652    }
653
654    /**
655    * Retrieves the ServiceStateTracker of the phone instance.
656    */
657    public ServiceStateTracker getServiceStateTracker() {
658        return null;
659    }
660
661    /**
662    * Get call tracker
663    */
664    public CallTracker getCallTracker() {
665        return null;
666    }
667
668    @Override
669    public IccCard getIccCard() {
670        return mIccCard.get();
671    }
672
673    @Override
674    public String getIccSerialNumber() {
675        return mIccRecords.iccid;
676    }
677
678    @Override
679    public boolean getIccRecordsLoaded() {
680        return mIccRecords.getRecordsLoaded();
681    }
682
683    @Override
684    public boolean getMessageWaitingIndicator() {
685        return mIccRecords.getVoiceMessageWaiting();
686    }
687
688    @Override
689    public boolean getCallForwardingIndicator() {
690        return mIccRecords.getVoiceCallForwardingFlag();
691    }
692
693    /**
694     *  Query the status of the CDMA roaming preference
695     */
696    public void queryCdmaRoamingPreference(Message response) {
697        mCM.queryCdmaRoamingPreference(response);
698    }
699
700    /**
701     *  Set the status of the CDMA roaming preference
702     */
703    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
704        mCM.setCdmaRoamingPreference(cdmaRoamingType, response);
705    }
706
707    /**
708     *  Set the status of the CDMA subscription mode
709     */
710    public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
711        mCM.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
712    }
713
714    /**
715     *  Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
716     */
717    public void setPreferredNetworkType(int networkType, Message response) {
718        mCM.setPreferredNetworkType(networkType, response);
719    }
720
721    public void getPreferredNetworkType(Message response) {
722        mCM.getPreferredNetworkType(response);
723    }
724
725    public void getSmscAddress(Message result) {
726        mCM.getSmscAddress(result);
727    }
728
729    public void setSmscAddress(String address, Message result) {
730        mCM.setSmscAddress(address, result);
731    }
732
733    public void setTTYMode(int ttyMode, Message onComplete) {
734        mCM.setTTYMode(ttyMode, onComplete);
735    }
736
737    public void queryTTYMode(Message onComplete) {
738        mCM.queryTTYMode(onComplete);
739    }
740
741    public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
742        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
743        logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy");
744    }
745
746    public void getEnhancedVoicePrivacy(Message onComplete) {
747        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
748        logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy");
749    }
750
751    public void setBandMode(int bandMode, Message response) {
752        mCM.setBandMode(bandMode, response);
753    }
754
755    public void queryAvailableBandMode(Message response) {
756        mCM.queryAvailableBandMode(response);
757    }
758
759    public void invokeOemRilRequestRaw(byte[] data, Message response) {
760        mCM.invokeOemRilRequestRaw(data, response);
761    }
762
763    public void invokeOemRilRequestStrings(String[] strings, Message response) {
764        mCM.invokeOemRilRequestStrings(strings, response);
765    }
766
767    public void notifyDataActivity() {
768        mNotifier.notifyDataActivity(this);
769    }
770
771    public void notifyMessageWaitingIndicator() {
772        // Do not notify voice mail waiting if device doesn't support voice
773        if (!mIsVoiceCapable)
774            return;
775
776        // This function is added to send the notification to DefaultPhoneNotifier.
777        mNotifier.notifyMessageWaitingChanged(this);
778    }
779
780    public void notifyDataConnection(String reason, String apnType,
781            PhoneConstants.DataState state) {
782        mNotifier.notifyDataConnection(this, reason, apnType, state);
783    }
784
785    public void notifyDataConnection(String reason, String apnType) {
786        mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
787    }
788
789    public void notifyDataConnection(String reason) {
790        String types[] = getActiveApnTypes();
791        for (String apnType : types) {
792            mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
793        }
794    }
795
796    public void notifyOtaspChanged(int otaspMode) {
797        mNotifier.notifyOtaspChanged(this, otaspMode);
798    }
799
800    /**
801     * @return true if a mobile originating emergency call is active
802     */
803    public boolean isInEmergencyCall() {
804        return false;
805    }
806
807    /**
808     * @return true if we are in the emergency call back mode. This is a period where
809     * the phone should be using as little power as possible and be ready to receive an
810     * incoming call from the emergency operator.
811     */
812    public boolean isInEcm() {
813        return false;
814    }
815
816    public abstract String getPhoneName();
817
818    public abstract int getPhoneType();
819
820    /** @hide */
821    public int getVoiceMessageCount(){
822        return 0;
823    }
824
825    /**
826     * Returns the CDMA ERI icon index to display
827     */
828    public int getCdmaEriIconIndex() {
829        logUnexpectedCdmaMethodCall("getCdmaEriIconIndex");
830        return -1;
831    }
832
833    /**
834     * Returns the CDMA ERI icon mode,
835     * 0 - ON
836     * 1 - FLASHING
837     */
838    public int getCdmaEriIconMode() {
839        logUnexpectedCdmaMethodCall("getCdmaEriIconMode");
840        return -1;
841    }
842
843    /**
844     * Returns the CDMA ERI text,
845     */
846    public String getCdmaEriText() {
847        logUnexpectedCdmaMethodCall("getCdmaEriText");
848        return "GSM nw, no ERI";
849    }
850
851    public String getCdmaMin() {
852        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
853        logUnexpectedCdmaMethodCall("getCdmaMin");
854        return null;
855    }
856
857    public boolean isMinInfoReady() {
858        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
859        logUnexpectedCdmaMethodCall("isMinInfoReady");
860        return false;
861    }
862
863    public String getCdmaPrlVersion(){
864        //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
865        logUnexpectedCdmaMethodCall("getCdmaPrlVersion");
866        return null;
867    }
868
869    public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
870        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
871        logUnexpectedCdmaMethodCall("sendBurstDtmf");
872    }
873
874    public void exitEmergencyCallbackMode() {
875        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
876        logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode");
877    }
878
879    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
880        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
881        logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange");
882    }
883
884    public void unregisterForCdmaOtaStatusChange(Handler h) {
885        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
886        logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange");
887    }
888
889    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
890        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
891        logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady");
892    }
893
894    public void unregisterForSubscriptionInfoReady(Handler h) {
895        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
896        logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
897    }
898
899    /**
900     * Returns true if OTA Service Provisioning needs to be performed.
901     * If not overridden return false.
902     */
903    public boolean needsOtaServiceProvisioning() {
904        return false;
905    }
906
907    /**
908     * Return true if number is an OTASP number.
909     * If not overridden return false.
910     */
911    public  boolean isOtaSpNumber(String dialStr) {
912        return false;
913    }
914
915    public void registerForCallWaiting(Handler h, int what, Object obj){
916        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
917        logUnexpectedCdmaMethodCall("registerForCallWaiting");
918    }
919
920    public void unregisterForCallWaiting(Handler h){
921        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
922        logUnexpectedCdmaMethodCall("unregisterForCallWaiting");
923    }
924
925    public void registerForEcmTimerReset(Handler h, int what, Object obj) {
926        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
927        logUnexpectedCdmaMethodCall("registerForEcmTimerReset");
928    }
929
930    public void unregisterForEcmTimerReset(Handler h) {
931        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
932        logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset");
933    }
934
935    public void registerForSignalInfo(Handler h, int what, Object obj) {
936        mCM.registerForSignalInfo(h, what, obj);
937    }
938
939    public void unregisterForSignalInfo(Handler h) {
940        mCM.unregisterForSignalInfo(h);
941    }
942
943    public void registerForDisplayInfo(Handler h, int what, Object obj) {
944        mCM.registerForDisplayInfo(h, what, obj);
945    }
946
947     public void unregisterForDisplayInfo(Handler h) {
948         mCM.unregisterForDisplayInfo(h);
949     }
950
951    public void registerForNumberInfo(Handler h, int what, Object obj) {
952        mCM.registerForNumberInfo(h, what, obj);
953    }
954
955    public void unregisterForNumberInfo(Handler h) {
956        mCM.unregisterForNumberInfo(h);
957    }
958
959    public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
960        mCM.registerForRedirectedNumberInfo(h, what, obj);
961    }
962
963    public void unregisterForRedirectedNumberInfo(Handler h) {
964        mCM.unregisterForRedirectedNumberInfo(h);
965    }
966
967    public void registerForLineControlInfo(Handler h, int what, Object obj) {
968        mCM.registerForLineControlInfo( h, what, obj);
969    }
970
971    public void unregisterForLineControlInfo(Handler h) {
972        mCM.unregisterForLineControlInfo(h);
973    }
974
975    public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
976        mCM.registerFoT53ClirlInfo(h, what, obj);
977    }
978
979    public void unregisterForT53ClirInfo(Handler h) {
980        mCM.unregisterForT53ClirInfo(h);
981    }
982
983    public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
984        mCM.registerForT53AudioControlInfo( h, what, obj);
985    }
986
987    public void unregisterForT53AudioControlInfo(Handler h) {
988        mCM.unregisterForT53AudioControlInfo(h);
989    }
990
991     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
992         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
993         logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse");
994     }
995
996     public void unsetOnEcbModeExitResponse(Handler h){
997        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
998         logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
999     }
1000
1001    public String[] getActiveApnTypes() {
1002        return mDataConnectionTracker.getActiveApnTypes();
1003    }
1004
1005    public String getActiveApnHost(String apnType) {
1006        return mDataConnectionTracker.getActiveApnString(apnType);
1007    }
1008
1009    public LinkProperties getLinkProperties(String apnType) {
1010        return mDataConnectionTracker.getLinkProperties(apnType);
1011    }
1012
1013    public LinkCapabilities getLinkCapabilities(String apnType) {
1014        return mDataConnectionTracker.getLinkCapabilities(apnType);
1015    }
1016
1017    public int enableApnType(String type) {
1018        return mDataConnectionTracker.enableApnType(type);
1019    }
1020
1021    public int disableApnType(String type) {
1022        return mDataConnectionTracker.disableApnType(type);
1023    }
1024
1025    public boolean isDataConnectivityPossible() {
1026        return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT);
1027    }
1028
1029    public boolean isDataConnectivityPossible(String apnType) {
1030        return ((mDataConnectionTracker != null) &&
1031                (mDataConnectionTracker.isDataPossible(apnType)));
1032    }
1033
1034    /**
1035     * Notify registrants of a new ringing Connection.
1036     * Subclasses of Phone probably want to replace this with a
1037     * version scoped to their packages
1038     */
1039    protected void notifyNewRingingConnectionP(Connection cn) {
1040        if (!mIsVoiceCapable)
1041            return;
1042        AsyncResult ar = new AsyncResult(null, cn, null);
1043        mNewRingingConnectionRegistrants.notifyRegistrants(ar);
1044    }
1045
1046    /**
1047     * Notify registrants of a RING event.
1048     */
1049    private void notifyIncomingRing() {
1050        if (!mIsVoiceCapable)
1051            return;
1052        AsyncResult ar = new AsyncResult(null, this, null);
1053        mIncomingRingRegistrants.notifyRegistrants(ar);
1054    }
1055
1056    /**
1057     * Send the incoming call Ring notification if conditions are right.
1058     */
1059    private void sendIncomingCallRingNotification(int token) {
1060        if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
1061                (token == mCallRingContinueToken)) {
1062            Log.d(LOG_TAG, "Sending notifyIncomingRing");
1063            notifyIncomingRing();
1064            sendMessageDelayed(
1065                    obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
1066        } else {
1067            Log.d(LOG_TAG, "Ignoring ring notification request,"
1068                    + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
1069                    + " token=" + token
1070                    + " mCallRingContinueToken=" + mCallRingContinueToken
1071                    + " mIsVoiceCapable=" + mIsVoiceCapable);
1072        }
1073    }
1074
1075    public boolean isCspPlmnEnabled() {
1076        // This function should be overridden by the class GSMPhone.
1077        // Not implemented in CDMAPhone.
1078        logUnexpectedGsmMethodCall("isCspPlmnEnabled");
1079        return false;
1080    }
1081
1082    public IsimRecords getIsimRecords() {
1083        Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
1084        return null;
1085    }
1086
1087    public void requestIsimAuthentication(String nonce, Message result) {
1088        Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
1089    }
1090
1091    public String getMsisdn() {
1092        logUnexpectedGsmMethodCall("getMsisdn");
1093        return null;
1094    }
1095
1096    /**
1097     * Common error logger method for unexpected calls to CDMA-only methods.
1098     */
1099    private static void logUnexpectedCdmaMethodCall(String name)
1100    {
1101        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
1102                "called, CDMAPhone inactive.");
1103    }
1104
1105    public PhoneConstants.DataState getDataConnectionState() {
1106        return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
1107    }
1108
1109    /**
1110     * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
1111     */
1112    private static void logUnexpectedGsmMethodCall(String name) {
1113        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
1114                "called, GSMPhone inactive.");
1115    }
1116
1117    // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
1118    public void notifyCallForwardingIndicator() {
1119        // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
1120        Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
1121    }
1122
1123    public void notifyDataConnectionFailed(String reason, String apnType) {
1124        mNotifier.notifyDataConnectionFailed(this, reason, apnType);
1125    }
1126
1127    /**
1128     * {@inheritDoc}
1129     */
1130    @Override
1131    public int getLteOnCdmaMode() {
1132        return mCM.getLteOnCdmaMode();
1133    }
1134
1135    /**
1136     * Sets the SIM voice message waiting indicator records.
1137     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
1138     * @param countWaiting The number of messages waiting, if known. Use
1139     *                     -1 to indicate that an unknown number of
1140     *                      messages are waiting
1141     */
1142    @Override
1143    public void setVoiceMessageWaiting(int line, int countWaiting) {
1144        mIccRecords.setVoiceMessageWaiting(line, countWaiting);
1145    }
1146
1147    /**
1148     * Gets the USIM service table from the UICC, if present and available.
1149     * @return an interface to the UsimServiceTable record, or null if not available
1150     */
1151    @Override
1152    public UsimServiceTable getUsimServiceTable() {
1153        return mIccRecords.getUsimServiceTable();
1154    }
1155
1156    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1157        pw.println("PhoneBase:");
1158        pw.println(" mCM=" + mCM);
1159        pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
1160        pw.println(" mDataConnectionTracker=" + mDataConnectionTracker);
1161        pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
1162        pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
1163        pw.println(" mCallRingDelay=" + mCallRingDelay);
1164        pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
1165        pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
1166        pw.println(" mIccRecords=" + mIccRecords);
1167        pw.println(" mIccCard=" + mIccCard.get());
1168        pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
1169        pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
1170        pw.println(" mSMS=" + mSMS);
1171        pw.flush();
1172        pw.println(" mLooper=" + mLooper);
1173        pw.println(" mContext=" + mContext);
1174        pw.println(" mNotifier=" + mNotifier);
1175        pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
1176        pw.println(" mUnitTestMode=" + mUnitTestMode);
1177        pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
1178        pw.println(" getUnitTestMode()=" + getUnitTestMode());
1179        pw.println(" getState()=" + getState());
1180        pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
1181        pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
1182        pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
1183        pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
1184        pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
1185        pw.flush();
1186        pw.println(" isInEcm()=" + isInEcm());
1187        pw.println(" getPhoneName()=" + getPhoneName());
1188        pw.println(" getPhoneType()=" + getPhoneType());
1189        pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
1190        pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
1191        pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
1192        pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
1193    }
1194}
1195