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 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 701 logUnexpectedCdmaMethodCall("setTTYMode"); 702 } 703 704 public void queryTTYMode(Message onComplete) { 705 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 706 logUnexpectedCdmaMethodCall("queryTTYMode"); 707 } 708 709 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 710 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 711 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 712 } 713 714 public void getEnhancedVoicePrivacy(Message onComplete) { 715 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 716 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 717 } 718 719 public void setBandMode(int bandMode, Message response) { 720 mCM.setBandMode(bandMode, response); 721 } 722 723 public void queryAvailableBandMode(Message response) { 724 mCM.queryAvailableBandMode(response); 725 } 726 727 public void invokeOemRilRequestRaw(byte[] data, Message response) { 728 mCM.invokeOemRilRequestRaw(data, response); 729 } 730 731 public void invokeOemRilRequestStrings(String[] strings, Message response) { 732 mCM.invokeOemRilRequestStrings(strings, response); 733 } 734 735 public void notifyDataActivity() { 736 mNotifier.notifyDataActivity(this); 737 } 738 739 public void notifyMessageWaitingIndicator() { 740 // This function is added to send the notification to DefaultPhoneNotifier. 741 mNotifier.notifyMessageWaitingChanged(this); 742 } 743 744 public void notifyDataConnection(String reason) { 745 mNotifier.notifyDataConnection(this, reason); 746 } 747 748 public abstract String getPhoneName(); 749 750 public abstract int getPhoneType(); 751 752 /** @hide */ 753 public int getVoiceMessageCount(){ 754 return 0; 755 } 756 757 /** 758 * Returns the CDMA ERI icon index to display 759 */ 760 public int getCdmaEriIconIndex() { 761 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 762 return -1; 763 } 764 765 /** 766 * Returns the CDMA ERI icon mode, 767 * 0 - ON 768 * 1 - FLASHING 769 */ 770 public int getCdmaEriIconMode() { 771 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 772 return -1; 773 } 774 775 /** 776 * Returns the CDMA ERI text, 777 */ 778 public String getCdmaEriText() { 779 logUnexpectedCdmaMethodCall("getCdmaEriText"); 780 return "GSM nw, no ERI"; 781 } 782 783 public String getCdmaMin() { 784 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 785 logUnexpectedCdmaMethodCall("getCdmaMin"); 786 return null; 787 } 788 789 public boolean isMinInfoReady() { 790 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 791 logUnexpectedCdmaMethodCall("isMinInfoReady"); 792 return false; 793 } 794 795 public String getCdmaPrlVersion(){ 796 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 797 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 798 return null; 799 } 800 801 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 802 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 803 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 804 } 805 806 public void exitEmergencyCallbackMode() { 807 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 808 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 809 } 810 811 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 812 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 813 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 814 } 815 816 public void unregisterForCdmaOtaStatusChange(Handler h) { 817 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 818 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 819 } 820 821 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 822 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 823 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 824 } 825 826 public void unregisterForSubscriptionInfoReady(Handler h) { 827 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 828 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 829 } 830 831 public boolean isOtaSpNumber(String dialStr) { 832 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 833 logUnexpectedCdmaMethodCall("isOtaSpNumber"); 834 return false; 835 } 836 837 public void registerForCallWaiting(Handler h, int what, Object obj){ 838 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 839 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 840 } 841 842 public void unregisterForCallWaiting(Handler h){ 843 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 844 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 845 } 846 847 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 848 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 849 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 850 } 851 852 public void unregisterForEcmTimerReset(Handler h) { 853 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 854 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 855 } 856 857 public void registerForSignalInfo(Handler h, int what, Object obj) { 858 mCM.registerForSignalInfo(h, what, obj); 859 } 860 861 public void unregisterForSignalInfo(Handler h) { 862 mCM.unregisterForSignalInfo(h); 863 } 864 865 public void registerForDisplayInfo(Handler h, int what, Object obj) { 866 mCM.registerForDisplayInfo(h, what, obj); 867 } 868 869 public void unregisterForDisplayInfo(Handler h) { 870 mCM.unregisterForDisplayInfo(h); 871 } 872 873 public void registerForNumberInfo(Handler h, int what, Object obj) { 874 mCM.registerForNumberInfo(h, what, obj); 875 } 876 877 public void unregisterForNumberInfo(Handler h) { 878 mCM.unregisterForNumberInfo(h); 879 } 880 881 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 882 mCM.registerForRedirectedNumberInfo(h, what, obj); 883 } 884 885 public void unregisterForRedirectedNumberInfo(Handler h) { 886 mCM.unregisterForRedirectedNumberInfo(h); 887 } 888 889 public void registerForLineControlInfo(Handler h, int what, Object obj) { 890 mCM.registerForLineControlInfo( h, what, obj); 891 } 892 893 public void unregisterForLineControlInfo(Handler h) { 894 mCM.unregisterForLineControlInfo(h); 895 } 896 897 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 898 mCM.registerFoT53ClirlInfo(h, what, obj); 899 } 900 901 public void unregisterForT53ClirInfo(Handler h) { 902 mCM.unregisterForT53ClirInfo(h); 903 } 904 905 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 906 mCM.registerForT53AudioControlInfo( h, what, obj); 907 } 908 909 public void unregisterForT53AudioControlInfo(Handler h) { 910 mCM.unregisterForT53AudioControlInfo(h); 911 } 912 913 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 914 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 915 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 916 } 917 918 public void unsetOnEcbModeExitResponse(Handler h){ 919 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 920 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 921 } 922 923 public String getInterfaceName(String apnType) { 924 return mDataConnection.getInterfaceName(apnType); 925 } 926 927 public String getIpAddress(String apnType) { 928 return mDataConnection.getIpAddress(apnType); 929 } 930 931 public boolean isDataConnectivityEnabled() { 932 return mDataConnection.getDataEnabled(); 933 } 934 935 public String getGateway(String apnType) { 936 return mDataConnection.getGateway(apnType); 937 } 938 939 public String[] getDnsServers(String apnType) { 940 return mDataConnection.getDnsServers(apnType); 941 } 942 943 public String[] getActiveApnTypes() { 944 return mDataConnection.getActiveApnTypes(); 945 } 946 947 public String getActiveApn() { 948 return mDataConnection.getActiveApnString(); 949 } 950 951 public int enableApnType(String type) { 952 return mDataConnection.enableApnType(type); 953 } 954 955 public int disableApnType(String type) { 956 return mDataConnection.disableApnType(type); 957 } 958 959 /** 960 * simulateDataConnection 961 * 962 * simulates various data connection states. This messes with 963 * DataConnectionTracker's internal states, but doesn't actually change 964 * the underlying radio connection states. 965 * 966 * @param state Phone.DataState enum. 967 */ 968 public void simulateDataConnection(Phone.DataState state) { 969 DataConnectionTracker.State dcState; 970 971 switch (state) { 972 case CONNECTED: 973 dcState = DataConnectionTracker.State.CONNECTED; 974 break; 975 case SUSPENDED: 976 dcState = DataConnectionTracker.State.CONNECTED; 977 break; 978 case DISCONNECTED: 979 dcState = DataConnectionTracker.State.FAILED; 980 break; 981 default: 982 dcState = DataConnectionTracker.State.CONNECTING; 983 break; 984 } 985 986 mDataConnection.setState(dcState); 987 notifyDataConnection(null); 988 } 989 990 /** 991 * Notify registrants of a new ringing Connection. 992 * Subclasses of Phone probably want to replace this with a 993 * version scoped to their packages 994 */ 995 protected void notifyNewRingingConnectionP(Connection cn) { 996 AsyncResult ar = new AsyncResult(null, cn, null); 997 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 998 } 999 1000 /** 1001 * Notify registrants of a RING event. 1002 */ 1003 private void notifyIncomingRing() { 1004 AsyncResult ar = new AsyncResult(null, this, null); 1005 mIncomingRingRegistrants.notifyRegistrants(ar); 1006 } 1007 1008 /** 1009 * Send the incoming call Ring notification if conditions are right. 1010 */ 1011 private void sendIncomingCallRingNotification(int token) { 1012 if (!mDoesRilSendMultipleCallRing && (token == mCallRingContinueToken)) { 1013 Log.d(LOG_TAG, "Sending notifyIncomingRing"); 1014 notifyIncomingRing(); 1015 sendMessageDelayed( 1016 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1017 } else { 1018 Log.d(LOG_TAG, "Ignoring ring notification request," 1019 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1020 + " token=" + token 1021 + " mCallRingContinueToken=" + mCallRingContinueToken); 1022 } 1023 } 1024 1025 /** 1026 * Common error logger method for unexpected calls to CDMA-only methods. 1027 */ 1028 private void logUnexpectedCdmaMethodCall(String name) 1029 { 1030 Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1031 "called, CDMAPhone inactive."); 1032 } 1033 } 1034