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