PhoneBase.java revision 2cc8c148fa4cb6cba5deac6b011268b4174a0b02
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 /** 747 * Retrieves the ServiceStateTracker of the phone instance. 748 */ 749 public ServiceStateTracker getServiceStateTracker() { 750 return null; 751 } 752 753 /** 754 * Get call tracker 755 */ 756 public CallTracker getCallTracker() { 757 return null; 758 } 759 760 public AppType getCurrentUiccAppType() { 761 UiccCardApplication currentApp = mUiccApplication.get(); 762 if (currentApp != null) { 763 return currentApp.getType(); 764 } 765 return AppType.APPTYPE_UNKNOWN; 766 } 767 768 @Override 769 public IccCard getIccCard() { 770 return null; 771 //throw new Exception("getIccCard Shouldn't be called from PhoneBase"); 772 } 773 774 @Override 775 public String getIccSerialNumber() { 776 IccRecords r = mIccRecords.get(); 777 return (r != null) ? r.getIccId() : ""; 778 } 779 780 @Override 781 public boolean getIccRecordsLoaded() { 782 IccRecords r = mIccRecords.get(); 783 return (r != null) ? r.getRecordsLoaded() : false; 784 } 785 786 /** 787 * @return all available cell information or null if none. 788 */ 789 @Override 790 public List<CellInfo> getAllCellInfo() { 791 return getServiceStateTracker().getAllCellInfo(); 792 } 793 794 @Override 795 public boolean getMessageWaitingIndicator() { 796 IccRecords r = mIccRecords.get(); 797 return (r != null) ? r.getVoiceMessageWaiting() : false; 798 } 799 800 @Override 801 public boolean getCallForwardingIndicator() { 802 IccRecords r = mIccRecords.get(); 803 return (r != null) ? r.getVoiceCallForwardingFlag() : false; 804 } 805 806 /** 807 * Query the status of the CDMA roaming preference 808 */ 809 @Override 810 public void queryCdmaRoamingPreference(Message response) { 811 mCi.queryCdmaRoamingPreference(response); 812 } 813 814 /** 815 * Get the signal strength 816 */ 817 @Override 818 public SignalStrength getSignalStrength() { 819 ServiceStateTracker sst = getServiceStateTracker(); 820 if (sst == null) { 821 return new SignalStrength(); 822 } else { 823 return sst.getSignalStrength(); 824 } 825 } 826 827 /** 828 * Set the status of the CDMA roaming preference 829 */ 830 @Override 831 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 832 mCi.setCdmaRoamingPreference(cdmaRoamingType, response); 833 } 834 835 /** 836 * Set the status of the CDMA subscription mode 837 */ 838 @Override 839 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 840 mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 841 } 842 843 /** 844 * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only 845 */ 846 @Override 847 public void setPreferredNetworkType(int networkType, Message response) { 848 mCi.setPreferredNetworkType(networkType, response); 849 } 850 851 @Override 852 public void getPreferredNetworkType(Message response) { 853 mCi.getPreferredNetworkType(response); 854 } 855 856 @Override 857 public void getSmscAddress(Message result) { 858 mCi.getSmscAddress(result); 859 } 860 861 @Override 862 public void setSmscAddress(String address, Message result) { 863 mCi.setSmscAddress(address, result); 864 } 865 866 @Override 867 public void setTTYMode(int ttyMode, Message onComplete) { 868 mCi.setTTYMode(ttyMode, onComplete); 869 } 870 871 @Override 872 public void queryTTYMode(Message onComplete) { 873 mCi.queryTTYMode(onComplete); 874 } 875 876 @Override 877 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 878 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 879 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 880 } 881 882 @Override 883 public void getEnhancedVoicePrivacy(Message onComplete) { 884 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 885 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 886 } 887 888 @Override 889 public void setBandMode(int bandMode, Message response) { 890 mCi.setBandMode(bandMode, response); 891 } 892 893 @Override 894 public void queryAvailableBandMode(Message response) { 895 mCi.queryAvailableBandMode(response); 896 } 897 898 @Override 899 public void invokeOemRilRequestRaw(byte[] data, Message response) { 900 mCi.invokeOemRilRequestRaw(data, response); 901 } 902 903 @Override 904 public void invokeOemRilRequestStrings(String[] strings, Message response) { 905 mCi.invokeOemRilRequestStrings(strings, response); 906 } 907 908 @Override 909 public void notifyDataActivity() { 910 mNotifier.notifyDataActivity(this); 911 } 912 913 public void notifyMessageWaitingIndicator() { 914 // Do not notify voice mail waiting if device doesn't support voice 915 if (!mIsVoiceCapable) 916 return; 917 918 // This function is added to send the notification to DefaultPhoneNotifier. 919 mNotifier.notifyMessageWaitingChanged(this); 920 } 921 922 public void notifyDataConnection(String reason, String apnType, 923 PhoneConstants.DataState state) { 924 mNotifier.notifyDataConnection(this, reason, apnType, state); 925 } 926 927 public void notifyDataConnection(String reason, String apnType) { 928 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 929 } 930 931 public void notifyDataConnection(String reason) { 932 String types[] = getActiveApnTypes(); 933 for (String apnType : types) { 934 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 935 } 936 } 937 938 public void notifyOtaspChanged(int otaspMode) { 939 mNotifier.notifyOtaspChanged(this, otaspMode); 940 } 941 942 public void notifySignalStrength() { 943 mNotifier.notifySignalStrength(this); 944 } 945 946 public void notifyCellInfo(List<CellInfo> cellInfo) { 947 mNotifier.notifyCellInfo(this, cellInfo); 948 } 949 950 /** 951 * @return true if a mobile originating emergency call is active 952 */ 953 public boolean isInEmergencyCall() { 954 return false; 955 } 956 957 /** 958 * @return true if we are in the emergency call back mode. This is a period where 959 * the phone should be using as little power as possible and be ready to receive an 960 * incoming call from the emergency operator. 961 */ 962 public boolean isInEcm() { 963 return false; 964 } 965 966 @Override 967 public abstract int getPhoneType(); 968 969 /** @hide */ 970 @Override 971 public int getVoiceMessageCount(){ 972 return 0; 973 } 974 975 /** 976 * Returns the CDMA ERI icon index to display 977 */ 978 @Override 979 public int getCdmaEriIconIndex() { 980 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 981 return -1; 982 } 983 984 /** 985 * Returns the CDMA ERI icon mode, 986 * 0 - ON 987 * 1 - FLASHING 988 */ 989 @Override 990 public int getCdmaEriIconMode() { 991 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 992 return -1; 993 } 994 995 /** 996 * Returns the CDMA ERI text, 997 */ 998 @Override 999 public String getCdmaEriText() { 1000 logUnexpectedCdmaMethodCall("getCdmaEriText"); 1001 return "GSM nw, no ERI"; 1002 } 1003 1004 @Override 1005 public String getCdmaMin() { 1006 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1007 logUnexpectedCdmaMethodCall("getCdmaMin"); 1008 return null; 1009 } 1010 1011 @Override 1012 public boolean isMinInfoReady() { 1013 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1014 logUnexpectedCdmaMethodCall("isMinInfoReady"); 1015 return false; 1016 } 1017 1018 @Override 1019 public String getCdmaPrlVersion(){ 1020 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1021 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 1022 return null; 1023 } 1024 1025 @Override 1026 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 1027 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1028 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 1029 } 1030 1031 @Override 1032 public void exitEmergencyCallbackMode() { 1033 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1034 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 1035 } 1036 1037 @Override 1038 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 1039 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1040 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 1041 } 1042 1043 @Override 1044 public void unregisterForCdmaOtaStatusChange(Handler h) { 1045 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1046 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 1047 } 1048 1049 @Override 1050 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 1051 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1052 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 1053 } 1054 1055 @Override 1056 public void unregisterForSubscriptionInfoReady(Handler h) { 1057 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1058 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 1059 } 1060 1061 /** 1062 * Returns true if OTA Service Provisioning needs to be performed. 1063 * If not overridden return false. 1064 */ 1065 @Override 1066 public boolean needsOtaServiceProvisioning() { 1067 return false; 1068 } 1069 1070 /** 1071 * Return true if number is an OTASP number. 1072 * If not overridden return false. 1073 */ 1074 @Override 1075 public boolean isOtaSpNumber(String dialStr) { 1076 return false; 1077 } 1078 1079 @Override 1080 public void registerForCallWaiting(Handler h, int what, Object obj){ 1081 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1082 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 1083 } 1084 1085 @Override 1086 public void unregisterForCallWaiting(Handler h){ 1087 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1088 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 1089 } 1090 1091 @Override 1092 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 1093 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1094 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 1095 } 1096 1097 @Override 1098 public void unregisterForEcmTimerReset(Handler h) { 1099 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1100 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 1101 } 1102 1103 @Override 1104 public void registerForSignalInfo(Handler h, int what, Object obj) { 1105 mCi.registerForSignalInfo(h, what, obj); 1106 } 1107 1108 @Override 1109 public void unregisterForSignalInfo(Handler h) { 1110 mCi.unregisterForSignalInfo(h); 1111 } 1112 1113 @Override 1114 public void registerForDisplayInfo(Handler h, int what, Object obj) { 1115 mCi.registerForDisplayInfo(h, what, obj); 1116 } 1117 1118 @Override 1119 public void unregisterForDisplayInfo(Handler h) { 1120 mCi.unregisterForDisplayInfo(h); 1121 } 1122 1123 @Override 1124 public void registerForNumberInfo(Handler h, int what, Object obj) { 1125 mCi.registerForNumberInfo(h, what, obj); 1126 } 1127 1128 @Override 1129 public void unregisterForNumberInfo(Handler h) { 1130 mCi.unregisterForNumberInfo(h); 1131 } 1132 1133 @Override 1134 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 1135 mCi.registerForRedirectedNumberInfo(h, what, obj); 1136 } 1137 1138 @Override 1139 public void unregisterForRedirectedNumberInfo(Handler h) { 1140 mCi.unregisterForRedirectedNumberInfo(h); 1141 } 1142 1143 @Override 1144 public void registerForLineControlInfo(Handler h, int what, Object obj) { 1145 mCi.registerForLineControlInfo( h, what, obj); 1146 } 1147 1148 @Override 1149 public void unregisterForLineControlInfo(Handler h) { 1150 mCi.unregisterForLineControlInfo(h); 1151 } 1152 1153 @Override 1154 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 1155 mCi.registerFoT53ClirlInfo(h, what, obj); 1156 } 1157 1158 @Override 1159 public void unregisterForT53ClirInfo(Handler h) { 1160 mCi.unregisterForT53ClirInfo(h); 1161 } 1162 1163 @Override 1164 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 1165 mCi.registerForT53AudioControlInfo( h, what, obj); 1166 } 1167 1168 @Override 1169 public void unregisterForT53AudioControlInfo(Handler h) { 1170 mCi.unregisterForT53AudioControlInfo(h); 1171 } 1172 1173 @Override 1174 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 1175 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1176 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 1177 } 1178 1179 @Override 1180 public void unsetOnEcbModeExitResponse(Handler h){ 1181 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1182 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 1183 } 1184 1185 @Override 1186 public String[] getActiveApnTypes() { 1187 return mDcTracker.getActiveApnTypes(); 1188 } 1189 1190 @Override 1191 public String getActiveApnHost(String apnType) { 1192 return mDcTracker.getActiveApnString(apnType); 1193 } 1194 1195 @Override 1196 public LinkProperties getLinkProperties(String apnType) { 1197 return mDcTracker.getLinkProperties(apnType); 1198 } 1199 1200 @Override 1201 public LinkCapabilities getLinkCapabilities(String apnType) { 1202 return mDcTracker.getLinkCapabilities(apnType); 1203 } 1204 1205 @Override 1206 public int enableApnType(String type) { 1207 return mDcTracker.enableApnType(type); 1208 } 1209 1210 @Override 1211 public int disableApnType(String type) { 1212 return mDcTracker.disableApnType(type); 1213 } 1214 1215 @Override 1216 public boolean isDataConnectivityPossible() { 1217 return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT); 1218 } 1219 1220 @Override 1221 public boolean isDataConnectivityPossible(String apnType) { 1222 return ((mDcTracker != null) && 1223 (mDcTracker.isDataPossible(apnType))); 1224 } 1225 1226 /** 1227 * Notify registrants of a new ringing Connection. 1228 * Subclasses of Phone probably want to replace this with a 1229 * version scoped to their packages 1230 */ 1231 protected void notifyNewRingingConnectionP(Connection cn) { 1232 if (!mIsVoiceCapable) 1233 return; 1234 AsyncResult ar = new AsyncResult(null, cn, null); 1235 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 1236 } 1237 1238 /** 1239 * Notify registrants of a RING event. 1240 */ 1241 private void notifyIncomingRing() { 1242 if (!mIsVoiceCapable) 1243 return; 1244 AsyncResult ar = new AsyncResult(null, this, null); 1245 mIncomingRingRegistrants.notifyRegistrants(ar); 1246 } 1247 1248 /** 1249 * Send the incoming call Ring notification if conditions are right. 1250 */ 1251 private void sendIncomingCallRingNotification(int token) { 1252 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 1253 (token == mCallRingContinueToken)) { 1254 Rlog.d(LOG_TAG, "Sending notifyIncomingRing"); 1255 notifyIncomingRing(); 1256 sendMessageDelayed( 1257 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1258 } else { 1259 Rlog.d(LOG_TAG, "Ignoring ring notification request," 1260 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1261 + " token=" + token 1262 + " mCallRingContinueToken=" + mCallRingContinueToken 1263 + " mIsVoiceCapable=" + mIsVoiceCapable); 1264 } 1265 } 1266 1267 @Override 1268 public boolean isCspPlmnEnabled() { 1269 // This function should be overridden by the class GSMPhone. 1270 // Not implemented in CDMAPhone. 1271 logUnexpectedGsmMethodCall("isCspPlmnEnabled"); 1272 return false; 1273 } 1274 1275 @Override 1276 public IsimRecords getIsimRecords() { 1277 Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 1278 return null; 1279 } 1280 1281 @Override 1282 public void requestIsimAuthentication(String nonce, Message result) { 1283 Rlog.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices"); 1284 } 1285 1286 @Override 1287 public String getMsisdn() { 1288 logUnexpectedGsmMethodCall("getMsisdn"); 1289 return null; 1290 } 1291 1292 /** 1293 * Common error logger method for unexpected calls to CDMA-only methods. 1294 */ 1295 private static void logUnexpectedCdmaMethodCall(String name) 1296 { 1297 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1298 "called, CDMAPhone inactive."); 1299 } 1300 1301 @Override 1302 public PhoneConstants.DataState getDataConnectionState() { 1303 return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT); 1304 } 1305 1306 /** 1307 * Common error logger method for unexpected calls to GSM/WCDMA-only methods. 1308 */ 1309 private static void logUnexpectedGsmMethodCall(String name) { 1310 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1311 "called, GSMPhone inactive."); 1312 } 1313 1314 // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone. 1315 public void notifyCallForwardingIndicator() { 1316 // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone. 1317 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); 1318 } 1319 1320 public void notifyDataConnectionFailed(String reason, String apnType) { 1321 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 1322 } 1323 1324 /** 1325 * {@inheritDoc} 1326 */ 1327 @Override 1328 public int getLteOnCdmaMode() { 1329 return mCi.getLteOnCdmaMode(); 1330 } 1331 1332 /** 1333 * Sets the SIM voice message waiting indicator records. 1334 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 1335 * @param countWaiting The number of messages waiting, if known. Use 1336 * -1 to indicate that an unknown number of 1337 * messages are waiting 1338 */ 1339 @Override 1340 public void setVoiceMessageWaiting(int line, int countWaiting) { 1341 IccRecords r = mIccRecords.get(); 1342 if (r != null) { 1343 r.setVoiceMessageWaiting(line, countWaiting); 1344 } 1345 } 1346 1347 /** 1348 * Gets the USIM service table from the UICC, if present and available. 1349 * @return an interface to the UsimServiceTable record, or null if not available 1350 */ 1351 @Override 1352 public UsimServiceTable getUsimServiceTable() { 1353 IccRecords r = mIccRecords.get(); 1354 return (r != null) ? r.getUsimServiceTable() : null; 1355 } 1356 1357 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1358 pw.println("PhoneBase:"); 1359 pw.println(" mCi=" + mCi); 1360 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 1361 pw.println(" mDcTracker=" + mDcTracker); 1362 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 1363 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 1364 pw.println(" mCallRingDelay=" + mCallRingDelay); 1365 pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone); 1366 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 1367 pw.println(" mIccRecords=" + mIccRecords.get()); 1368 pw.println(" mUiccApplication=" + mUiccApplication.get()); 1369 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 1370 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 1371 pw.println(" mSMS=" + mSMS); 1372 pw.flush(); 1373 pw.println(" mLooper=" + mLooper); 1374 pw.println(" mContext=" + mContext); 1375 pw.println(" mNotifier=" + mNotifier); 1376 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 1377 pw.println(" mUnitTestMode=" + mUnitTestMode); 1378 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 1379 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 1380 pw.println(" getState()=" + getState()); 1381 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 1382 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 1383 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 1384 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 1385 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 1386 pw.flush(); 1387 pw.println(" isInEcm()=" + isInEcm()); 1388 pw.println(" getPhoneName()=" + getPhoneName()); 1389 pw.println(" getPhoneType()=" + getPhoneType()); 1390 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 1391 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 1392 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 1393 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 1394 } 1395} 1396