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