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