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