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