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