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