OSDN Git Service

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