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