PhoneBase.java revision ef1d4bff9bbf7d967dbcace73f08910e14e367d0
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 17package com.android.internal.telephony; 18 19import android.app.ActivityManagerNative; 20import android.app.IActivityManager; 21import android.content.Context; 22import android.content.res.Configuration; 23import android.content.SharedPreferences; 24import android.net.LinkCapabilities; 25import android.net.LinkProperties; 26import android.net.wifi.WifiManager; 27import android.os.AsyncResult; 28import android.os.Handler; 29import android.os.Looper; 30import android.os.Message; 31import android.os.RegistrantList; 32import android.os.SystemProperties; 33import android.preference.PreferenceManager; 34import android.provider.Settings; 35import android.telephony.CellInfo; 36import android.telephony.ServiceState; 37import android.telephony.SignalStrength; 38import android.text.TextUtils; 39import android.util.Log; 40 41import com.android.internal.R; 42import com.android.internal.telephony.gsm.UsimServiceTable; 43import com.android.internal.telephony.ims.IsimRecords; 44import com.android.internal.telephony.test.SimulatedRadioControl; 45import com.android.internal.telephony.gsm.SIMRecords; 46 47import java.io.FileDescriptor; 48import java.io.PrintWriter; 49import java.util.List; 50import java.util.Locale; 51import java.util.concurrent.atomic.AtomicReference; 52 53 54/** 55 * (<em>Not for SDK use</em>) 56 * A base implementation for the com.android.internal.telephony.Phone interface. 57 * 58 * Note that implementations of Phone.java are expected to be used 59 * from a single application thread. This should be the same thread that 60 * originally called PhoneFactory to obtain the interface. 61 * 62 * {@hide} 63 * 64 */ 65 66public abstract class PhoneBase extends Handler implements Phone { 67 private static final String LOG_TAG = "PHONE"; 68 private static final boolean LOCAL_DEBUG = true; 69 70 // Key used to read and write the saved network selection numeric value 71 public static final String NETWORK_SELECTION_KEY = "network_selection_key"; 72 // Key used to read and write the saved network selection operator name 73 public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key"; 74 75 76 // Key used to read/write "disable data connection on boot" pref (used for testing) 77 public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key"; 78 79 /* Event Constants */ 80 protected static final int EVENT_RADIO_AVAILABLE = 1; 81 /** Supplementary Service Notification received. */ 82 protected static final int EVENT_SSN = 2; 83 protected static final int EVENT_SIM_RECORDS_LOADED = 3; 84 protected static final int EVENT_MMI_DONE = 4; 85 protected static final int EVENT_RADIO_ON = 5; 86 protected static final int EVENT_GET_BASEBAND_VERSION_DONE = 6; 87 protected static final int EVENT_USSD = 7; 88 protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8; 89 protected static final int EVENT_GET_IMEI_DONE = 9; 90 protected static final int EVENT_GET_IMEISV_DONE = 10; 91 protected static final int EVENT_GET_SIM_STATUS_DONE = 11; 92 protected static final int EVENT_SET_CALL_FORWARD_DONE = 12; 93 protected static final int EVENT_GET_CALL_FORWARD_DONE = 13; 94 protected static final int EVENT_CALL_RING = 14; 95 protected static final int EVENT_CALL_RING_CONTINUE = 15; 96 97 // Used to intercept the carrier selection calls so that 98 // we can save the values. 99 protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 16; 100 protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17; 101 protected static final int EVENT_SET_CLIR_COMPLETE = 18; 102 protected static final int EVENT_REGISTERED_TO_NETWORK = 19; 103 protected static final int EVENT_SET_VM_NUMBER_DONE = 20; 104 // Events for CDMA support 105 protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 21; 106 protected static final int EVENT_RUIM_RECORDS_LOADED = 22; 107 protected static final int EVENT_NV_READY = 23; 108 protected static final int EVENT_SET_ENHANCED_VP = 24; 109 protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25; 110 protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26; 111 protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27; 112 // other 113 protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28; 114 protected static final int EVENT_NEW_ICC_SMS = 29; 115 protected static final int EVENT_ICC_RECORD_EVENTS = 30; 116 117 // Key used to read/write current CLIR setting 118 public static final String CLIR_KEY = "clir_key"; 119 120 // Key used to read/write "disable DNS server check" pref (used for testing) 121 public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key"; 122 123 /* Instance Variables */ 124 public CommandsInterface mCM; 125 boolean mDnsCheckDisabled; 126 public DataConnectionTracker mDataConnectionTracker; 127 boolean mDoesRilSendMultipleCallRing; 128 int mCallRingContinueToken; 129 int mCallRingDelay; 130 public boolean mIsTheCurrentActivePhone = true; 131 boolean mIsVoiceCapable = true; 132 public IccRecords mIccRecords; 133 protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>(); 134 public SmsStorageMonitor mSmsStorageMonitor; 135 public SmsUsageMonitor mSmsUsageMonitor; 136 public SMSDispatcher mSMS; 137 138 /** 139 * Set a system property, unless we're in unit test mode 140 */ 141 public void 142 setSystemProperty(String property, String value) { 143 if(getUnitTestMode()) { 144 return; 145 } 146 SystemProperties.set(property, value); 147 } 148 149 150 protected final RegistrantList mPreciseCallStateRegistrants 151 = new RegistrantList(); 152 153 protected final RegistrantList mNewRingingConnectionRegistrants 154 = new RegistrantList(); 155 156 protected final RegistrantList mIncomingRingRegistrants 157 = new RegistrantList(); 158 159 protected final RegistrantList mDisconnectRegistrants 160 = new RegistrantList(); 161 162 protected final RegistrantList mServiceStateRegistrants 163 = new RegistrantList(); 164 165 protected final RegistrantList mMmiCompleteRegistrants 166 = new RegistrantList(); 167 168 protected final RegistrantList mMmiRegistrants 169 = new RegistrantList(); 170 171 protected final RegistrantList mUnknownConnectionRegistrants 172 = new RegistrantList(); 173 174 protected final RegistrantList mSuppServiceFailedRegistrants 175 = new RegistrantList(); 176 177 protected Looper mLooper; /* to insure registrants are in correct thread*/ 178 179 protected final Context mContext; 180 181 /** 182 * PhoneNotifier is an abstraction for all system-wide 183 * state change notification. DefaultPhoneNotifier is 184 * used here unless running we're inside a unit test. 185 */ 186 protected PhoneNotifier mNotifier; 187 188 protected SimulatedRadioControl mSimulatedRadioControl; 189 190 boolean mUnitTestMode; 191 192 /** 193 * Constructs a PhoneBase in normal (non-unit test) mode. 194 * 195 * @param notifier An instance of DefaultPhoneNotifier, 196 * @param context Context object from hosting application 197 * unless unit testing. 198 * @param ci the CommandsInterface 199 */ 200 protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci) { 201 this(notifier, context, ci, false); 202 } 203 204 /** 205 * Constructs a PhoneBase in normal (non-unit test) mode. 206 * 207 * @param notifier An instance of DefaultPhoneNotifier, 208 * @param context Context object from hosting application 209 * unless unit testing. 210 * @param ci is CommandsInterface 211 * @param unitTestMode when true, prevents notifications 212 * of state change events 213 */ 214 protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci, 215 boolean unitTestMode) { 216 this.mNotifier = notifier; 217 this.mContext = context; 218 mLooper = Looper.myLooper(); 219 mCM = ci; 220 221 setPropertiesByCarrier(); 222 223 setUnitTestMode(unitTestMode); 224 225 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 226 mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); 227 mCM.setOnCallRing(this, EVENT_CALL_RING, null); 228 229 /* "Voice capable" means that this device supports circuit-switched 230 * (i.e. voice) phone calls over the telephony network, and is allowed 231 * to display the in-call UI while a cellular voice call is active. 232 * This will be false on "data only" devices which can't make voice 233 * calls and don't support any in-call UI. 234 */ 235 mIsVoiceCapable = mContext.getResources().getBoolean( 236 com.android.internal.R.bool.config_voice_capable); 237 238 /** 239 * Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs 240 * to be generated locally. Ideally all ring tones should be loops 241 * and this wouldn't be necessary. But to minimize changes to upper 242 * layers it is requested that it be generated by lower layers. 243 * 244 * By default old phones won't have the property set but do generate 245 * the RIL_UNSOL_CALL_RING so the default if there is no property is 246 * true. 247 */ 248 mDoesRilSendMultipleCallRing = SystemProperties.getBoolean( 249 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true); 250 Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 251 252 mCallRingDelay = SystemProperties.getInt( 253 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000); 254 Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay); 255 256 // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers. 257 mSmsStorageMonitor = new SmsStorageMonitor(this); 258 mSmsUsageMonitor = new SmsUsageMonitor(context); 259 } 260 261 public void dispose() { 262 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 263 mCM.unSetOnCallRing(this); 264 // Must cleanup all connectionS and needs to use sendMessage! 265 mDataConnectionTracker.cleanUpAllConnections(null); 266 mIsTheCurrentActivePhone = false; 267 // Dispose the SMS usage and storage monitors 268 mSmsStorageMonitor.dispose(); 269 mSmsUsageMonitor.dispose(); 270 } 271 } 272 273 public void removeReferences() { 274 mSmsStorageMonitor = null; 275 mSmsUsageMonitor = null; 276 mSMS = null; 277 mIccRecords = null; 278 mIccCard.set(null); 279 mDataConnectionTracker = null; 280 } 281 282 /** 283 * When overridden the derived class needs to call 284 * super.handleMessage(msg) so this method has a 285 * a chance to process the message. 286 * 287 * @param msg 288 */ 289 @Override 290 public void handleMessage(Message msg) { 291 AsyncResult ar; 292 293 switch(msg.what) { 294 case EVENT_CALL_RING: 295 Log.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState()); 296 ar = (AsyncResult)msg.obj; 297 if (ar.exception == null) { 298 PhoneConstants.State state = getState(); 299 if ((!mDoesRilSendMultipleCallRing) 300 && ((state == PhoneConstants.State.RINGING) || 301 (state == PhoneConstants.State.IDLE))) { 302 mCallRingContinueToken += 1; 303 sendIncomingCallRingNotification(mCallRingContinueToken); 304 } else { 305 notifyIncomingRing(); 306 } 307 } 308 break; 309 310 case EVENT_CALL_RING_CONTINUE: 311 Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState()); 312 if (getState() == PhoneConstants.State.RINGING) { 313 sendIncomingCallRingNotification(msg.arg1); 314 } 315 break; 316 317 default: 318 throw new RuntimeException("unexpected event not handled"); 319 } 320 } 321 322 // Inherited documentation suffices. 323 public Context getContext() { 324 return mContext; 325 } 326 327 /** 328 * Disables the DNS check (i.e., allows "0.0.0.0"). 329 * Useful for lab testing environment. 330 * @param b true disables the check, false enables. 331 */ 332 public void disableDnsCheck(boolean b) { 333 mDnsCheckDisabled = b; 334 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 335 SharedPreferences.Editor editor = sp.edit(); 336 editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); 337 editor.apply(); 338 } 339 340 /** 341 * Returns true if the DNS check is currently disabled. 342 */ 343 public boolean isDnsCheckDisabled() { 344 return mDnsCheckDisabled; 345 } 346 347 // Inherited documentation suffices. 348 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { 349 checkCorrectThread(h); 350 351 mPreciseCallStateRegistrants.addUnique(h, what, obj); 352 } 353 354 // Inherited documentation suffices. 355 public void unregisterForPreciseCallStateChanged(Handler h) { 356 mPreciseCallStateRegistrants.remove(h); 357 } 358 359 /** 360 * Subclasses of Phone probably want to replace this with a 361 * version scoped to their packages 362 */ 363 protected void notifyPreciseCallStateChangedP() { 364 AsyncResult ar = new AsyncResult(null, this, null); 365 mPreciseCallStateRegistrants.notifyRegistrants(ar); 366 } 367 368 // Inherited documentation suffices. 369 public void registerForUnknownConnection(Handler h, int what, Object obj) { 370 checkCorrectThread(h); 371 372 mUnknownConnectionRegistrants.addUnique(h, what, obj); 373 } 374 375 // Inherited documentation suffices. 376 public void unregisterForUnknownConnection(Handler h) { 377 mUnknownConnectionRegistrants.remove(h); 378 } 379 380 // Inherited documentation suffices. 381 public void registerForNewRingingConnection( 382 Handler h, int what, Object obj) { 383 checkCorrectThread(h); 384 385 mNewRingingConnectionRegistrants.addUnique(h, what, obj); 386 } 387 388 // Inherited documentation suffices. 389 public void unregisterForNewRingingConnection(Handler h) { 390 mNewRingingConnectionRegistrants.remove(h); 391 } 392 393 // Inherited documentation suffices. 394 public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ 395 mCM.registerForInCallVoicePrivacyOn(h,what,obj); 396 } 397 398 // Inherited documentation suffices. 399 public void unregisterForInCallVoicePrivacyOn(Handler h){ 400 mCM.unregisterForInCallVoicePrivacyOn(h); 401 } 402 403 // Inherited documentation suffices. 404 public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ 405 mCM.registerForInCallVoicePrivacyOff(h,what,obj); 406 } 407 408 // Inherited documentation suffices. 409 public void unregisterForInCallVoicePrivacyOff(Handler h){ 410 mCM.unregisterForInCallVoicePrivacyOff(h); 411 } 412 413 // Inherited documentation suffices. 414 public void registerForIncomingRing( 415 Handler h, int what, Object obj) { 416 checkCorrectThread(h); 417 418 mIncomingRingRegistrants.addUnique(h, what, obj); 419 } 420 421 // Inherited documentation suffices. 422 public void unregisterForIncomingRing(Handler h) { 423 mIncomingRingRegistrants.remove(h); 424 } 425 426 // Inherited documentation suffices. 427 public void registerForDisconnect(Handler h, int what, Object obj) { 428 checkCorrectThread(h); 429 430 mDisconnectRegistrants.addUnique(h, what, obj); 431 } 432 433 // Inherited documentation suffices. 434 public void unregisterForDisconnect(Handler h) { 435 mDisconnectRegistrants.remove(h); 436 } 437 438 // Inherited documentation suffices. 439 public void registerForSuppServiceFailed(Handler h, int what, Object obj) { 440 checkCorrectThread(h); 441 442 mSuppServiceFailedRegistrants.addUnique(h, what, obj); 443 } 444 445 // Inherited documentation suffices. 446 public void unregisterForSuppServiceFailed(Handler h) { 447 mSuppServiceFailedRegistrants.remove(h); 448 } 449 450 // Inherited documentation suffices. 451 public void registerForMmiInitiate(Handler h, int what, Object obj) { 452 checkCorrectThread(h); 453 454 mMmiRegistrants.addUnique(h, what, obj); 455 } 456 457 // Inherited documentation suffices. 458 public void unregisterForMmiInitiate(Handler h) { 459 mMmiRegistrants.remove(h); 460 } 461 462 // Inherited documentation suffices. 463 public void registerForMmiComplete(Handler h, int what, Object obj) { 464 checkCorrectThread(h); 465 466 mMmiCompleteRegistrants.addUnique(h, what, obj); 467 } 468 469 // Inherited documentation suffices. 470 public void unregisterForMmiComplete(Handler h) { 471 checkCorrectThread(h); 472 473 mMmiCompleteRegistrants.remove(h); 474 } 475 476 /** 477 * Method to retrieve the saved operator id from the Shared Preferences 478 */ 479 private String getSavedNetworkSelection() { 480 // open the shared preferences and search with our key. 481 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 482 return sp.getString(NETWORK_SELECTION_KEY, ""); 483 } 484 485 /** 486 * Method to restore the previously saved operator id, or reset to 487 * automatic selection, all depending upon the value in the shared 488 * preferences. 489 */ 490 public void restoreSavedNetworkSelection(Message response) { 491 // retrieve the operator id 492 String networkSelection = getSavedNetworkSelection(); 493 494 // set to auto if the id is empty, otherwise select the network. 495 if (TextUtils.isEmpty(networkSelection)) { 496 mCM.setNetworkSelectionModeAutomatic(response); 497 } else { 498 mCM.setNetworkSelectionModeManual(networkSelection, response); 499 } 500 } 501 502 // Inherited documentation suffices. 503 public void setUnitTestMode(boolean f) { 504 mUnitTestMode = f; 505 } 506 507 // Inherited documentation suffices. 508 public boolean getUnitTestMode() { 509 return mUnitTestMode; 510 } 511 512 /** 513 * To be invoked when a voice call Connection disconnects. 514 * 515 * Subclasses of Phone probably want to replace this with a 516 * version scoped to their packages 517 */ 518 protected void notifyDisconnectP(Connection cn) { 519 AsyncResult ar = new AsyncResult(null, cn, null); 520 mDisconnectRegistrants.notifyRegistrants(ar); 521 } 522 523 // Inherited documentation suffices. 524 public void registerForServiceStateChanged( 525 Handler h, int what, Object obj) { 526 checkCorrectThread(h); 527 528 mServiceStateRegistrants.add(h, what, obj); 529 } 530 531 // Inherited documentation suffices. 532 public void unregisterForServiceStateChanged(Handler h) { 533 mServiceStateRegistrants.remove(h); 534 } 535 536 // Inherited documentation suffices. 537 public void registerForRingbackTone(Handler h, int what, Object obj) { 538 mCM.registerForRingbackTone(h,what,obj); 539 } 540 541 // Inherited documentation suffices. 542 public void unregisterForRingbackTone(Handler h) { 543 mCM.unregisterForRingbackTone(h); 544 } 545 546 // Inherited documentation suffices. 547 public void registerForResendIncallMute(Handler h, int what, Object obj) { 548 mCM.registerForResendIncallMute(h,what,obj); 549 } 550 551 // Inherited documentation suffices. 552 public void unregisterForResendIncallMute(Handler h) { 553 mCM.unregisterForResendIncallMute(h); 554 } 555 556 public void setEchoSuppressionEnabled(boolean enabled) { 557 // no need for regular phone 558 } 559 560 /** 561 * Subclasses of Phone probably want to replace this with a 562 * version scoped to their packages 563 */ 564 protected void notifyServiceStateChangedP(ServiceState ss) { 565 AsyncResult ar = new AsyncResult(null, ss, null); 566 mServiceStateRegistrants.notifyRegistrants(ar); 567 568 mNotifier.notifyServiceState(this); 569 } 570 571 // Inherited documentation suffices. 572 public SimulatedRadioControl getSimulatedRadioControl() { 573 return mSimulatedRadioControl; 574 } 575 576 /** 577 * Verifies the current thread is the same as the thread originally 578 * used in the initialization of this instance. Throws RuntimeException 579 * if not. 580 * 581 * @exception RuntimeException if the current thread is not 582 * the thread that originally obtained this PhoneBase instance. 583 */ 584 private void checkCorrectThread(Handler h) { 585 if (h.getLooper() != mLooper) { 586 throw new RuntimeException( 587 "com.android.internal.telephony.Phone must be used from within one thread"); 588 } 589 } 590 591 /** 592 * Set the properties by matching the carrier string in 593 * a string-array resource 594 */ 595 private void setPropertiesByCarrier() { 596 String carrier = SystemProperties.get("ro.carrier"); 597 598 if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { 599 return; 600 } 601 602 CharSequence[] carrierLocales = mContext. 603 getResources().getTextArray(R.array.carrier_properties); 604 605 for (int i = 0; i < carrierLocales.length; i+=3) { 606 String c = carrierLocales[i].toString(); 607 if (carrier.equals(c)) { 608 String l = carrierLocales[i+1].toString(); 609 610 String language = l.substring(0, 2); 611 String country = ""; 612 if (l.length() >=5) { 613 country = l.substring(3, 5); 614 } 615 MccTable.setSystemLocale(mContext, language, country); 616 617 if (!country.isEmpty()) { 618 try { 619 Settings.Secure.getInt(mContext.getContentResolver(), 620 Settings.Secure.WIFI_COUNTRY_CODE); 621 } catch (Settings.SettingNotFoundException e) { 622 // note this is not persisting 623 WifiManager wM = (WifiManager) 624 mContext.getSystemService(Context.WIFI_SERVICE); 625 wM.setCountryCode(country, false); 626 } 627 } 628 return; 629 } 630 } 631 } 632 633 /** 634 * Get state 635 */ 636 public abstract PhoneConstants.State getState(); 637 638 /** 639 * Retrieves the IccFileHandler of the Phone instance 640 */ 641 public IccFileHandler getIccFileHandler(){ 642 IccCard iccCard = mIccCard.get(); 643 if (iccCard == null) return null; 644 return iccCard.getIccFileHandler(); 645 } 646 647 /* 648 * Retrieves the Handler of the Phone instance 649 */ 650 public Handler getHandler() { 651 return this; 652 } 653 654 /** 655 * Retrieves the ServiceStateTracker of the phone instance. 656 */ 657 public ServiceStateTracker getServiceStateTracker() { 658 return null; 659 } 660 661 /** 662 * Get call tracker 663 */ 664 public CallTracker getCallTracker() { 665 return null; 666 } 667 668 @Override 669 public IccCard getIccCard() { 670 return mIccCard.get(); 671 } 672 673 @Override 674 public String getIccSerialNumber() { 675 return mIccRecords.iccid; 676 } 677 678 @Override 679 public boolean getIccRecordsLoaded() { 680 return mIccRecords.getRecordsLoaded(); 681 } 682 683 /** 684 * @return all available cell information or null if none. 685 */ 686 @Override 687 public List<CellInfo> getAllCellInfo() { 688 return getServiceStateTracker().getAllCellInfo(); 689 } 690 691 @Override 692 public boolean getMessageWaitingIndicator() { 693 return mIccRecords.getVoiceMessageWaiting(); 694 } 695 696 @Override 697 public boolean getCallForwardingIndicator() { 698 return mIccRecords.getVoiceCallForwardingFlag(); 699 } 700 701 /** 702 * Query the status of the CDMA roaming preference 703 */ 704 public void queryCdmaRoamingPreference(Message response) { 705 mCM.queryCdmaRoamingPreference(response); 706 } 707 708 /** 709 * Get the signal strength 710 */ 711 @Override 712 public SignalStrength getSignalStrength() { 713 ServiceStateTracker sst = getServiceStateTracker(); 714 if (sst == null) { 715 return new SignalStrength(); 716 } else { 717 return sst.getSignalStrength(); 718 } 719 } 720 721 /** 722 * Set the status of the CDMA roaming preference 723 */ 724 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 725 mCM.setCdmaRoamingPreference(cdmaRoamingType, response); 726 } 727 728 /** 729 * Set the status of the CDMA subscription mode 730 */ 731 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 732 mCM.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 733 } 734 735 /** 736 * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only 737 */ 738 public void setPreferredNetworkType(int networkType, Message response) { 739 mCM.setPreferredNetworkType(networkType, response); 740 } 741 742 public void getPreferredNetworkType(Message response) { 743 mCM.getPreferredNetworkType(response); 744 } 745 746 public void getSmscAddress(Message result) { 747 mCM.getSmscAddress(result); 748 } 749 750 public void setSmscAddress(String address, Message result) { 751 mCM.setSmscAddress(address, result); 752 } 753 754 public void setTTYMode(int ttyMode, Message onComplete) { 755 mCM.setTTYMode(ttyMode, onComplete); 756 } 757 758 public void queryTTYMode(Message onComplete) { 759 mCM.queryTTYMode(onComplete); 760 } 761 762 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 763 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 764 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 765 } 766 767 public void getEnhancedVoicePrivacy(Message onComplete) { 768 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 769 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 770 } 771 772 public void setBandMode(int bandMode, Message response) { 773 mCM.setBandMode(bandMode, response); 774 } 775 776 public void queryAvailableBandMode(Message response) { 777 mCM.queryAvailableBandMode(response); 778 } 779 780 public void invokeOemRilRequestRaw(byte[] data, Message response) { 781 mCM.invokeOemRilRequestRaw(data, response); 782 } 783 784 public void invokeOemRilRequestStrings(String[] strings, Message response) { 785 mCM.invokeOemRilRequestStrings(strings, response); 786 } 787 788 public void notifyDataActivity() { 789 mNotifier.notifyDataActivity(this); 790 } 791 792 public void notifyMessageWaitingIndicator() { 793 // Do not notify voice mail waiting if device doesn't support voice 794 if (!mIsVoiceCapable) 795 return; 796 797 // This function is added to send the notification to DefaultPhoneNotifier. 798 mNotifier.notifyMessageWaitingChanged(this); 799 } 800 801 public void notifyDataConnection(String reason, String apnType, 802 PhoneConstants.DataState state) { 803 mNotifier.notifyDataConnection(this, reason, apnType, state); 804 } 805 806 public void notifyDataConnection(String reason, String apnType) { 807 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 808 } 809 810 public void notifyDataConnection(String reason) { 811 String types[] = getActiveApnTypes(); 812 for (String apnType : types) { 813 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 814 } 815 } 816 817 public void notifyOtaspChanged(int otaspMode) { 818 mNotifier.notifyOtaspChanged(this, otaspMode); 819 } 820 821 public void notifySignalStrength() { 822 mNotifier.notifySignalStrength(this); 823 } 824 825 public void notifyCellInfo(List<CellInfo> cellInfo) { 826 mNotifier.notifyCellInfo(this, cellInfo); 827 } 828 829 /** 830 * @return true if a mobile originating emergency call is active 831 */ 832 public boolean isInEmergencyCall() { 833 return false; 834 } 835 836 /** 837 * @return true if we are in the emergency call back mode. This is a period where 838 * the phone should be using as little power as possible and be ready to receive an 839 * incoming call from the emergency operator. 840 */ 841 public boolean isInEcm() { 842 return false; 843 } 844 845 public abstract String getPhoneName(); 846 847 public abstract int getPhoneType(); 848 849 /** @hide */ 850 public int getVoiceMessageCount(){ 851 return 0; 852 } 853 854 /** 855 * Returns the CDMA ERI icon index to display 856 */ 857 public int getCdmaEriIconIndex() { 858 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 859 return -1; 860 } 861 862 /** 863 * Returns the CDMA ERI icon mode, 864 * 0 - ON 865 * 1 - FLASHING 866 */ 867 public int getCdmaEriIconMode() { 868 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 869 return -1; 870 } 871 872 /** 873 * Returns the CDMA ERI text, 874 */ 875 public String getCdmaEriText() { 876 logUnexpectedCdmaMethodCall("getCdmaEriText"); 877 return "GSM nw, no ERI"; 878 } 879 880 public String getCdmaMin() { 881 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 882 logUnexpectedCdmaMethodCall("getCdmaMin"); 883 return null; 884 } 885 886 public boolean isMinInfoReady() { 887 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 888 logUnexpectedCdmaMethodCall("isMinInfoReady"); 889 return false; 890 } 891 892 public String getCdmaPrlVersion(){ 893 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 894 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 895 return null; 896 } 897 898 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 899 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 900 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 901 } 902 903 public void exitEmergencyCallbackMode() { 904 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 905 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 906 } 907 908 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 909 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 910 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 911 } 912 913 public void unregisterForCdmaOtaStatusChange(Handler h) { 914 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 915 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 916 } 917 918 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 919 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 920 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 921 } 922 923 public void unregisterForSubscriptionInfoReady(Handler h) { 924 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 925 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 926 } 927 928 /** 929 * Returns true if OTA Service Provisioning needs to be performed. 930 * If not overridden return false. 931 */ 932 public boolean needsOtaServiceProvisioning() { 933 return false; 934 } 935 936 /** 937 * Return true if number is an OTASP number. 938 * If not overridden return false. 939 */ 940 public boolean isOtaSpNumber(String dialStr) { 941 return false; 942 } 943 944 public void registerForCallWaiting(Handler h, int what, Object obj){ 945 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 946 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 947 } 948 949 public void unregisterForCallWaiting(Handler h){ 950 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 951 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 952 } 953 954 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 955 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 956 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 957 } 958 959 public void unregisterForEcmTimerReset(Handler h) { 960 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 961 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 962 } 963 964 public void registerForSignalInfo(Handler h, int what, Object obj) { 965 mCM.registerForSignalInfo(h, what, obj); 966 } 967 968 public void unregisterForSignalInfo(Handler h) { 969 mCM.unregisterForSignalInfo(h); 970 } 971 972 public void registerForDisplayInfo(Handler h, int what, Object obj) { 973 mCM.registerForDisplayInfo(h, what, obj); 974 } 975 976 public void unregisterForDisplayInfo(Handler h) { 977 mCM.unregisterForDisplayInfo(h); 978 } 979 980 public void registerForNumberInfo(Handler h, int what, Object obj) { 981 mCM.registerForNumberInfo(h, what, obj); 982 } 983 984 public void unregisterForNumberInfo(Handler h) { 985 mCM.unregisterForNumberInfo(h); 986 } 987 988 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 989 mCM.registerForRedirectedNumberInfo(h, what, obj); 990 } 991 992 public void unregisterForRedirectedNumberInfo(Handler h) { 993 mCM.unregisterForRedirectedNumberInfo(h); 994 } 995 996 public void registerForLineControlInfo(Handler h, int what, Object obj) { 997 mCM.registerForLineControlInfo( h, what, obj); 998 } 999 1000 public void unregisterForLineControlInfo(Handler h) { 1001 mCM.unregisterForLineControlInfo(h); 1002 } 1003 1004 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 1005 mCM.registerFoT53ClirlInfo(h, what, obj); 1006 } 1007 1008 public void unregisterForT53ClirInfo(Handler h) { 1009 mCM.unregisterForT53ClirInfo(h); 1010 } 1011 1012 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 1013 mCM.registerForT53AudioControlInfo( h, what, obj); 1014 } 1015 1016 public void unregisterForT53AudioControlInfo(Handler h) { 1017 mCM.unregisterForT53AudioControlInfo(h); 1018 } 1019 1020 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 1021 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1022 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 1023 } 1024 1025 public void unsetOnEcbModeExitResponse(Handler h){ 1026 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1027 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 1028 } 1029 1030 public String[] getActiveApnTypes() { 1031 return mDataConnectionTracker.getActiveApnTypes(); 1032 } 1033 1034 public String getActiveApnHost(String apnType) { 1035 return mDataConnectionTracker.getActiveApnString(apnType); 1036 } 1037 1038 public LinkProperties getLinkProperties(String apnType) { 1039 return mDataConnectionTracker.getLinkProperties(apnType); 1040 } 1041 1042 public LinkCapabilities getLinkCapabilities(String apnType) { 1043 return mDataConnectionTracker.getLinkCapabilities(apnType); 1044 } 1045 1046 public int enableApnType(String type) { 1047 return mDataConnectionTracker.enableApnType(type); 1048 } 1049 1050 public int disableApnType(String type) { 1051 return mDataConnectionTracker.disableApnType(type); 1052 } 1053 1054 public boolean isDataConnectivityPossible() { 1055 return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT); 1056 } 1057 1058 public boolean isDataConnectivityPossible(String apnType) { 1059 return ((mDataConnectionTracker != null) && 1060 (mDataConnectionTracker.isDataPossible(apnType))); 1061 } 1062 1063 /** 1064 * Notify registrants of a new ringing Connection. 1065 * Subclasses of Phone probably want to replace this with a 1066 * version scoped to their packages 1067 */ 1068 protected void notifyNewRingingConnectionP(Connection cn) { 1069 if (!mIsVoiceCapable) 1070 return; 1071 AsyncResult ar = new AsyncResult(null, cn, null); 1072 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 1073 } 1074 1075 /** 1076 * Notify registrants of a RING event. 1077 */ 1078 private void notifyIncomingRing() { 1079 if (!mIsVoiceCapable) 1080 return; 1081 AsyncResult ar = new AsyncResult(null, this, null); 1082 mIncomingRingRegistrants.notifyRegistrants(ar); 1083 } 1084 1085 /** 1086 * Send the incoming call Ring notification if conditions are right. 1087 */ 1088 private void sendIncomingCallRingNotification(int token) { 1089 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 1090 (token == mCallRingContinueToken)) { 1091 Log.d(LOG_TAG, "Sending notifyIncomingRing"); 1092 notifyIncomingRing(); 1093 sendMessageDelayed( 1094 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1095 } else { 1096 Log.d(LOG_TAG, "Ignoring ring notification request," 1097 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1098 + " token=" + token 1099 + " mCallRingContinueToken=" + mCallRingContinueToken 1100 + " mIsVoiceCapable=" + mIsVoiceCapable); 1101 } 1102 } 1103 1104 public boolean isCspPlmnEnabled() { 1105 // This function should be overridden by the class GSMPhone. 1106 // Not implemented in CDMAPhone. 1107 logUnexpectedGsmMethodCall("isCspPlmnEnabled"); 1108 return false; 1109 } 1110 1111 public IsimRecords getIsimRecords() { 1112 Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 1113 return null; 1114 } 1115 1116 public void requestIsimAuthentication(String nonce, Message result) { 1117 Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices"); 1118 } 1119 1120 public String getMsisdn() { 1121 logUnexpectedGsmMethodCall("getMsisdn"); 1122 return null; 1123 } 1124 1125 /** 1126 * Common error logger method for unexpected calls to CDMA-only methods. 1127 */ 1128 private static void logUnexpectedCdmaMethodCall(String name) 1129 { 1130 Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1131 "called, CDMAPhone inactive."); 1132 } 1133 1134 public PhoneConstants.DataState getDataConnectionState() { 1135 return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT); 1136 } 1137 1138 /** 1139 * Common error logger method for unexpected calls to GSM/WCDMA-only methods. 1140 */ 1141 private static void logUnexpectedGsmMethodCall(String name) { 1142 Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1143 "called, GSMPhone inactive."); 1144 } 1145 1146 // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone. 1147 public void notifyCallForwardingIndicator() { 1148 // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone. 1149 Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); 1150 } 1151 1152 public void notifyDataConnectionFailed(String reason, String apnType) { 1153 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 1154 } 1155 1156 /** 1157 * {@inheritDoc} 1158 */ 1159 @Override 1160 public int getLteOnCdmaMode() { 1161 return mCM.getLteOnCdmaMode(); 1162 } 1163 1164 /** 1165 * Sets the SIM voice message waiting indicator records. 1166 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 1167 * @param countWaiting The number of messages waiting, if known. Use 1168 * -1 to indicate that an unknown number of 1169 * messages are waiting 1170 */ 1171 @Override 1172 public void setVoiceMessageWaiting(int line, int countWaiting) { 1173 mIccRecords.setVoiceMessageWaiting(line, countWaiting); 1174 } 1175 1176 /** 1177 * Gets the USIM service table from the UICC, if present and available. 1178 * @return an interface to the UsimServiceTable record, or null if not available 1179 */ 1180 @Override 1181 public UsimServiceTable getUsimServiceTable() { 1182 return mIccRecords.getUsimServiceTable(); 1183 } 1184 1185 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1186 pw.println("PhoneBase:"); 1187 pw.println(" mCM=" + mCM); 1188 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 1189 pw.println(" mDataConnectionTracker=" + mDataConnectionTracker); 1190 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 1191 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 1192 pw.println(" mCallRingDelay=" + mCallRingDelay); 1193 pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone); 1194 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 1195 pw.println(" mIccRecords=" + mIccRecords); 1196 pw.println(" mIccCard=" + mIccCard.get()); 1197 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 1198 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 1199 pw.println(" mSMS=" + mSMS); 1200 pw.flush(); 1201 pw.println(" mLooper=" + mLooper); 1202 pw.println(" mContext=" + mContext); 1203 pw.println(" mNotifier=" + mNotifier); 1204 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 1205 pw.println(" mUnitTestMode=" + mUnitTestMode); 1206 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 1207 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 1208 pw.println(" getState()=" + getState()); 1209 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 1210 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 1211 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 1212 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 1213 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 1214 pw.flush(); 1215 pw.println(" isInEcm()=" + isInEcm()); 1216 pw.println(" getPhoneName()=" + getPhoneName()); 1217 pw.println(" getPhoneType()=" + getPhoneType()); 1218 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 1219 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 1220 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 1221 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 1222 } 1223} 1224