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