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                    Phone.State state = getState();
294                    if ((!mDoesRilSendMultipleCallRing)
295                            && ((state == Phone.State.RINGING) || (state == Phone.State.IDLE))) {
296                        mCallRingContinueToken += 1;
297                        sendIncomingCallRingNotification(mCallRingContinueToken);
298                    } else {
299                        notifyIncomingRing();
300                    }
301                }
302                break;
303
304            case EVENT_CALL_RING_CONTINUE:
305                Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
306                if (getState() == Phone.State.RINGING) {
307                    sendIncomingCallRingNotification(msg.arg1);
308                }
309                break;
310
311            default:
312                throw new RuntimeException("unexpected event not handled");
313        }
314    }
315
316    // Inherited documentation suffices.
317    public Context getContext() {
318        return mContext;
319    }
320
321    /**
322     * Disables the DNS check (i.e., allows "0.0.0.0").
323     * Useful for lab testing environment.
324     * @param b true disables the check, false enables.
325     */
326    public void disableDnsCheck(boolean b) {
327        mDnsCheckDisabled = b;
328        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
329        SharedPreferences.Editor editor = sp.edit();
330        editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
331        editor.apply();
332    }
333
334    /**
335     * Returns true if the DNS check is currently disabled.
336     */
337    public boolean isDnsCheckDisabled() {
338        return mDnsCheckDisabled;
339    }
340
341    // Inherited documentation suffices.
342    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
343        checkCorrectThread(h);
344
345        mPreciseCallStateRegistrants.addUnique(h, what, obj);
346    }
347
348    // Inherited documentation suffices.
349    public void unregisterForPreciseCallStateChanged(Handler h) {
350        mPreciseCallStateRegistrants.remove(h);
351    }
352
353    /**
354     * Subclasses of Phone probably want to replace this with a
355     * version scoped to their packages
356     */
357    protected void notifyPreciseCallStateChangedP() {
358        AsyncResult ar = new AsyncResult(null, this, null);
359        mPreciseCallStateRegistrants.notifyRegistrants(ar);
360    }
361
362    // Inherited documentation suffices.
363    public void registerForUnknownConnection(Handler h, int what, Object obj) {
364        checkCorrectThread(h);
365
366        mUnknownConnectionRegistrants.addUnique(h, what, obj);
367    }
368
369    // Inherited documentation suffices.
370    public void unregisterForUnknownConnection(Handler h) {
371        mUnknownConnectionRegistrants.remove(h);
372    }
373
374    // Inherited documentation suffices.
375    public void registerForNewRingingConnection(
376            Handler h, int what, Object obj) {
377        checkCorrectThread(h);
378
379        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
380    }
381
382    // Inherited documentation suffices.
383    public void unregisterForNewRingingConnection(Handler h) {
384        mNewRingingConnectionRegistrants.remove(h);
385    }
386
387    // Inherited documentation suffices.
388    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
389        mCM.registerForInCallVoicePrivacyOn(h,what,obj);
390    }
391
392    // Inherited documentation suffices.
393    public void unregisterForInCallVoicePrivacyOn(Handler h){
394        mCM.unregisterForInCallVoicePrivacyOn(h);
395    }
396
397    // Inherited documentation suffices.
398    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
399        mCM.registerForInCallVoicePrivacyOff(h,what,obj);
400    }
401
402    // Inherited documentation suffices.
403    public void unregisterForInCallVoicePrivacyOff(Handler h){
404        mCM.unregisterForInCallVoicePrivacyOff(h);
405    }
406
407    // Inherited documentation suffices.
408    public void registerForIncomingRing(
409            Handler h, int what, Object obj) {
410        checkCorrectThread(h);
411
412        mIncomingRingRegistrants.addUnique(h, what, obj);
413    }
414
415    // Inherited documentation suffices.
416    public void unregisterForIncomingRing(Handler h) {
417        mIncomingRingRegistrants.remove(h);
418    }
419
420    // Inherited documentation suffices.
421    public void registerForDisconnect(Handler h, int what, Object obj) {
422        checkCorrectThread(h);
423
424        mDisconnectRegistrants.addUnique(h, what, obj);
425    }
426
427    // Inherited documentation suffices.
428    public void unregisterForDisconnect(Handler h) {
429        mDisconnectRegistrants.remove(h);
430    }
431
432    // Inherited documentation suffices.
433    public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
434        checkCorrectThread(h);
435
436        mSuppServiceFailedRegistrants.addUnique(h, what, obj);
437    }
438
439    // Inherited documentation suffices.
440    public void unregisterForSuppServiceFailed(Handler h) {
441        mSuppServiceFailedRegistrants.remove(h);
442    }
443
444    // Inherited documentation suffices.
445    public void registerForMmiInitiate(Handler h, int what, Object obj) {
446        checkCorrectThread(h);
447
448        mMmiRegistrants.addUnique(h, what, obj);
449    }
450
451    // Inherited documentation suffices.
452    public void unregisterForMmiInitiate(Handler h) {
453        mMmiRegistrants.remove(h);
454    }
455
456    // Inherited documentation suffices.
457    public void registerForMmiComplete(Handler h, int what, Object obj) {
458        checkCorrectThread(h);
459
460        mMmiCompleteRegistrants.addUnique(h, what, obj);
461    }
462
463    // Inherited documentation suffices.
464    public void unregisterForMmiComplete(Handler h) {
465        checkCorrectThread(h);
466
467        mMmiCompleteRegistrants.remove(h);
468    }
469
470    /**
471     * Method to retrieve the saved operator id from the Shared Preferences
472     */
473    private String getSavedNetworkSelection() {
474        // open the shared preferences and search with our key.
475        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
476        return sp.getString(NETWORK_SELECTION_KEY, "");
477    }
478
479    /**
480     * Method to restore the previously saved operator id, or reset to
481     * automatic selection, all depending upon the value in the shared
482     * preferences.
483     */
484    public void restoreSavedNetworkSelection(Message response) {
485        // retrieve the operator id
486        String networkSelection = getSavedNetworkSelection();
487
488        // set to auto if the id is empty, otherwise select the network.
489        if (TextUtils.isEmpty(networkSelection)) {
490            mCM.setNetworkSelectionModeAutomatic(response);
491        } else {
492            mCM.setNetworkSelectionModeManual(networkSelection, response);
493        }
494    }
495
496    // Inherited documentation suffices.
497    public void setUnitTestMode(boolean f) {
498        mUnitTestMode = f;
499    }
500
501    // Inherited documentation suffices.
502    public boolean getUnitTestMode() {
503        return mUnitTestMode;
504    }
505
506    /**
507     * To be invoked when a voice call Connection disconnects.
508     *
509     * Subclasses of Phone probably want to replace this with a
510     * version scoped to their packages
511     */
512    protected void notifyDisconnectP(Connection cn) {
513        AsyncResult ar = new AsyncResult(null, cn, null);
514        mDisconnectRegistrants.notifyRegistrants(ar);
515    }
516
517    // Inherited documentation suffices.
518    public void registerForServiceStateChanged(
519            Handler h, int what, Object obj) {
520        checkCorrectThread(h);
521
522        mServiceStateRegistrants.add(h, what, obj);
523    }
524
525    // Inherited documentation suffices.
526    public void unregisterForServiceStateChanged(Handler h) {
527        mServiceStateRegistrants.remove(h);
528    }
529
530    // Inherited documentation suffices.
531    public void registerForRingbackTone(Handler h, int what, Object obj) {
532        mCM.registerForRingbackTone(h,what,obj);
533    }
534
535    // Inherited documentation suffices.
536    public void unregisterForRingbackTone(Handler h) {
537        mCM.unregisterForRingbackTone(h);
538    }
539
540    // Inherited documentation suffices.
541    public void registerForResendIncallMute(Handler h, int what, Object obj) {
542        mCM.registerForResendIncallMute(h,what,obj);
543    }
544
545    // Inherited documentation suffices.
546    public void unregisterForResendIncallMute(Handler h) {
547        mCM.unregisterForResendIncallMute(h);
548    }
549
550    public void setEchoSuppressionEnabled(boolean enabled) {
551        // no need for regular phone
552    }
553
554    /**
555     * Subclasses of Phone probably want to replace this with a
556     * version scoped to their packages
557     */
558    protected void notifyServiceStateChangedP(ServiceState ss) {
559        AsyncResult ar = new AsyncResult(null, ss, null);
560        mServiceStateRegistrants.notifyRegistrants(ar);
561
562        mNotifier.notifyServiceState(this);
563    }
564
565    // Inherited documentation suffices.
566    public SimulatedRadioControl getSimulatedRadioControl() {
567        return mSimulatedRadioControl;
568    }
569
570    /**
571     * Verifies the current thread is the same as the thread originally
572     * used in the initialization of this instance. Throws RuntimeException
573     * if not.
574     *
575     * @exception RuntimeException if the current thread is not
576     * the thread that originally obtained this PhoneBase instance.
577     */
578    private void checkCorrectThread(Handler h) {
579        if (h.getLooper() != mLooper) {
580            throw new RuntimeException(
581                    "com.android.internal.telephony.Phone must be used from within one thread");
582        }
583    }
584
585    /**
586     * Set the properties by matching the carrier string in
587     * a string-array resource
588     */
589    private void setPropertiesByCarrier() {
590        String carrier = SystemProperties.get("ro.carrier");
591
592        if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
593            return;
594        }
595
596        CharSequence[] carrierLocales = mContext.
597                getResources().getTextArray(R.array.carrier_properties);
598
599        for (int i = 0; i < carrierLocales.length; i+=3) {
600            String c = carrierLocales[i].toString();
601            if (carrier.equals(c)) {
602                String l = carrierLocales[i+1].toString();
603
604                String language = l.substring(0, 2);
605                String country = "";
606                if (l.length() >=5) {
607                    country = l.substring(3, 5);
608                }
609                MccTable.setSystemLocale(mContext, language, country);
610
611                if (!country.isEmpty()) {
612                    try {
613                        Settings.Secure.getInt(mContext.getContentResolver(),
614                                Settings.Secure.WIFI_COUNTRY_CODE);
615                    } catch (Settings.SettingNotFoundException e) {
616                        // note this is not persisting
617                        WifiManager wM = (WifiManager)
618                                mContext.getSystemService(Context.WIFI_SERVICE);
619                        wM.setCountryCode(country, false);
620                    }
621                }
622                return;
623            }
624        }
625    }
626
627    /**
628     * Get state
629     */
630    public abstract Phone.State getState();
631
632    /**
633     * Retrieves the IccFileHandler of the Phone instance
634     */
635    public IccFileHandler getIccFileHandler(){
636        IccCard iccCard = mIccCard.get();
637        if (iccCard == null) return null;
638        return iccCard.getIccFileHandler();
639    }
640
641    /*
642     * Retrieves the Handler of the Phone instance
643     */
644    public Handler getHandler() {
645        return this;
646    }
647
648    /**
649    * Retrieves the ServiceStateTracker of the phone instance.
650    */
651    public ServiceStateTracker getServiceStateTracker() {
652        return null;
653    }
654
655    /**
656    * Get call tracker
657    */
658    public CallTracker getCallTracker() {
659        return null;
660    }
661
662    @Override
663    public IccCard getIccCard() {
664        return mIccCard.get();
665    }
666
667    @Override
668    public String getIccSerialNumber() {
669        return mIccRecords.iccid;
670    }
671
672    @Override
673    public boolean getIccRecordsLoaded() {
674        return mIccRecords.getRecordsLoaded();
675    }
676
677    @Override
678    public boolean getMessageWaitingIndicator() {
679        return mIccRecords.getVoiceMessageWaiting();
680    }
681
682    @Override
683    public boolean getCallForwardingIndicator() {
684        return mIccRecords.getVoiceCallForwardingFlag();
685    }
686
687    /**
688     *  Query the status of the CDMA roaming preference
689     */
690    public void queryCdmaRoamingPreference(Message response) {
691        mCM.queryCdmaRoamingPreference(response);
692    }
693
694    /**
695     *  Set the status of the CDMA roaming preference
696     */
697    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
698        mCM.setCdmaRoamingPreference(cdmaRoamingType, response);
699    }
700
701    /**
702     *  Set the status of the CDMA subscription mode
703     */
704    public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
705        mCM.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
706    }
707
708    /**
709     *  Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
710     */
711    public void setPreferredNetworkType(int networkType, Message response) {
712        mCM.setPreferredNetworkType(networkType, response);
713    }
714
715    public void getPreferredNetworkType(Message response) {
716        mCM.getPreferredNetworkType(response);
717    }
718
719    public void getSmscAddress(Message result) {
720        mCM.getSmscAddress(result);
721    }
722
723    public void setSmscAddress(String address, Message result) {
724        mCM.setSmscAddress(address, result);
725    }
726
727    public void setTTYMode(int ttyMode, Message onComplete) {
728        mCM.setTTYMode(ttyMode, onComplete);
729    }
730
731    public void queryTTYMode(Message onComplete) {
732        mCM.queryTTYMode(onComplete);
733    }
734
735    public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
736        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
737        logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy");
738    }
739
740    public void getEnhancedVoicePrivacy(Message onComplete) {
741        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
742        logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy");
743    }
744
745    public void setBandMode(int bandMode, Message response) {
746        mCM.setBandMode(bandMode, response);
747    }
748
749    public void queryAvailableBandMode(Message response) {
750        mCM.queryAvailableBandMode(response);
751    }
752
753    public void invokeOemRilRequestRaw(byte[] data, Message response) {
754        mCM.invokeOemRilRequestRaw(data, response);
755    }
756
757    public void invokeOemRilRequestStrings(String[] strings, Message response) {
758        mCM.invokeOemRilRequestStrings(strings, response);
759    }
760
761    public void notifyDataActivity() {
762        mNotifier.notifyDataActivity(this);
763    }
764
765    public void notifyMessageWaitingIndicator() {
766        // Do not notify voice mail waiting if device doesn't support voice
767        if (!mIsVoiceCapable)
768            return;
769
770        // This function is added to send the notification to DefaultPhoneNotifier.
771        mNotifier.notifyMessageWaitingChanged(this);
772    }
773
774    public void notifyDataConnection(String reason, String apnType,
775            Phone.DataState state) {
776        mNotifier.notifyDataConnection(this, reason, apnType, state);
777    }
778
779    public void notifyDataConnection(String reason, String apnType) {
780        mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
781    }
782
783    public void notifyDataConnection(String reason) {
784        String types[] = getActiveApnTypes();
785        for (String apnType : types) {
786            mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
787        }
788    }
789
790    public void notifyOtaspChanged(int otaspMode) {
791        mNotifier.notifyOtaspChanged(this, otaspMode);
792    }
793
794    /**
795     * @return true if a mobile originating emergency call is active
796     */
797    public boolean isInEmergencyCall() {
798        return false;
799    }
800
801    /**
802     * @return true if we are in the emergency call back mode. This is a period where
803     * the phone should be using as little power as possible and be ready to receive an
804     * incoming call from the emergency operator.
805     */
806    public boolean isInEcm() {
807        return false;
808    }
809
810    public abstract String getPhoneName();
811
812    public abstract int getPhoneType();
813
814    /** @hide */
815    public int getVoiceMessageCount(){
816        return 0;
817    }
818
819    /**
820     * Returns the CDMA ERI icon index to display
821     */
822    public int getCdmaEriIconIndex() {
823        logUnexpectedCdmaMethodCall("getCdmaEriIconIndex");
824        return -1;
825    }
826
827    /**
828     * Returns the CDMA ERI icon mode,
829     * 0 - ON
830     * 1 - FLASHING
831     */
832    public int getCdmaEriIconMode() {
833        logUnexpectedCdmaMethodCall("getCdmaEriIconMode");
834        return -1;
835    }
836
837    /**
838     * Returns the CDMA ERI text,
839     */
840    public String getCdmaEriText() {
841        logUnexpectedCdmaMethodCall("getCdmaEriText");
842        return "GSM nw, no ERI";
843    }
844
845    public String getCdmaMin() {
846        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
847        logUnexpectedCdmaMethodCall("getCdmaMin");
848        return null;
849    }
850
851    public boolean isMinInfoReady() {
852        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
853        logUnexpectedCdmaMethodCall("isMinInfoReady");
854        return false;
855    }
856
857    public String getCdmaPrlVersion(){
858        //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
859        logUnexpectedCdmaMethodCall("getCdmaPrlVersion");
860        return null;
861    }
862
863    public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
864        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
865        logUnexpectedCdmaMethodCall("sendBurstDtmf");
866    }
867
868    public void exitEmergencyCallbackMode() {
869        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
870        logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode");
871    }
872
873    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
874        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
875        logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange");
876    }
877
878    public void unregisterForCdmaOtaStatusChange(Handler h) {
879        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
880        logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange");
881    }
882
883    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
884        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
885        logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady");
886    }
887
888    public void unregisterForSubscriptionInfoReady(Handler h) {
889        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
890        logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
891    }
892
893    /**
894     * Returns true if OTA Service Provisioning needs to be performed.
895     * If not overridden return false.
896     */
897    public boolean needsOtaServiceProvisioning() {
898        return false;
899    }
900
901    /**
902     * Return true if number is an OTASP number.
903     * If not overridden return false.
904     */
905    public  boolean isOtaSpNumber(String dialStr) {
906        return false;
907    }
908
909    public void registerForCallWaiting(Handler h, int what, Object obj){
910        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
911        logUnexpectedCdmaMethodCall("registerForCallWaiting");
912    }
913
914    public void unregisterForCallWaiting(Handler h){
915        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
916        logUnexpectedCdmaMethodCall("unregisterForCallWaiting");
917    }
918
919    public void registerForEcmTimerReset(Handler h, int what, Object obj) {
920        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
921        logUnexpectedCdmaMethodCall("registerForEcmTimerReset");
922    }
923
924    public void unregisterForEcmTimerReset(Handler h) {
925        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
926        logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset");
927    }
928
929    public void registerForSignalInfo(Handler h, int what, Object obj) {
930        mCM.registerForSignalInfo(h, what, obj);
931    }
932
933    public void unregisterForSignalInfo(Handler h) {
934        mCM.unregisterForSignalInfo(h);
935    }
936
937    public void registerForDisplayInfo(Handler h, int what, Object obj) {
938        mCM.registerForDisplayInfo(h, what, obj);
939    }
940
941     public void unregisterForDisplayInfo(Handler h) {
942         mCM.unregisterForDisplayInfo(h);
943     }
944
945    public void registerForNumberInfo(Handler h, int what, Object obj) {
946        mCM.registerForNumberInfo(h, what, obj);
947    }
948
949    public void unregisterForNumberInfo(Handler h) {
950        mCM.unregisterForNumberInfo(h);
951    }
952
953    public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
954        mCM.registerForRedirectedNumberInfo(h, what, obj);
955    }
956
957    public void unregisterForRedirectedNumberInfo(Handler h) {
958        mCM.unregisterForRedirectedNumberInfo(h);
959    }
960
961    public void registerForLineControlInfo(Handler h, int what, Object obj) {
962        mCM.registerForLineControlInfo( h, what, obj);
963    }
964
965    public void unregisterForLineControlInfo(Handler h) {
966        mCM.unregisterForLineControlInfo(h);
967    }
968
969    public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
970        mCM.registerFoT53ClirlInfo(h, what, obj);
971    }
972
973    public void unregisterForT53ClirInfo(Handler h) {
974        mCM.unregisterForT53ClirInfo(h);
975    }
976
977    public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
978        mCM.registerForT53AudioControlInfo( h, what, obj);
979    }
980
981    public void unregisterForT53AudioControlInfo(Handler h) {
982        mCM.unregisterForT53AudioControlInfo(h);
983    }
984
985     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
986         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
987         logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse");
988     }
989
990     public void unsetOnEcbModeExitResponse(Handler h){
991        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
992         logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
993     }
994
995    public String[] getActiveApnTypes() {
996        return mDataConnectionTracker.getActiveApnTypes();
997    }
998
999    public String getActiveApnHost(String apnType) {
1000        return mDataConnectionTracker.getActiveApnString(apnType);
1001    }
1002
1003    public LinkProperties getLinkProperties(String apnType) {
1004        return mDataConnectionTracker.getLinkProperties(apnType);
1005    }
1006
1007    public LinkCapabilities getLinkCapabilities(String apnType) {
1008        return mDataConnectionTracker.getLinkCapabilities(apnType);
1009    }
1010
1011    public int enableApnType(String type) {
1012        return mDataConnectionTracker.enableApnType(type);
1013    }
1014
1015    public int disableApnType(String type) {
1016        return mDataConnectionTracker.disableApnType(type);
1017    }
1018
1019    public boolean isDataConnectivityPossible() {
1020        return isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT);
1021    }
1022
1023    public boolean isDataConnectivityPossible(String apnType) {
1024        return ((mDataConnectionTracker != null) &&
1025                (mDataConnectionTracker.isDataPossible(apnType)));
1026    }
1027
1028    /**
1029     * Notify registrants of a new ringing Connection.
1030     * Subclasses of Phone probably want to replace this with a
1031     * version scoped to their packages
1032     */
1033    protected void notifyNewRingingConnectionP(Connection cn) {
1034        if (!mIsVoiceCapable)
1035            return;
1036        AsyncResult ar = new AsyncResult(null, cn, null);
1037        mNewRingingConnectionRegistrants.notifyRegistrants(ar);
1038    }
1039
1040    /**
1041     * Notify registrants of a RING event.
1042     */
1043    private void notifyIncomingRing() {
1044        if (!mIsVoiceCapable)
1045            return;
1046        AsyncResult ar = new AsyncResult(null, this, null);
1047        mIncomingRingRegistrants.notifyRegistrants(ar);
1048    }
1049
1050    /**
1051     * Send the incoming call Ring notification if conditions are right.
1052     */
1053    private void sendIncomingCallRingNotification(int token) {
1054        if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
1055                (token == mCallRingContinueToken)) {
1056            Log.d(LOG_TAG, "Sending notifyIncomingRing");
1057            notifyIncomingRing();
1058            sendMessageDelayed(
1059                    obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
1060        } else {
1061            Log.d(LOG_TAG, "Ignoring ring notification request,"
1062                    + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
1063                    + " token=" + token
1064                    + " mCallRingContinueToken=" + mCallRingContinueToken
1065                    + " mIsVoiceCapable=" + mIsVoiceCapable);
1066        }
1067    }
1068
1069    public boolean isCspPlmnEnabled() {
1070        // This function should be overridden by the class GSMPhone.
1071        // Not implemented in CDMAPhone.
1072        logUnexpectedGsmMethodCall("isCspPlmnEnabled");
1073        return false;
1074    }
1075
1076    public IsimRecords getIsimRecords() {
1077        Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
1078        return null;
1079    }
1080
1081    public void requestIsimAuthentication(String nonce, Message result) {
1082        Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
1083    }
1084
1085    public String getMsisdn() {
1086        logUnexpectedGsmMethodCall("getMsisdn");
1087        return null;
1088    }
1089
1090    /**
1091     * Common error logger method for unexpected calls to CDMA-only methods.
1092     */
1093    private static void logUnexpectedCdmaMethodCall(String name)
1094    {
1095        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
1096                "called, CDMAPhone inactive.");
1097    }
1098
1099    public DataState getDataConnectionState() {
1100        return getDataConnectionState(APN_TYPE_DEFAULT);
1101    }
1102
1103    /**
1104     * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
1105     */
1106    private static void logUnexpectedGsmMethodCall(String name) {
1107        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
1108                "called, GSMPhone inactive.");
1109    }
1110
1111    // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
1112    public void notifyCallForwardingIndicator() {
1113        // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
1114        Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
1115    }
1116
1117    public void notifyDataConnectionFailed(String reason, String apnType) {
1118        mNotifier.notifyDataConnectionFailed(this, reason, apnType);
1119    }
1120
1121    /**
1122     * {@inheritDoc}
1123     */
1124    @Override
1125    public int getLteOnCdmaMode() {
1126        return mCM.getLteOnCdmaMode();
1127    }
1128
1129    /**
1130     * Sets the SIM voice message waiting indicator records.
1131     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
1132     * @param countWaiting The number of messages waiting, if known. Use
1133     *                     -1 to indicate that an unknown number of
1134     *                      messages are waiting
1135     */
1136    @Override
1137    public void setVoiceMessageWaiting(int line, int countWaiting) {
1138        mIccRecords.setVoiceMessageWaiting(line, countWaiting);
1139    }
1140
1141    /**
1142     * Gets the USIM service table from the UICC, if present and available.
1143     * @return an interface to the UsimServiceTable record, or null if not available
1144     */
1145    @Override
1146    public UsimServiceTable getUsimServiceTable() {
1147        return mIccRecords.getUsimServiceTable();
1148    }
1149
1150    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1151        pw.println("PhoneBase:");
1152        pw.println(" mCM=" + mCM);
1153        pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
1154        pw.println(" mDataConnectionTracker=" + mDataConnectionTracker);
1155        pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
1156        pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
1157        pw.println(" mCallRingDelay=" + mCallRingDelay);
1158        pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
1159        pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
1160        pw.println(" mIccRecords=" + mIccRecords);
1161        pw.println(" mIccCard=" + mIccCard.get());
1162        pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
1163        pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
1164        pw.println(" mSMS=" + mSMS);
1165        pw.flush();
1166        pw.println(" mLooper=" + mLooper);
1167        pw.println(" mContext=" + mContext);
1168        pw.println(" mNotifier=" + mNotifier);
1169        pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
1170        pw.println(" mUnitTestMode=" + mUnitTestMode);
1171        pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
1172        pw.println(" getUnitTestMode()=" + getUnitTestMode());
1173        pw.println(" getState()=" + getState());
1174        pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
1175        pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
1176        pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
1177        pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
1178        pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
1179        pw.flush();
1180        pw.println(" isInEcm()=" + isInEcm());
1181        pw.println(" getPhoneName()=" + getPhoneName());
1182        pw.println(" getPhoneType()=" + getPhoneType());
1183        pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
1184        pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
1185        pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
1186        pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
1187    }
1188}
1189