• 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.app.ActivityManagerNative;
20 import android.app.IActivityManager;
21 import android.content.Context;
22 import android.content.res.Configuration;
23 import android.content.SharedPreferences;
24 import android.net.wifi.WifiManager;
25 import android.os.AsyncResult;
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.ServiceState;
34 import android.text.TextUtils;
35 import android.util.Log;
36 
37 import com.android.internal.R;
38 import com.android.internal.telephony.gsm.PdpConnection;
39 import com.android.internal.telephony.test.SimulatedRadioControl;
40 
41 import java.util.List;
42 import java.util.Locale;
43 
44 
45 /**
46  * (<em>Not for SDK use</em>)
47  * A base implementation for the com.android.internal.telephony.Phone interface.
48  *
49  * Note that implementations of Phone.java are expected to be used
50  * from a single application thread. This should be the same thread that
51  * originally called PhoneFactory to obtain the interface.
52  *
53  *  {@hide}
54  *
55  */
56 
57 public abstract class PhoneBase extends Handler implements Phone {
58     private static final String LOG_TAG = "PHONE";
59     private static final boolean LOCAL_DEBUG = true;
60 
61     // Key used to read and write the saved network selection numeric value
62     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
63     // Key used to read and write the saved network selection operator name
64     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
65 
66 
67     // Key used to read/write "disable data connection on boot" pref (used for testing)
68     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
69 
70     /* Event Constants */
71     protected static final int EVENT_RADIO_AVAILABLE             = 1;
72     /** Supplementary Service Notification received. */
73     protected static final int EVENT_SSN                         = 2;
74     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
75     protected static final int EVENT_MMI_DONE                    = 4;
76     protected static final int EVENT_RADIO_ON                    = 5;
77     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
78     protected static final int EVENT_USSD                        = 7;
79     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
80     protected static final int EVENT_GET_IMEI_DONE               = 9;
81     protected static final int EVENT_GET_IMEISV_DONE             = 10;
82     protected static final int EVENT_GET_SIM_STATUS_DONE         = 11;
83     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
84     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
85     protected static final int EVENT_CALL_RING                   = 14;
86     protected static final int EVENT_CALL_RING_CONTINUE          = 15;
87 
88     // Used to intercept the carrier selection calls so that
89     // we can save the values.
90     protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE    = 16;
91     protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17;
92     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
93     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
94     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
95     // Events for CDMA support
96     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
97     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
98     protected static final int EVENT_NV_READY                       = 23;
99     protected static final int EVENT_SET_ENHANCED_VP                = 24;
100     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
101     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
102 
103     // Key used to read/write current CLIR setting
104     public static final String CLIR_KEY = "clir_key";
105 
106     // Key used to read/write "disable DNS server check" pref (used for testing)
107     public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
108 
109     /* Instance Variables */
110     public CommandsInterface mCM;
111     protected IccFileHandler mIccFileHandler;
112     boolean mDnsCheckDisabled = false;
113     public DataConnectionTracker mDataConnection;
114     boolean mDoesRilSendMultipleCallRing;
115     int mCallRingContinueToken = 0;
116     int mCallRingDelay;
117 
118     /**
119      * Set a system property, unless we're in unit test mode
120      */
121     public void
setSystemProperty(String property, String value)122     setSystemProperty(String property, String value) {
123         if(getUnitTestMode()) {
124             return;
125         }
126         SystemProperties.set(property, value);
127     }
128 
129 
130     protected final RegistrantList mPreciseCallStateRegistrants
131             = new RegistrantList();
132 
133     protected final RegistrantList mNewRingingConnectionRegistrants
134             = new RegistrantList();
135 
136     protected final RegistrantList mIncomingRingRegistrants
137             = new RegistrantList();
138 
139     protected final RegistrantList mDisconnectRegistrants
140             = new RegistrantList();
141 
142     protected final RegistrantList mServiceStateRegistrants
143             = new RegistrantList();
144 
145     protected final RegistrantList mMmiCompleteRegistrants
146             = new RegistrantList();
147 
148     protected final RegistrantList mMmiRegistrants
149             = new RegistrantList();
150 
151     protected final RegistrantList mUnknownConnectionRegistrants
152             = new RegistrantList();
153 
154     protected final RegistrantList mSuppServiceFailedRegistrants
155             = new RegistrantList();
156 
157     protected Looper mLooper; /* to insure registrants are in correct thread*/
158 
159     protected Context mContext;
160 
161     /**
162      * PhoneNotifier is an abstraction for all system-wide
163      * state change notification. DefaultPhoneNotifier is
164      * used here unless running we're inside a unit test.
165      */
166     protected PhoneNotifier mNotifier;
167 
168     protected SimulatedRadioControl mSimulatedRadioControl;
169 
170     boolean mUnitTestMode;
171 
172     /**
173      * Constructs a PhoneBase in normal (non-unit test) mode.
174      *
175      * @param context Context object from hosting application
176      * @param notifier An instance of DefaultPhoneNotifier,
177      * unless unit testing.
178      */
PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci)179     protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci) {
180         this(notifier, context, ci, false);
181     }
182 
183     /**
184      * Constructs a PhoneBase in normal (non-unit test) mode.
185      *
186      * @param context Context object from hosting application
187      * @param notifier An instance of DefaultPhoneNotifier,
188      * unless unit testing.
189      * @param unitTestMode when true, prevents notifications
190      * of state change events
191      */
PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode)192     protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci,
193             boolean unitTestMode) {
194         this.mNotifier = notifier;
195         this.mContext = context;
196         mLooper = Looper.myLooper();
197         mCM = ci;
198 
199         setPropertiesByCarrier();
200 
201         setUnitTestMode(unitTestMode);
202 
203         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
204         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
205         mCM.setOnCallRing(this, EVENT_CALL_RING, null);
206 
207         /**
208          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
209          *  to be generated locally. Ideally all ring tones should be loops
210          * and this wouldn't be necessary. But to minimize changes to upper
211          * layers it is requested that it be generated by lower layers.
212          *
213          * By default old phones won't have the property set but do generate
214          * the RIL_UNSOL_CALL_RING so the default if there is no property is
215          * true.
216          */
217         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
218                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
219         Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
220 
221         mCallRingDelay = SystemProperties.getInt(
222                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
223         Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
224     }
225 
dispose()226     public void dispose() {
227         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
228             mCM.unSetOnCallRing(this);
229         }
230     }
231 
232     /**
233      * When overridden the derived class needs to call
234      * super.handleMessage(msg) so this method has a
235      * a chance to process the message.
236      *
237      * @param msg
238      */
239     @Override
handleMessage(Message msg)240     public void handleMessage(Message msg) {
241         AsyncResult ar;
242 
243         switch(msg.what) {
244             case EVENT_CALL_RING:
245                 Log.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
246                 ar = (AsyncResult)msg.obj;
247                 if (ar.exception == null) {
248                     Phone.State state = getState();
249                     if ((!mDoesRilSendMultipleCallRing)
250                             && ((state == Phone.State.RINGING) || (state == Phone.State.IDLE))) {
251                         mCallRingContinueToken += 1;
252                         sendIncomingCallRingNotification(mCallRingContinueToken);
253                     } else {
254                         notifyIncomingRing();
255                     }
256                 }
257                 break;
258 
259             case EVENT_CALL_RING_CONTINUE:
260                 Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
261                 if (getState() == Phone.State.RINGING) {
262                     sendIncomingCallRingNotification(msg.arg1);
263                 }
264                 break;
265 
266             default:
267                 throw new RuntimeException("unexpected event not handled");
268         }
269     }
270 
271     // Inherited documentation suffices.
getContext()272     public Context getContext() {
273         return mContext;
274     }
275 
276     /**
277      * Disables the DNS check (i.e., allows "0.0.0.0").
278      * Useful for lab testing environment.
279      * @param b true disables the check, false enables.
280      */
disableDnsCheck(boolean b)281     public void disableDnsCheck(boolean b) {
282         mDnsCheckDisabled = b;
283         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
284         SharedPreferences.Editor editor = sp.edit();
285         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
286         editor.commit();
287     }
288 
289     /**
290      * Returns true if the DNS check is currently disabled.
291      */
isDnsCheckDisabled()292     public boolean isDnsCheckDisabled() {
293         return mDnsCheckDisabled;
294     }
295 
296     // Inherited documentation suffices.
registerForPreciseCallStateChanged(Handler h, int what, Object obj)297     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
298         checkCorrectThread(h);
299 
300         mPreciseCallStateRegistrants.addUnique(h, what, obj);
301     }
302 
303     // Inherited documentation suffices.
unregisterForPreciseCallStateChanged(Handler h)304     public void unregisterForPreciseCallStateChanged(Handler h) {
305         mPreciseCallStateRegistrants.remove(h);
306     }
307 
308     /**
309      * Subclasses of Phone probably want to replace this with a
310      * version scoped to their packages
311      */
notifyPreciseCallStateChangedP()312     protected void notifyPreciseCallStateChangedP() {
313         AsyncResult ar = new AsyncResult(null, this, null);
314         mPreciseCallStateRegistrants.notifyRegistrants(ar);
315     }
316 
317     // Inherited documentation suffices.
registerForUnknownConnection(Handler h, int what, Object obj)318     public void registerForUnknownConnection(Handler h, int what, Object obj) {
319         checkCorrectThread(h);
320 
321         mUnknownConnectionRegistrants.addUnique(h, what, obj);
322     }
323 
324     // Inherited documentation suffices.
unregisterForUnknownConnection(Handler h)325     public void unregisterForUnknownConnection(Handler h) {
326         mUnknownConnectionRegistrants.remove(h);
327     }
328 
329     // Inherited documentation suffices.
registerForNewRingingConnection( Handler h, int what, Object obj)330     public void registerForNewRingingConnection(
331             Handler h, int what, Object obj) {
332         checkCorrectThread(h);
333 
334         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
335     }
336 
337     // Inherited documentation suffices.
unregisterForNewRingingConnection(Handler h)338     public void unregisterForNewRingingConnection(Handler h) {
339         mNewRingingConnectionRegistrants.remove(h);
340     }
341 
342     // Inherited documentation suffices.
registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)343     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
344         mCM.registerForInCallVoicePrivacyOn(h,what,obj);
345     }
346 
347     // Inherited documentation suffices.
unregisterForInCallVoicePrivacyOn(Handler h)348     public void unregisterForInCallVoicePrivacyOn(Handler h){
349         mCM.unregisterForInCallVoicePrivacyOn(h);
350     }
351 
352     // Inherited documentation suffices.
registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)353     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
354         mCM.registerForInCallVoicePrivacyOff(h,what,obj);
355     }
356 
357     // Inherited documentation suffices.
unregisterForInCallVoicePrivacyOff(Handler h)358     public void unregisterForInCallVoicePrivacyOff(Handler h){
359         mCM.unregisterForInCallVoicePrivacyOff(h);
360     }
361 
362     // Inherited documentation suffices.
registerForIncomingRing( Handler h, int what, Object obj)363     public void registerForIncomingRing(
364             Handler h, int what, Object obj) {
365         checkCorrectThread(h);
366 
367         mIncomingRingRegistrants.addUnique(h, what, obj);
368     }
369 
370     // Inherited documentation suffices.
unregisterForIncomingRing(Handler h)371     public void unregisterForIncomingRing(Handler h) {
372         mIncomingRingRegistrants.remove(h);
373     }
374 
375     // Inherited documentation suffices.
registerForDisconnect(Handler h, int what, Object obj)376     public void registerForDisconnect(Handler h, int what, Object obj) {
377         checkCorrectThread(h);
378 
379         mDisconnectRegistrants.addUnique(h, what, obj);
380     }
381 
382     // Inherited documentation suffices.
unregisterForDisconnect(Handler h)383     public void unregisterForDisconnect(Handler h) {
384         mDisconnectRegistrants.remove(h);
385     }
386 
387     // Inherited documentation suffices.
registerForSuppServiceFailed(Handler h, int what, Object obj)388     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
389         checkCorrectThread(h);
390 
391         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
392     }
393 
394     // Inherited documentation suffices.
unregisterForSuppServiceFailed(Handler h)395     public void unregisterForSuppServiceFailed(Handler h) {
396         mSuppServiceFailedRegistrants.remove(h);
397     }
398 
399     // Inherited documentation suffices.
registerForMmiInitiate(Handler h, int what, Object obj)400     public void registerForMmiInitiate(Handler h, int what, Object obj) {
401         checkCorrectThread(h);
402 
403         mMmiRegistrants.addUnique(h, what, obj);
404     }
405 
406     // Inherited documentation suffices.
unregisterForMmiInitiate(Handler h)407     public void unregisterForMmiInitiate(Handler h) {
408         mMmiRegistrants.remove(h);
409     }
410 
411     // Inherited documentation suffices.
registerForMmiComplete(Handler h, int what, Object obj)412     public void registerForMmiComplete(Handler h, int what, Object obj) {
413         checkCorrectThread(h);
414 
415         mMmiCompleteRegistrants.addUnique(h, what, obj);
416     }
417 
418     // Inherited documentation suffices.
unregisterForMmiComplete(Handler h)419     public void unregisterForMmiComplete(Handler h) {
420         checkCorrectThread(h);
421 
422         mMmiCompleteRegistrants.remove(h);
423     }
424 
425     /**
426      * Method to retrieve the saved operator id from the Shared Preferences
427      */
getSavedNetworkSelection()428     private String getSavedNetworkSelection() {
429         // open the shared preferences and search with our key.
430         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
431         return sp.getString(NETWORK_SELECTION_KEY, "");
432     }
433 
434     /**
435      * Method to restore the previously saved operator id, or reset to
436      * automatic selection, all depending upon the value in the shared
437      * preferences.
438      */
restoreSavedNetworkSelection(Message response)439     public void restoreSavedNetworkSelection(Message response) {
440         // retrieve the operator id
441         String networkSelection = getSavedNetworkSelection();
442 
443         // set to auto if the id is empty, otherwise select the network.
444         if (TextUtils.isEmpty(networkSelection)) {
445             mCM.setNetworkSelectionModeAutomatic(response);
446         } else {
447             mCM.setNetworkSelectionModeManual(networkSelection, response);
448         }
449     }
450 
451     // Inherited documentation suffices.
setUnitTestMode(boolean f)452     public void setUnitTestMode(boolean f) {
453         mUnitTestMode = f;
454     }
455 
456     // Inherited documentation suffices.
getUnitTestMode()457     public boolean getUnitTestMode() {
458         return mUnitTestMode;
459     }
460 
461     /**
462      * To be invoked when a voice call Connection disconnects.
463      *
464      * Subclasses of Phone probably want to replace this with a
465      * version scoped to their packages
466      */
notifyDisconnectP(Connection cn)467     protected void notifyDisconnectP(Connection cn) {
468         AsyncResult ar = new AsyncResult(null, cn, null);
469         mDisconnectRegistrants.notifyRegistrants(ar);
470     }
471 
472     // Inherited documentation suffices.
registerForServiceStateChanged( Handler h, int what, Object obj)473     public void registerForServiceStateChanged(
474             Handler h, int what, Object obj) {
475         checkCorrectThread(h);
476 
477         mServiceStateRegistrants.add(h, what, obj);
478     }
479 
480     // Inherited documentation suffices.
unregisterForServiceStateChanged(Handler h)481     public void unregisterForServiceStateChanged(Handler h) {
482         mServiceStateRegistrants.remove(h);
483     }
484 
485     // Inherited documentation suffices.
registerForRingbackTone(Handler h, int what, Object obj)486     public void registerForRingbackTone(Handler h, int what, Object obj) {
487         mCM.registerForRingbackTone(h,what,obj);
488     }
489 
490     // Inherited documentation suffices.
unregisterForRingbackTone(Handler h)491     public void unregisterForRingbackTone(Handler h) {
492         mCM.unregisterForRingbackTone(h);
493     }
494 
495     /**
496      * Subclasses of Phone probably want to replace this with a
497      * version scoped to their packages
498      */
notifyServiceStateChangedP(ServiceState ss)499     protected void notifyServiceStateChangedP(ServiceState ss) {
500         AsyncResult ar = new AsyncResult(null, ss, null);
501         mServiceStateRegistrants.notifyRegistrants(ar);
502 
503         mNotifier.notifyServiceState(this);
504     }
505 
506     // Inherited documentation suffices.
getSimulatedRadioControl()507     public SimulatedRadioControl getSimulatedRadioControl() {
508         return mSimulatedRadioControl;
509     }
510 
511     /**
512      * Verifies the current thread is the same as the thread originally
513      * used in the initialization of this instance. Throws RuntimeException
514      * if not.
515      *
516      * @exception RuntimeException if the current thread is not
517      * the thread that originally obtained this PhoneBase instance.
518      */
checkCorrectThread(Handler h)519     private void checkCorrectThread(Handler h) {
520         if (h.getLooper() != mLooper) {
521             throw new RuntimeException(
522                     "com.android.internal.telephony.Phone must be used from within one thread");
523         }
524     }
525 
526     /**
527      * Set the properties by matching the carrier string in
528      * a string-array resource
529      */
setPropertiesByCarrier()530     private void setPropertiesByCarrier() {
531         String carrier = SystemProperties.get("ro.carrier");
532 
533         if (null == carrier || 0 == carrier.length()) {
534             return;
535         }
536 
537         CharSequence[] carrierLocales = mContext.
538                 getResources().getTextArray(R.array.carrier_properties);
539 
540         for (int i = 0; i < carrierLocales.length; i+=3) {
541             String c = carrierLocales[i].toString();
542             if (carrier.equals(c)) {
543                 String l = carrierLocales[i+1].toString();
544                 int wifiChannels = 0;
545                 try {
546                     wifiChannels = Integer.parseInt(
547                             carrierLocales[i+2].toString());
548                 } catch (NumberFormatException e) { }
549 
550                 String language = l.substring(0, 2);
551                 String country = "";
552                 if (l.length() >=5) {
553                     country = l.substring(3, 5);
554                 }
555                 setSystemLocale(language, country);
556 
557                 if (wifiChannels != 0) {
558                     try {
559                         Settings.Secure.getInt(mContext.getContentResolver(),
560                                 Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
561                     } catch (Settings.SettingNotFoundException e) {
562                         // note this is not persisting
563                         WifiManager wM = (WifiManager)
564                                 mContext.getSystemService(Context.WIFI_SERVICE);
565                         wM.setNumAllowedChannels(wifiChannels, false);
566                     }
567                 }
568                 return;
569             }
570         }
571     }
572 
573     /**
574      * Utility code to set the system locale if it's not set already
575      * @param langauge Two character language code desired
576      * @param country Two character country code desired
577      *
578      *  {@hide}
579      */
setSystemLocale(String language, String country)580     public void setSystemLocale(String language, String country) {
581         String l = SystemProperties.get("persist.sys.language");
582         String c = SystemProperties.get("persist.sys.country");
583 
584         if (null == language) {
585             return; // no match possible
586         }
587         language = language.toLowerCase();
588         if (null == country) {
589             country = "";
590         }
591         country = country.toUpperCase();
592 
593         if((null == l || 0 == l.length()) && (null == c || 0 == c.length())) {
594             try {
595                 // try to find a good match
596                 String[] locales = mContext.getAssets().getLocales();
597                 final int N = locales.length;
598                 String bestMatch = null;
599                 for(int i = 0; i < N; i++) {
600                     // only match full (lang + country) locales
601                     if (locales[i]!=null && locales[i].length() >= 5 &&
602                             locales[i].substring(0,2).equals(language)) {
603                         if (locales[i].substring(3,5).equals(country)) {
604                             bestMatch = locales[i];
605                             break;
606                         } else if (null == bestMatch) {
607                             bestMatch = locales[i];
608                         }
609                     }
610                 }
611                 if (null != bestMatch) {
612                     IActivityManager am = ActivityManagerNative.getDefault();
613                     Configuration config = am.getConfiguration();
614                     config.locale = new Locale(bestMatch.substring(0,2),
615                                                bestMatch.substring(3,5));
616                     config.userSetLocale = true;
617                     am.updateConfiguration(config);
618                 }
619             } catch (Exception e) {
620                 // Intentionally left blank
621             }
622         }
623     }
624 
625     /**
626      * Get state
627      */
getState()628     public abstract Phone.State getState();
629 
630     /**
631      * Retrieves the IccFileHandler of the Phone instance
632      */
getIccFileHandler()633     public abstract IccFileHandler getIccFileHandler();
634 
635     /*
636      * Retrieves the Handler of the Phone instance
637      */
getHandler()638     public Handler getHandler() {
639         return this;
640     }
641 
642     /**
643      *  Query the status of the CDMA roaming preference
644      */
queryCdmaRoamingPreference(Message response)645     public void queryCdmaRoamingPreference(Message response) {
646         mCM.queryCdmaRoamingPreference(response);
647     }
648 
649     /**
650      *  Set the status of the CDMA roaming preference
651      */
setCdmaRoamingPreference(int cdmaRoamingType, Message response)652     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
653         mCM.setCdmaRoamingPreference(cdmaRoamingType, response);
654     }
655 
656     /**
657      *  Set the status of the CDMA subscription mode
658      */
setCdmaSubscription(int cdmaSubscriptionType, Message response)659     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
660         mCM.setCdmaSubscription(cdmaSubscriptionType, response);
661     }
662 
663     /**
664      *  Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
665      */
setPreferredNetworkType(int networkType, Message response)666     public void setPreferredNetworkType(int networkType, Message response) {
667         mCM.setPreferredNetworkType(networkType, response);
668     }
669 
getPreferredNetworkType(Message response)670     public void getPreferredNetworkType(Message response) {
671         mCM.getPreferredNetworkType(response);
672     }
673 
getSmscAddress(Message result)674     public void getSmscAddress(Message result) {
675         mCM.getSmscAddress(result);
676     }
677 
setSmscAddress(String address, Message result)678     public void setSmscAddress(String address, Message result) {
679         mCM.setSmscAddress(address, result);
680     }
681 
setTTYMode(int ttyMode, Message onComplete)682     public void setTTYMode(int ttyMode, Message onComplete) {
683         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
684         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
685     }
686 
queryTTYMode(Message onComplete)687     public void queryTTYMode(Message onComplete) {
688         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
689         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
690     }
691 
692     /**
693      * This should only be called in GSM mode.
694      * Only here for some backward compatibility
695      * issues concerning the GSMPhone class.
696      * @deprecated Always returns null.
697      */
getCurrentPdpList()698     public List<PdpConnection> getCurrentPdpList() {
699         return null;
700     }
701 
enableEnhancedVoicePrivacy(boolean enable, Message onComplete)702     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
703         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
704         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
705     }
706 
getEnhancedVoicePrivacy(Message onComplete)707     public void getEnhancedVoicePrivacy(Message onComplete) {
708         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
709         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
710     }
711 
setBandMode(int bandMode, Message response)712     public void setBandMode(int bandMode, Message response) {
713         mCM.setBandMode(bandMode, response);
714     }
715 
queryAvailableBandMode(Message response)716     public void queryAvailableBandMode(Message response) {
717         mCM.queryAvailableBandMode(response);
718     }
719 
invokeOemRilRequestRaw(byte[] data, Message response)720     public void invokeOemRilRequestRaw(byte[] data, Message response) {
721         mCM.invokeOemRilRequestRaw(data, response);
722     }
723 
invokeOemRilRequestStrings(String[] strings, Message response)724     public void invokeOemRilRequestStrings(String[] strings, Message response) {
725         mCM.invokeOemRilRequestStrings(strings, response);
726     }
727 
notifyDataActivity()728     public void notifyDataActivity() {
729         mNotifier.notifyDataActivity(this);
730     }
731 
notifyMessageWaitingIndicator()732     public void notifyMessageWaitingIndicator() {
733         // This function is added to send the notification to DefaultPhoneNotifier.
734         mNotifier.notifyMessageWaitingChanged(this);
735     }
736 
notifyDataConnection(String reason)737     public void notifyDataConnection(String reason) {
738         mNotifier.notifyDataConnection(this, reason);
739     }
740 
getPhoneName()741     public abstract String getPhoneName();
742 
getPhoneType()743     public abstract int getPhoneType();
744 
745     /** @hide */
getVoiceMessageCount()746     public int getVoiceMessageCount(){
747         return 0;
748     }
749 
750     /**
751      * Returns the CDMA ERI icon index to display
752      */
getCdmaEriIconIndex()753     public int getCdmaEriIconIndex() {
754         Log.e(LOG_TAG, "Error! getCdmaEriIconIndex should never be executed in GSM mode");
755         return -1;
756     }
757 
758     /**
759      * Returns the CDMA ERI icon mode,
760      * 0 - ON
761      * 1 - FLASHING
762      */
getCdmaEriIconMode()763     public int getCdmaEriIconMode() {
764         Log.e(LOG_TAG, "Error! getCdmaEriIconMode should never be executed in GSM mode");
765         return -1;
766     }
767 
768     /**
769      * Returns the CDMA ERI text,
770      */
getCdmaEriText()771     public String getCdmaEriText() {
772         Log.e(LOG_TAG, "Error! getCdmaEriText should never be executed in GSM mode");
773         return "GSM nw, no ERI";
774     }
775 
getCdmaMin()776     public String getCdmaMin() {
777         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
778         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
779         return null;
780     }
781 
isMinInfoReady()782     public boolean isMinInfoReady() {
783         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
784         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
785         return false;
786     }
787 
getCdmaPrlVersion()788     public String getCdmaPrlVersion(){
789         //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
790         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
791         return null;
792     }
793 
sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)794     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
795         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
796         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
797     }
798 
exitEmergencyCallbackMode()799     public void exitEmergencyCallbackMode() {
800         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
801         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
802     }
803 
registerForCdmaOtaStatusChange(Handler h, int what, Object obj)804     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
805         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
806         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
807     }
808 
unregisterForCdmaOtaStatusChange(Handler h)809     public void unregisterForCdmaOtaStatusChange(Handler h) {
810         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
811         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
812     }
813 
registerForSubscriptionInfoReady(Handler h, int what, Object obj)814     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
815         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
816         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
817     }
818 
unregisterForSubscriptionInfoReady(Handler h)819     public void unregisterForSubscriptionInfoReady(Handler h) {
820         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
821         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
822     }
823 
isOtaSpNumber(String dialStr)824     public  boolean isOtaSpNumber(String dialStr) {
825         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
826         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
827         return false;
828     }
829 
registerForCallWaiting(Handler h, int what, Object obj)830     public void registerForCallWaiting(Handler h, int what, Object obj){
831         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
832         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
833     }
834 
unregisterForCallWaiting(Handler h)835     public void unregisterForCallWaiting(Handler h){
836         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
837         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
838     }
839 
registerForEcmTimerReset(Handler h, int what, Object obj)840     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
841         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
842         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
843     }
844 
unregisterForEcmTimerReset(Handler h)845     public void unregisterForEcmTimerReset(Handler h) {
846         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
847         Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
848     }
849 
registerForSignalInfo(Handler h, int what, Object obj)850     public void registerForSignalInfo(Handler h, int what, Object obj) {
851         mCM.registerForSignalInfo(h, what, obj);
852     }
853 
unregisterForSignalInfo(Handler h)854     public void unregisterForSignalInfo(Handler h) {
855         mCM.unregisterForSignalInfo(h);
856     }
857 
registerForDisplayInfo(Handler h, int what, Object obj)858     public void registerForDisplayInfo(Handler h, int what, Object obj) {
859         mCM.registerForDisplayInfo(h, what, obj);
860     }
861 
unregisterForDisplayInfo(Handler h)862      public void unregisterForDisplayInfo(Handler h) {
863          mCM.unregisterForDisplayInfo(h);
864      }
865 
registerForNumberInfo(Handler h, int what, Object obj)866     public void registerForNumberInfo(Handler h, int what, Object obj) {
867         mCM.registerForNumberInfo(h, what, obj);
868     }
869 
unregisterForNumberInfo(Handler h)870     public void unregisterForNumberInfo(Handler h) {
871         mCM.unregisterForNumberInfo(h);
872     }
873 
registerForRedirectedNumberInfo(Handler h, int what, Object obj)874     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
875         mCM.registerForRedirectedNumberInfo(h, what, obj);
876     }
877 
unregisterForRedirectedNumberInfo(Handler h)878     public void unregisterForRedirectedNumberInfo(Handler h) {
879         mCM.unregisterForRedirectedNumberInfo(h);
880     }
881 
registerForLineControlInfo(Handler h, int what, Object obj)882     public void registerForLineControlInfo(Handler h, int what, Object obj) {
883         mCM.registerForLineControlInfo( h, what, obj);
884     }
885 
unregisterForLineControlInfo(Handler h)886     public void unregisterForLineControlInfo(Handler h) {
887         mCM.unregisterForLineControlInfo(h);
888     }
889 
registerFoT53ClirlInfo(Handler h, int what, Object obj)890     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
891         mCM.registerFoT53ClirlInfo(h, what, obj);
892     }
893 
unregisterForT53ClirInfo(Handler h)894     public void unregisterForT53ClirInfo(Handler h) {
895         mCM.unregisterForT53ClirInfo(h);
896     }
897 
registerForT53AudioControlInfo(Handler h, int what, Object obj)898     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
899         mCM.registerForT53AudioControlInfo( h, what, obj);
900     }
901 
unregisterForT53AudioControlInfo(Handler h)902     public void unregisterForT53AudioControlInfo(Handler h) {
903         mCM.unregisterForT53AudioControlInfo(h);
904     }
905 
setOnEcbModeExitResponse(Handler h, int what, Object obj)906      public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
907          // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
908          Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
909      }
910 
unsetOnEcbModeExitResponse(Handler h)911      public void unsetOnEcbModeExitResponse(Handler h){
912         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
913          Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
914      }
915 
getInterfaceName(String apnType)916     public String getInterfaceName(String apnType) {
917         return mDataConnection.getInterfaceName(apnType);
918     }
919 
getIpAddress(String apnType)920     public String getIpAddress(String apnType) {
921         return mDataConnection.getIpAddress(apnType);
922     }
923 
isDataConnectivityEnabled()924     public boolean isDataConnectivityEnabled() {
925         return mDataConnection.getDataEnabled();
926     }
927 
getGateway(String apnType)928     public String getGateway(String apnType) {
929         return mDataConnection.getGateway(apnType);
930     }
931 
getDnsServers(String apnType)932     public String[] getDnsServers(String apnType) {
933         return mDataConnection.getDnsServers(apnType);
934     }
935 
getActiveApnTypes()936     public String[] getActiveApnTypes() {
937         return mDataConnection.getActiveApnTypes();
938     }
939 
getActiveApn()940     public String getActiveApn() {
941         return mDataConnection.getActiveApnString();
942     }
943 
enableApnType(String type)944     public int enableApnType(String type) {
945         return mDataConnection.enableApnType(type);
946     }
947 
disableApnType(String type)948     public int disableApnType(String type) {
949         return mDataConnection.disableApnType(type);
950     }
951 
952     /**
953      * simulateDataConnection
954      *
955      * simulates various data connection states. This messes with
956      * DataConnectionTracker's internal states, but doesn't actually change
957      * the underlying radio connection states.
958      *
959      * @param state Phone.DataState enum.
960      */
simulateDataConnection(Phone.DataState state)961     public void simulateDataConnection(Phone.DataState state) {
962         DataConnectionTracker.State dcState;
963 
964         switch (state) {
965             case CONNECTED:
966                 dcState = DataConnectionTracker.State.CONNECTED;
967                 break;
968             case SUSPENDED:
969                 dcState = DataConnectionTracker.State.CONNECTED;
970                 break;
971             case DISCONNECTED:
972                 dcState = DataConnectionTracker.State.FAILED;
973                 break;
974             default:
975                 dcState = DataConnectionTracker.State.CONNECTING;
976                 break;
977         }
978 
979         mDataConnection.setState(dcState);
980         notifyDataConnection(null);
981     }
982 
983     /**
984      * Notifiy registrants of a new ringing Connection.
985      * Subclasses of Phone probably want to replace this with a
986      * version scoped to their packages
987      */
notifyNewRingingConnectionP(Connection cn)988     protected void notifyNewRingingConnectionP(Connection cn) {
989         AsyncResult ar = new AsyncResult(null, cn, null);
990         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
991     }
992 
993     /**
994      * Notify registrants of a RING event.
995      */
notifyIncomingRing()996     private void notifyIncomingRing() {
997         AsyncResult ar = new AsyncResult(null, this, null);
998         mIncomingRingRegistrants.notifyRegistrants(ar);
999     }
1000 
1001     /**
1002      * Send the incoming call Ring notification if conditions are right.
1003      */
sendIncomingCallRingNotification(int token)1004     private void sendIncomingCallRingNotification(int token) {
1005         if (!mDoesRilSendMultipleCallRing && (token == mCallRingContinueToken)) {
1006             Log.d(LOG_TAG, "Sending notifyIncomingRing");
1007             notifyIncomingRing();
1008             sendMessageDelayed(
1009                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
1010         } else {
1011             Log.d(LOG_TAG, "Ignoring ring notification request,"
1012                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
1013                     + " token=" + token
1014                     + " mCallRingContinueToken=" + mCallRingContinueToken);
1015         }
1016     }
1017 }
1018