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.ServiceState; 36 import android.text.TextUtils; 37 import android.util.Log; 38 39 import com.android.internal.R; 40 import com.android.internal.telephony.gsm.UsimServiceTable; 41 import com.android.internal.telephony.ims.IsimRecords; 42 import com.android.internal.telephony.test.SimulatedRadioControl; 43 import com.android.internal.telephony.gsm.SIMRecords; 44 45 import java.io.FileDescriptor; 46 import java.io.PrintWriter; 47 import java.util.Locale; 48 import 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 63 public 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 Phone.State state = getState(); 294 if ((!mDoesRilSendMultipleCallRing) 295 && ((state == Phone.State.RINGING) || (state == Phone.State.IDLE))) { 296 mCallRingContinueToken += 1; 297 sendIncomingCallRingNotification(mCallRingContinueToken); 298 } else { 299 notifyIncomingRing(); 300 } 301 } 302 break; 303 304 case EVENT_CALL_RING_CONTINUE: 305 Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState()); 306 if (getState() == Phone.State.RINGING) { 307 sendIncomingCallRingNotification(msg.arg1); 308 } 309 break; 310 311 default: 312 throw new RuntimeException("unexpected event not handled"); 313 } 314 } 315 316 // Inherited documentation suffices. 317 public Context getContext() { 318 return mContext; 319 } 320 321 /** 322 * Disables the DNS check (i.e., allows "0.0.0.0"). 323 * Useful for lab testing environment. 324 * @param b true disables the check, false enables. 325 */ 326 public void disableDnsCheck(boolean b) { 327 mDnsCheckDisabled = b; 328 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 329 SharedPreferences.Editor editor = sp.edit(); 330 editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); 331 editor.apply(); 332 } 333 334 /** 335 * Returns true if the DNS check is currently disabled. 336 */ 337 public boolean isDnsCheckDisabled() { 338 return mDnsCheckDisabled; 339 } 340 341 // Inherited documentation suffices. 342 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { 343 checkCorrectThread(h); 344 345 mPreciseCallStateRegistrants.addUnique(h, what, obj); 346 } 347 348 // Inherited documentation suffices. 349 public void unregisterForPreciseCallStateChanged(Handler h) { 350 mPreciseCallStateRegistrants.remove(h); 351 } 352 353 /** 354 * Subclasses of Phone probably want to replace this with a 355 * version scoped to their packages 356 */ 357 protected void notifyPreciseCallStateChangedP() { 358 AsyncResult ar = new AsyncResult(null, this, null); 359 mPreciseCallStateRegistrants.notifyRegistrants(ar); 360 } 361 362 // Inherited documentation suffices. 363 public void registerForUnknownConnection(Handler h, int what, Object obj) { 364 checkCorrectThread(h); 365 366 mUnknownConnectionRegistrants.addUnique(h, what, obj); 367 } 368 369 // Inherited documentation suffices. 370 public void unregisterForUnknownConnection(Handler h) { 371 mUnknownConnectionRegistrants.remove(h); 372 } 373 374 // Inherited documentation suffices. 375 public void registerForNewRingingConnection( 376 Handler h, int what, Object obj) { 377 checkCorrectThread(h); 378 379 mNewRingingConnectionRegistrants.addUnique(h, what, obj); 380 } 381 382 // Inherited documentation suffices. 383 public void unregisterForNewRingingConnection(Handler h) { 384 mNewRingingConnectionRegistrants.remove(h); 385 } 386 387 // Inherited documentation suffices. 388 public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ 389 mCM.registerForInCallVoicePrivacyOn(h,what,obj); 390 } 391 392 // Inherited documentation suffices. 393 public void unregisterForInCallVoicePrivacyOn(Handler h){ 394 mCM.unregisterForInCallVoicePrivacyOn(h); 395 } 396 397 // Inherited documentation suffices. 398 public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ 399 mCM.registerForInCallVoicePrivacyOff(h,what,obj); 400 } 401 402 // Inherited documentation suffices. 403 public void unregisterForInCallVoicePrivacyOff(Handler h){ 404 mCM.unregisterForInCallVoicePrivacyOff(h); 405 } 406 407 // Inherited documentation suffices. 408 public void registerForIncomingRing( 409 Handler h, int what, Object obj) { 410 checkCorrectThread(h); 411 412 mIncomingRingRegistrants.addUnique(h, what, obj); 413 } 414 415 // Inherited documentation suffices. 416 public void unregisterForIncomingRing(Handler h) { 417 mIncomingRingRegistrants.remove(h); 418 } 419 420 // Inherited documentation suffices. 421 public void registerForDisconnect(Handler h, int what, Object obj) { 422 checkCorrectThread(h); 423 424 mDisconnectRegistrants.addUnique(h, what, obj); 425 } 426 427 // Inherited documentation suffices. 428 public void unregisterForDisconnect(Handler h) { 429 mDisconnectRegistrants.remove(h); 430 } 431 432 // Inherited documentation suffices. 433 public void registerForSuppServiceFailed(Handler h, int what, Object obj) { 434 checkCorrectThread(h); 435 436 mSuppServiceFailedRegistrants.addUnique(h, what, obj); 437 } 438 439 // Inherited documentation suffices. 440 public void unregisterForSuppServiceFailed(Handler h) { 441 mSuppServiceFailedRegistrants.remove(h); 442 } 443 444 // Inherited documentation suffices. 445 public void registerForMmiInitiate(Handler h, int what, Object obj) { 446 checkCorrectThread(h); 447 448 mMmiRegistrants.addUnique(h, what, obj); 449 } 450 451 // Inherited documentation suffices. 452 public void unregisterForMmiInitiate(Handler h) { 453 mMmiRegistrants.remove(h); 454 } 455 456 // Inherited documentation suffices. 457 public void registerForMmiComplete(Handler h, int what, Object obj) { 458 checkCorrectThread(h); 459 460 mMmiCompleteRegistrants.addUnique(h, what, obj); 461 } 462 463 // Inherited documentation suffices. 464 public void unregisterForMmiComplete(Handler h) { 465 checkCorrectThread(h); 466 467 mMmiCompleteRegistrants.remove(h); 468 } 469 470 /** 471 * Method to retrieve the saved operator id from the Shared Preferences 472 */ 473 private String getSavedNetworkSelection() { 474 // open the shared preferences and search with our key. 475 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 476 return sp.getString(NETWORK_SELECTION_KEY, ""); 477 } 478 479 /** 480 * Method to restore the previously saved operator id, or reset to 481 * automatic selection, all depending upon the value in the shared 482 * preferences. 483 */ 484 public void restoreSavedNetworkSelection(Message response) { 485 // retrieve the operator id 486 String networkSelection = getSavedNetworkSelection(); 487 488 // set to auto if the id is empty, otherwise select the network. 489 if (TextUtils.isEmpty(networkSelection)) { 490 mCM.setNetworkSelectionModeAutomatic(response); 491 } else { 492 mCM.setNetworkSelectionModeManual(networkSelection, response); 493 } 494 } 495 496 // Inherited documentation suffices. 497 public void setUnitTestMode(boolean f) { 498 mUnitTestMode = f; 499 } 500 501 // Inherited documentation suffices. 502 public boolean getUnitTestMode() { 503 return mUnitTestMode; 504 } 505 506 /** 507 * To be invoked when a voice call Connection disconnects. 508 * 509 * Subclasses of Phone probably want to replace this with a 510 * version scoped to their packages 511 */ 512 protected void notifyDisconnectP(Connection cn) { 513 AsyncResult ar = new AsyncResult(null, cn, null); 514 mDisconnectRegistrants.notifyRegistrants(ar); 515 } 516 517 // Inherited documentation suffices. 518 public void registerForServiceStateChanged( 519 Handler h, int what, Object obj) { 520 checkCorrectThread(h); 521 522 mServiceStateRegistrants.add(h, what, obj); 523 } 524 525 // Inherited documentation suffices. 526 public void unregisterForServiceStateChanged(Handler h) { 527 mServiceStateRegistrants.remove(h); 528 } 529 530 // Inherited documentation suffices. 531 public void registerForRingbackTone(Handler h, int what, Object obj) { 532 mCM.registerForRingbackTone(h,what,obj); 533 } 534 535 // Inherited documentation suffices. 536 public void unregisterForRingbackTone(Handler h) { 537 mCM.unregisterForRingbackTone(h); 538 } 539 540 // Inherited documentation suffices. 541 public void registerForResendIncallMute(Handler h, int what, Object obj) { 542 mCM.registerForResendIncallMute(h,what,obj); 543 } 544 545 // Inherited documentation suffices. 546 public void unregisterForResendIncallMute(Handler h) { 547 mCM.unregisterForResendIncallMute(h); 548 } 549 550 public void setEchoSuppressionEnabled(boolean enabled) { 551 // no need for regular phone 552 } 553 554 /** 555 * Subclasses of Phone probably want to replace this with a 556 * version scoped to their packages 557 */ 558 protected void notifyServiceStateChangedP(ServiceState ss) { 559 AsyncResult ar = new AsyncResult(null, ss, null); 560 mServiceStateRegistrants.notifyRegistrants(ar); 561 562 mNotifier.notifyServiceState(this); 563 } 564 565 // Inherited documentation suffices. 566 public SimulatedRadioControl getSimulatedRadioControl() { 567 return mSimulatedRadioControl; 568 } 569 570 /** 571 * Verifies the current thread is the same as the thread originally 572 * used in the initialization of this instance. Throws RuntimeException 573 * if not. 574 * 575 * @exception RuntimeException if the current thread is not 576 * the thread that originally obtained this PhoneBase instance. 577 */ 578 private void checkCorrectThread(Handler h) { 579 if (h.getLooper() != mLooper) { 580 throw new RuntimeException( 581 "com.android.internal.telephony.Phone must be used from within one thread"); 582 } 583 } 584 585 /** 586 * Set the properties by matching the carrier string in 587 * a string-array resource 588 */ 589 private void setPropertiesByCarrier() { 590 String carrier = SystemProperties.get("ro.carrier"); 591 592 if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { 593 return; 594 } 595 596 CharSequence[] carrierLocales = mContext. 597 getResources().getTextArray(R.array.carrier_properties); 598 599 for (int i = 0; i < carrierLocales.length; i+=3) { 600 String c = carrierLocales[i].toString(); 601 if (carrier.equals(c)) { 602 String l = carrierLocales[i+1].toString(); 603 604 String language = l.substring(0, 2); 605 String country = ""; 606 if (l.length() >=5) { 607 country = l.substring(3, 5); 608 } 609 MccTable.setSystemLocale(mContext, language, country); 610 611 if (!country.isEmpty()) { 612 try { 613 Settings.Secure.getInt(mContext.getContentResolver(), 614 Settings.Secure.WIFI_COUNTRY_CODE); 615 } catch (Settings.SettingNotFoundException e) { 616 // note this is not persisting 617 WifiManager wM = (WifiManager) 618 mContext.getSystemService(Context.WIFI_SERVICE); 619 wM.setCountryCode(country, false); 620 } 621 } 622 return; 623 } 624 } 625 } 626 627 /** 628 * Get state 629 */ 630 public abstract Phone.State getState(); 631 632 /** 633 * Retrieves the IccFileHandler of the Phone instance 634 */ 635 public IccFileHandler getIccFileHandler(){ 636 IccCard iccCard = mIccCard.get(); 637 if (iccCard == null) return null; 638 return iccCard.getIccFileHandler(); 639 } 640 641 /* 642 * Retrieves the Handler of the Phone instance 643 */ 644 public Handler getHandler() { 645 return this; 646 } 647 648 /** 649 * Retrieves the ServiceStateTracker of the phone instance. 650 */ 651 public ServiceStateTracker getServiceStateTracker() { 652 return null; 653 } 654 655 /** 656 * Get call tracker 657 */ 658 public CallTracker getCallTracker() { 659 return null; 660 } 661 662 @Override 663 public IccCard getIccCard() { 664 return mIccCard.get(); 665 } 666 667 @Override 668 public String getIccSerialNumber() { 669 return mIccRecords.iccid; 670 } 671 672 @Override 673 public boolean getIccRecordsLoaded() { 674 return mIccRecords.getRecordsLoaded(); 675 } 676 677 @Override 678 public boolean getMessageWaitingIndicator() { 679 return mIccRecords.getVoiceMessageWaiting(); 680 } 681 682 @Override 683 public boolean getCallForwardingIndicator() { 684 return mIccRecords.getVoiceCallForwardingFlag(); 685 } 686 687 /** 688 * Query the status of the CDMA roaming preference 689 */ 690 public void queryCdmaRoamingPreference(Message response) { 691 mCM.queryCdmaRoamingPreference(response); 692 } 693 694 /** 695 * Set the status of the CDMA roaming preference 696 */ 697 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 698 mCM.setCdmaRoamingPreference(cdmaRoamingType, response); 699 } 700 701 /** 702 * Set the status of the CDMA subscription mode 703 */ 704 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 705 mCM.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 706 } 707 708 /** 709 * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only 710 */ 711 public void setPreferredNetworkType(int networkType, Message response) { 712 mCM.setPreferredNetworkType(networkType, response); 713 } 714 715 public void getPreferredNetworkType(Message response) { 716 mCM.getPreferredNetworkType(response); 717 } 718 719 public void getSmscAddress(Message result) { 720 mCM.getSmscAddress(result); 721 } 722 723 public void setSmscAddress(String address, Message result) { 724 mCM.setSmscAddress(address, result); 725 } 726 727 public void setTTYMode(int ttyMode, Message onComplete) { 728 mCM.setTTYMode(ttyMode, onComplete); 729 } 730 731 public void queryTTYMode(Message onComplete) { 732 mCM.queryTTYMode(onComplete); 733 } 734 735 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 736 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 737 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 738 } 739 740 public void getEnhancedVoicePrivacy(Message onComplete) { 741 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 742 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 743 } 744 745 public void setBandMode(int bandMode, Message response) { 746 mCM.setBandMode(bandMode, response); 747 } 748 749 public void queryAvailableBandMode(Message response) { 750 mCM.queryAvailableBandMode(response); 751 } 752 753 public void invokeOemRilRequestRaw(byte[] data, Message response) { 754 mCM.invokeOemRilRequestRaw(data, response); 755 } 756 757 public void invokeOemRilRequestStrings(String[] strings, Message response) { 758 mCM.invokeOemRilRequestStrings(strings, response); 759 } 760 761 public void notifyDataActivity() { 762 mNotifier.notifyDataActivity(this); 763 } 764 765 public void notifyMessageWaitingIndicator() { 766 // Do not notify voice mail waiting if device doesn't support voice 767 if (!mIsVoiceCapable) 768 return; 769 770 // This function is added to send the notification to DefaultPhoneNotifier. 771 mNotifier.notifyMessageWaitingChanged(this); 772 } 773 774 public void notifyDataConnection(String reason, String apnType, 775 Phone.DataState state) { 776 mNotifier.notifyDataConnection(this, reason, apnType, state); 777 } 778 779 public void notifyDataConnection(String reason, String apnType) { 780 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 781 } 782 783 public void notifyDataConnection(String reason) { 784 String types[] = getActiveApnTypes(); 785 for (String apnType : types) { 786 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 787 } 788 } 789 790 public void notifyOtaspChanged(int otaspMode) { 791 mNotifier.notifyOtaspChanged(this, otaspMode); 792 } 793 794 /** 795 * @return true if a mobile originating emergency call is active 796 */ 797 public boolean isInEmergencyCall() { 798 return false; 799 } 800 801 /** 802 * @return true if we are in the emergency call back mode. This is a period where 803 * the phone should be using as little power as possible and be ready to receive an 804 * incoming call from the emergency operator. 805 */ 806 public boolean isInEcm() { 807 return false; 808 } 809 810 public abstract String getPhoneName(); 811 812 public abstract int getPhoneType(); 813 814 /** @hide */ 815 public int getVoiceMessageCount(){ 816 return 0; 817 } 818 819 /** 820 * Returns the CDMA ERI icon index to display 821 */ 822 public int getCdmaEriIconIndex() { 823 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 824 return -1; 825 } 826 827 /** 828 * Returns the CDMA ERI icon mode, 829 * 0 - ON 830 * 1 - FLASHING 831 */ 832 public int getCdmaEriIconMode() { 833 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 834 return -1; 835 } 836 837 /** 838 * Returns the CDMA ERI text, 839 */ 840 public String getCdmaEriText() { 841 logUnexpectedCdmaMethodCall("getCdmaEriText"); 842 return "GSM nw, no ERI"; 843 } 844 845 public String getCdmaMin() { 846 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 847 logUnexpectedCdmaMethodCall("getCdmaMin"); 848 return null; 849 } 850 851 public boolean isMinInfoReady() { 852 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 853 logUnexpectedCdmaMethodCall("isMinInfoReady"); 854 return false; 855 } 856 857 public String getCdmaPrlVersion(){ 858 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 859 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 860 return null; 861 } 862 863 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 864 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 865 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 866 } 867 868 public void exitEmergencyCallbackMode() { 869 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 870 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 871 } 872 873 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 874 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 875 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 876 } 877 878 public void unregisterForCdmaOtaStatusChange(Handler h) { 879 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 880 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 881 } 882 883 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 884 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 885 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 886 } 887 888 public void unregisterForSubscriptionInfoReady(Handler h) { 889 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 890 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 891 } 892 893 /** 894 * Returns true if OTA Service Provisioning needs to be performed. 895 * If not overridden return false. 896 */ 897 public boolean needsOtaServiceProvisioning() { 898 return false; 899 } 900 901 /** 902 * Return true if number is an OTASP number. 903 * If not overridden return false. 904 */ 905 public boolean isOtaSpNumber(String dialStr) { 906 return false; 907 } 908 909 public void registerForCallWaiting(Handler h, int what, Object obj){ 910 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 911 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 912 } 913 914 public void unregisterForCallWaiting(Handler h){ 915 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 916 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 917 } 918 919 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 920 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 921 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 922 } 923 924 public void unregisterForEcmTimerReset(Handler h) { 925 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 926 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 927 } 928 929 public void registerForSignalInfo(Handler h, int what, Object obj) { 930 mCM.registerForSignalInfo(h, what, obj); 931 } 932 933 public void unregisterForSignalInfo(Handler h) { 934 mCM.unregisterForSignalInfo(h); 935 } 936 937 public void registerForDisplayInfo(Handler h, int what, Object obj) { 938 mCM.registerForDisplayInfo(h, what, obj); 939 } 940 941 public void unregisterForDisplayInfo(Handler h) { 942 mCM.unregisterForDisplayInfo(h); 943 } 944 945 public void registerForNumberInfo(Handler h, int what, Object obj) { 946 mCM.registerForNumberInfo(h, what, obj); 947 } 948 949 public void unregisterForNumberInfo(Handler h) { 950 mCM.unregisterForNumberInfo(h); 951 } 952 953 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 954 mCM.registerForRedirectedNumberInfo(h, what, obj); 955 } 956 957 public void unregisterForRedirectedNumberInfo(Handler h) { 958 mCM.unregisterForRedirectedNumberInfo(h); 959 } 960 961 public void registerForLineControlInfo(Handler h, int what, Object obj) { 962 mCM.registerForLineControlInfo( h, what, obj); 963 } 964 965 public void unregisterForLineControlInfo(Handler h) { 966 mCM.unregisterForLineControlInfo(h); 967 } 968 969 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 970 mCM.registerFoT53ClirlInfo(h, what, obj); 971 } 972 973 public void unregisterForT53ClirInfo(Handler h) { 974 mCM.unregisterForT53ClirInfo(h); 975 } 976 977 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 978 mCM.registerForT53AudioControlInfo( h, what, obj); 979 } 980 981 public void unregisterForT53AudioControlInfo(Handler h) { 982 mCM.unregisterForT53AudioControlInfo(h); 983 } 984 985 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 986 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 987 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 988 } 989 990 public void unsetOnEcbModeExitResponse(Handler h){ 991 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 992 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 993 } 994 995 public String[] getActiveApnTypes() { 996 return mDataConnectionTracker.getActiveApnTypes(); 997 } 998 999 public String getActiveApnHost(String apnType) { 1000 return mDataConnectionTracker.getActiveApnString(apnType); 1001 } 1002 1003 public LinkProperties getLinkProperties(String apnType) { 1004 return mDataConnectionTracker.getLinkProperties(apnType); 1005 } 1006 1007 public LinkCapabilities getLinkCapabilities(String apnType) { 1008 return mDataConnectionTracker.getLinkCapabilities(apnType); 1009 } 1010 1011 public int enableApnType(String type) { 1012 return mDataConnectionTracker.enableApnType(type); 1013 } 1014 1015 public int disableApnType(String type) { 1016 return mDataConnectionTracker.disableApnType(type); 1017 } 1018 1019 public boolean isDataConnectivityPossible() { 1020 return isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT); 1021 } 1022 1023 public boolean isDataConnectivityPossible(String apnType) { 1024 return ((mDataConnectionTracker != null) && 1025 (mDataConnectionTracker.isDataPossible(apnType))); 1026 } 1027 1028 /** 1029 * Notify registrants of a new ringing Connection. 1030 * Subclasses of Phone probably want to replace this with a 1031 * version scoped to their packages 1032 */ 1033 protected void notifyNewRingingConnectionP(Connection cn) { 1034 if (!mIsVoiceCapable) 1035 return; 1036 AsyncResult ar = new AsyncResult(null, cn, null); 1037 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 1038 } 1039 1040 /** 1041 * Notify registrants of a RING event. 1042 */ 1043 private void notifyIncomingRing() { 1044 if (!mIsVoiceCapable) 1045 return; 1046 AsyncResult ar = new AsyncResult(null, this, null); 1047 mIncomingRingRegistrants.notifyRegistrants(ar); 1048 } 1049 1050 /** 1051 * Send the incoming call Ring notification if conditions are right. 1052 */ 1053 private void sendIncomingCallRingNotification(int token) { 1054 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 1055 (token == mCallRingContinueToken)) { 1056 Log.d(LOG_TAG, "Sending notifyIncomingRing"); 1057 notifyIncomingRing(); 1058 sendMessageDelayed( 1059 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1060 } else { 1061 Log.d(LOG_TAG, "Ignoring ring notification request," 1062 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1063 + " token=" + token 1064 + " mCallRingContinueToken=" + mCallRingContinueToken 1065 + " mIsVoiceCapable=" + mIsVoiceCapable); 1066 } 1067 } 1068 1069 public boolean isCspPlmnEnabled() { 1070 // This function should be overridden by the class GSMPhone. 1071 // Not implemented in CDMAPhone. 1072 logUnexpectedGsmMethodCall("isCspPlmnEnabled"); 1073 return false; 1074 } 1075 1076 public IsimRecords getIsimRecords() { 1077 Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 1078 return null; 1079 } 1080 1081 public void requestIsimAuthentication(String nonce, Message result) { 1082 Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices"); 1083 } 1084 1085 public String getMsisdn() { 1086 logUnexpectedGsmMethodCall("getMsisdn"); 1087 return null; 1088 } 1089 1090 /** 1091 * Common error logger method for unexpected calls to CDMA-only methods. 1092 */ 1093 private static void logUnexpectedCdmaMethodCall(String name) 1094 { 1095 Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1096 "called, CDMAPhone inactive."); 1097 } 1098 1099 public DataState getDataConnectionState() { 1100 return getDataConnectionState(APN_TYPE_DEFAULT); 1101 } 1102 1103 /** 1104 * Common error logger method for unexpected calls to GSM/WCDMA-only methods. 1105 */ 1106 private static void logUnexpectedGsmMethodCall(String name) { 1107 Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1108 "called, GSMPhone inactive."); 1109 } 1110 1111 // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone. 1112 public void notifyCallForwardingIndicator() { 1113 // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone. 1114 Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); 1115 } 1116 1117 public void notifyDataConnectionFailed(String reason, String apnType) { 1118 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 1119 } 1120 1121 /** 1122 * {@inheritDoc} 1123 */ 1124 @Override 1125 public int getLteOnCdmaMode() { 1126 return mCM.getLteOnCdmaMode(); 1127 } 1128 1129 /** 1130 * Sets the SIM voice message waiting indicator records. 1131 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 1132 * @param countWaiting The number of messages waiting, if known. Use 1133 * -1 to indicate that an unknown number of 1134 * messages are waiting 1135 */ 1136 @Override 1137 public void setVoiceMessageWaiting(int line, int countWaiting) { 1138 mIccRecords.setVoiceMessageWaiting(line, countWaiting); 1139 } 1140 1141 /** 1142 * Gets the USIM service table from the UICC, if present and available. 1143 * @return an interface to the UsimServiceTable record, or null if not available 1144 */ 1145 @Override 1146 public UsimServiceTable getUsimServiceTable() { 1147 return mIccRecords.getUsimServiceTable(); 1148 } 1149 1150 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1151 pw.println("PhoneBase:"); 1152 pw.println(" mCM=" + mCM); 1153 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 1154 pw.println(" mDataConnectionTracker=" + mDataConnectionTracker); 1155 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 1156 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 1157 pw.println(" mCallRingDelay=" + mCallRingDelay); 1158 pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone); 1159 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 1160 pw.println(" mIccRecords=" + mIccRecords); 1161 pw.println(" mIccCard=" + mIccCard.get()); 1162 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 1163 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 1164 pw.println(" mSMS=" + mSMS); 1165 pw.flush(); 1166 pw.println(" mLooper=" + mLooper); 1167 pw.println(" mContext=" + mContext); 1168 pw.println(" mNotifier=" + mNotifier); 1169 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 1170 pw.println(" mUnitTestMode=" + mUnitTestMode); 1171 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 1172 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 1173 pw.println(" getState()=" + getState()); 1174 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 1175 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 1176 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 1177 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 1178 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 1179 pw.flush(); 1180 pw.println(" isInEcm()=" + isInEcm()); 1181 pw.println(" getPhoneName()=" + getPhoneName()); 1182 pw.println(" getPhoneType()=" + getPhoneType()); 1183 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 1184 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 1185 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 1186 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 1187 } 1188 } 1189