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