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