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