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