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.commit(); 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 /** 509 * Subclasses of Phone probably want to replace this with a 510 * version scoped to their packages 511 */ 512 protected void notifyServiceStateChangedP(ServiceState ss) { 513 AsyncResult ar = new AsyncResult(null, ss, null); 514 mServiceStateRegistrants.notifyRegistrants(ar); 515 516 mNotifier.notifyServiceState(this); 517 } 518 519 // Inherited documentation suffices. 520 public SimulatedRadioControl getSimulatedRadioControl() { 521 return mSimulatedRadioControl; 522 } 523 524 /** 525 * Verifies the current thread is the same as the thread originally 526 * used in the initialization of this instance. Throws RuntimeException 527 * if not. 528 * 529 * @exception RuntimeException if the current thread is not 530 * the thread that originally obtained this PhoneBase instance. 531 */ 532 private void checkCorrectThread(Handler h) { 533 if (h.getLooper() != mLooper) { 534 throw new RuntimeException( 535 "com.android.internal.telephony.Phone must be used from within one thread"); 536 } 537 } 538 539 /** 540 * Set the properties by matching the carrier string in 541 * a string-array resource 542 */ 543 private void setPropertiesByCarrier() { 544 String carrier = SystemProperties.get("ro.carrier"); 545 546 if (null == carrier || 0 == carrier.length()) { 547 return; 548 } 549 550 CharSequence[] carrierLocales = mContext. 551 getResources().getTextArray(R.array.carrier_properties); 552 553 for (int i = 0; i < carrierLocales.length; i+=3) { 554 String c = carrierLocales[i].toString(); 555 if (carrier.equals(c)) { 556 String l = carrierLocales[i+1].toString(); 557 int wifiChannels = 0; 558 try { 559 wifiChannels = Integer.parseInt( 560 carrierLocales[i+2].toString()); 561 } catch (NumberFormatException e) { } 562 563 String language = l.substring(0, 2); 564 String country = ""; 565 if (l.length() >=5) { 566 country = l.substring(3, 5); 567 } 568 setSystemLocale(language, country); 569 570 if (wifiChannels != 0) { 571 try { 572 Settings.Secure.getInt(mContext.getContentResolver(), 573 Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS); 574 } catch (Settings.SettingNotFoundException e) { 575 // note this is not persisting 576 WifiManager wM = (WifiManager) 577 mContext.getSystemService(Context.WIFI_SERVICE); 578 wM.setNumAllowedChannels(wifiChannels, false); 579 } 580 } 581 return; 582 } 583 } 584 } 585 586 /** 587 * Utility code to set the system locale if it's not set already 588 * @param language Two character language code desired 589 * @param country Two character country code desired 590 * 591 * {@hide} 592 */ 593 public void setSystemLocale(String language, String country) { 594 String l = SystemProperties.get("persist.sys.language"); 595 String c = SystemProperties.get("persist.sys.country"); 596 597 if (null == language) { 598 return; // no match possible 599 } 600 language = language.toLowerCase(); 601 if (null == country) { 602 country = ""; 603 } 604 country = country.toUpperCase(); 605 606 if((null == l || 0 == l.length()) && (null == c || 0 == c.length())) { 607 try { 608 // try to find a good match 609 String[] locales = mContext.getAssets().getLocales(); 610 final int N = locales.length; 611 String bestMatch = null; 612 for(int i = 0; i < N; i++) { 613 // only match full (lang + country) locales 614 if (locales[i]!=null && locales[i].length() >= 5 && 615 locales[i].substring(0,2).equals(language)) { 616 if (locales[i].substring(3,5).equals(country)) { 617 bestMatch = locales[i]; 618 break; 619 } else if (null == bestMatch) { 620 bestMatch = locales[i]; 621 } 622 } 623 } 624 if (null != bestMatch) { 625 IActivityManager am = ActivityManagerNative.getDefault(); 626 Configuration config = am.getConfiguration(); 627 config.locale = new Locale(bestMatch.substring(0,2), 628 bestMatch.substring(3,5)); 629 config.userSetLocale = true; 630 am.updateConfiguration(config); 631 } 632 } catch (Exception e) { 633 // Intentionally left blank 634 } 635 } 636 } 637 638 /** 639 * Get state 640 */ 641 public abstract Phone.State getState(); 642 643 /** 644 * Retrieves the IccFileHandler of the Phone instance 645 */ 646 public abstract IccFileHandler getIccFileHandler(); 647 648 /* 649 * Retrieves the Handler of the Phone instance 650 */ 651 public Handler getHandler() { 652 return this; 653 } 654 655 /** 656 * Query the status of the CDMA roaming preference 657 */ 658 public void queryCdmaRoamingPreference(Message response) { 659 mCM.queryCdmaRoamingPreference(response); 660 } 661 662 /** 663 * Set the status of the CDMA roaming preference 664 */ 665 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 666 mCM.setCdmaRoamingPreference(cdmaRoamingType, response); 667 } 668 669 /** 670 * Set the status of the CDMA subscription mode 671 */ 672 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 673 mCM.setCdmaSubscription(cdmaSubscriptionType, response); 674 } 675 676 /** 677 * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only 678 */ 679 public void setPreferredNetworkType(int networkType, Message response) { 680 mCM.setPreferredNetworkType(networkType, response); 681 } 682 683 public void getPreferredNetworkType(Message response) { 684 mCM.getPreferredNetworkType(response); 685 } 686 687 public void getSmscAddress(Message result) { 688 mCM.getSmscAddress(result); 689 } 690 691 public void setSmscAddress(String address, Message result) { 692 mCM.setSmscAddress(address, result); 693 } 694 695 public void setTTYMode(int ttyMode, Message onComplete) { 696 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 697 logUnexpectedCdmaMethodCall("setTTYMode"); 698 } 699 700 public void queryTTYMode(Message onComplete) { 701 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 702 logUnexpectedCdmaMethodCall("queryTTYMode"); 703 } 704 705 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 706 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 707 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 708 } 709 710 public void getEnhancedVoicePrivacy(Message onComplete) { 711 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 712 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 713 } 714 715 public void setBandMode(int bandMode, Message response) { 716 mCM.setBandMode(bandMode, response); 717 } 718 719 public void queryAvailableBandMode(Message response) { 720 mCM.queryAvailableBandMode(response); 721 } 722 723 public void invokeOemRilRequestRaw(byte[] data, Message response) { 724 mCM.invokeOemRilRequestRaw(data, response); 725 } 726 727 public void invokeOemRilRequestStrings(String[] strings, Message response) { 728 mCM.invokeOemRilRequestStrings(strings, response); 729 } 730 731 public void notifyDataActivity() { 732 mNotifier.notifyDataActivity(this); 733 } 734 735 public void notifyMessageWaitingIndicator() { 736 // This function is added to send the notification to DefaultPhoneNotifier. 737 mNotifier.notifyMessageWaitingChanged(this); 738 } 739 740 public void notifyDataConnection(String reason) { 741 mNotifier.notifyDataConnection(this, reason); 742 } 743 744 public abstract String getPhoneName(); 745 746 public abstract int getPhoneType(); 747 748 /** @hide */ 749 public int getVoiceMessageCount(){ 750 return 0; 751 } 752 753 /** 754 * Returns the CDMA ERI icon index to display 755 */ 756 public int getCdmaEriIconIndex() { 757 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 758 return -1; 759 } 760 761 /** 762 * Returns the CDMA ERI icon mode, 763 * 0 - ON 764 * 1 - FLASHING 765 */ 766 public int getCdmaEriIconMode() { 767 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 768 return -1; 769 } 770 771 /** 772 * Returns the CDMA ERI text, 773 */ 774 public String getCdmaEriText() { 775 logUnexpectedCdmaMethodCall("getCdmaEriText"); 776 return "GSM nw, no ERI"; 777 } 778 779 public String getCdmaMin() { 780 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 781 logUnexpectedCdmaMethodCall("getCdmaMin"); 782 return null; 783 } 784 785 public boolean isMinInfoReady() { 786 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 787 logUnexpectedCdmaMethodCall("isMinInfoReady"); 788 return false; 789 } 790 791 public String getCdmaPrlVersion(){ 792 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 793 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 794 return null; 795 } 796 797 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 798 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 799 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 800 } 801 802 public void exitEmergencyCallbackMode() { 803 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 804 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 805 } 806 807 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 808 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 809 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 810 } 811 812 public void unregisterForCdmaOtaStatusChange(Handler h) { 813 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 814 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 815 } 816 817 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 818 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 819 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 820 } 821 822 public void unregisterForSubscriptionInfoReady(Handler h) { 823 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 824 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 825 } 826 827 public boolean isOtaSpNumber(String dialStr) { 828 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 829 logUnexpectedCdmaMethodCall("isOtaSpNumber"); 830 return false; 831 } 832 833 public void registerForCallWaiting(Handler h, int what, Object obj){ 834 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 835 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 836 } 837 838 public void unregisterForCallWaiting(Handler h){ 839 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 840 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 841 } 842 843 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 844 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 845 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 846 } 847 848 public void unregisterForEcmTimerReset(Handler h) { 849 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 850 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 851 } 852 853 public void registerForSignalInfo(Handler h, int what, Object obj) { 854 mCM.registerForSignalInfo(h, what, obj); 855 } 856 857 public void unregisterForSignalInfo(Handler h) { 858 mCM.unregisterForSignalInfo(h); 859 } 860 861 public void registerForDisplayInfo(Handler h, int what, Object obj) { 862 mCM.registerForDisplayInfo(h, what, obj); 863 } 864 865 public void unregisterForDisplayInfo(Handler h) { 866 mCM.unregisterForDisplayInfo(h); 867 } 868 869 public void registerForNumberInfo(Handler h, int what, Object obj) { 870 mCM.registerForNumberInfo(h, what, obj); 871 } 872 873 public void unregisterForNumberInfo(Handler h) { 874 mCM.unregisterForNumberInfo(h); 875 } 876 877 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 878 mCM.registerForRedirectedNumberInfo(h, what, obj); 879 } 880 881 public void unregisterForRedirectedNumberInfo(Handler h) { 882 mCM.unregisterForRedirectedNumberInfo(h); 883 } 884 885 public void registerForLineControlInfo(Handler h, int what, Object obj) { 886 mCM.registerForLineControlInfo( h, what, obj); 887 } 888 889 public void unregisterForLineControlInfo(Handler h) { 890 mCM.unregisterForLineControlInfo(h); 891 } 892 893 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 894 mCM.registerFoT53ClirlInfo(h, what, obj); 895 } 896 897 public void unregisterForT53ClirInfo(Handler h) { 898 mCM.unregisterForT53ClirInfo(h); 899 } 900 901 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 902 mCM.registerForT53AudioControlInfo( h, what, obj); 903 } 904 905 public void unregisterForT53AudioControlInfo(Handler h) { 906 mCM.unregisterForT53AudioControlInfo(h); 907 } 908 909 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 910 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 911 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 912 } 913 914 public void unsetOnEcbModeExitResponse(Handler h){ 915 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 916 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 917 } 918 919 public String getInterfaceName(String apnType) { 920 return mDataConnection.getInterfaceName(apnType); 921 } 922 923 public String getIpAddress(String apnType) { 924 return mDataConnection.getIpAddress(apnType); 925 } 926 927 public boolean isDataConnectivityEnabled() { 928 return mDataConnection.getDataEnabled(); 929 } 930 931 public String getGateway(String apnType) { 932 return mDataConnection.getGateway(apnType); 933 } 934 935 public String[] getDnsServers(String apnType) { 936 return mDataConnection.getDnsServers(apnType); 937 } 938 939 public String[] getActiveApnTypes() { 940 return mDataConnection.getActiveApnTypes(); 941 } 942 943 public String getActiveApn() { 944 return mDataConnection.getActiveApnString(); 945 } 946 947 public int enableApnType(String type) { 948 return mDataConnection.enableApnType(type); 949 } 950 951 public int disableApnType(String type) { 952 return mDataConnection.disableApnType(type); 953 } 954 955 /** 956 * simulateDataConnection 957 * 958 * simulates various data connection states. This messes with 959 * DataConnectionTracker's internal states, but doesn't actually change 960 * the underlying radio connection states. 961 * 962 * @param state Phone.DataState enum. 963 */ 964 public void simulateDataConnection(Phone.DataState state) { 965 DataConnectionTracker.State dcState; 966 967 switch (state) { 968 case CONNECTED: 969 dcState = DataConnectionTracker.State.CONNECTED; 970 break; 971 case SUSPENDED: 972 dcState = DataConnectionTracker.State.CONNECTED; 973 break; 974 case DISCONNECTED: 975 dcState = DataConnectionTracker.State.FAILED; 976 break; 977 default: 978 dcState = DataConnectionTracker.State.CONNECTING; 979 break; 980 } 981 982 mDataConnection.setState(dcState); 983 notifyDataConnection(null); 984 } 985 986 /** 987 * Notify registrants of a new ringing Connection. 988 * Subclasses of Phone probably want to replace this with a 989 * version scoped to their packages 990 */ 991 protected void notifyNewRingingConnectionP(Connection cn) { 992 AsyncResult ar = new AsyncResult(null, cn, null); 993 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 994 } 995 996 /** 997 * Notify registrants of a RING event. 998 */ 999 private void notifyIncomingRing() { 1000 AsyncResult ar = new AsyncResult(null, this, null); 1001 mIncomingRingRegistrants.notifyRegistrants(ar); 1002 } 1003 1004 /** 1005 * Send the incoming call Ring notification if conditions are right. 1006 */ 1007 private void sendIncomingCallRingNotification(int token) { 1008 if (!mDoesRilSendMultipleCallRing && (token == mCallRingContinueToken)) { 1009 Log.d(LOG_TAG, "Sending notifyIncomingRing"); 1010 notifyIncomingRing(); 1011 sendMessageDelayed( 1012 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1013 } else { 1014 Log.d(LOG_TAG, "Ignoring ring notification request," 1015 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1016 + " token=" + token 1017 + " mCallRingContinueToken=" + mCallRingContinueToken); 1018 } 1019 } 1020 1021 /** 1022 * Common error logger method for unexpected calls to CDMA-only methods. 1023 */ 1024 private void logUnexpectedCdmaMethodCall(String name) 1025 { 1026 Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1027 "called, CDMAPhone inactive."); 1028 } 1029 } 1030