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