PhoneBase.java revision 4be56374921b52d54b80889540d982f39d26e3ab
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.BroadcastReceiver; 20import android.content.Context; 21import android.content.Intent; 22import android.content.IntentFilter; 23import android.content.SharedPreferences; 24import android.net.LinkProperties; 25import android.net.NetworkCapabilities; 26import android.net.wifi.WifiManager; 27import android.os.AsyncResult; 28import android.os.Build; 29import android.os.Handler; 30import android.os.Looper; 31import android.os.Message; 32import android.os.Registrant; 33import android.os.RegistrantList; 34import android.os.SystemProperties; 35import android.preference.PreferenceManager; 36import android.provider.Settings; 37import android.telecom.VideoProfile; 38import android.telephony.CellIdentityCdma; 39import android.telephony.CellInfo; 40import android.telephony.CellInfoCdma; 41import android.telephony.DataConnectionRealTimeInfo; 42import android.telephony.RadioAccessFamily; 43import android.telephony.Rlog; 44import android.telephony.ServiceState; 45import android.telephony.SignalStrength; 46import android.telephony.SubscriptionManager; 47import android.telephony.VoLteServiceState; 48import android.text.TextUtils; 49 50import com.android.ims.ImsManager; 51import com.android.internal.R; 52import com.android.internal.telephony.dataconnection.DcTrackerBase; 53import com.android.internal.telephony.imsphone.ImsPhone; 54import com.android.internal.telephony.RadioCapability; 55import com.android.internal.telephony.test.SimulatedRadioControl; 56import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 57import com.android.internal.telephony.uicc.IccFileHandler; 58import com.android.internal.telephony.uicc.IccRecords; 59import com.android.internal.telephony.uicc.IsimRecords; 60import com.android.internal.telephony.uicc.UiccCard; 61import com.android.internal.telephony.uicc.UiccCardApplication; 62import com.android.internal.telephony.uicc.UiccController; 63import com.android.internal.telephony.uicc.UsimServiceTable; 64 65import java.io.FileDescriptor; 66import java.io.PrintWriter; 67import java.util.ArrayList; 68import java.util.HashSet; 69import java.util.List; 70import java.util.Locale; 71import java.util.Set; 72import java.util.concurrent.atomic.AtomicReference; 73 74/** 75 * (<em>Not for SDK use</em>) 76 * A base implementation for the com.android.internal.telephony.Phone interface. 77 * 78 * Note that implementations of Phone.java are expected to be used 79 * from a single application thread. This should be the same thread that 80 * originally called PhoneFactory to obtain the interface. 81 * 82 * {@hide} 83 * 84 */ 85 86public abstract class PhoneBase extends Handler implements Phone { 87 private static final String LOG_TAG = "PhoneBase"; 88 89 private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() { 90 @Override 91 public void onReceive(Context context, Intent intent) { 92 Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction()); 93 if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) { 94 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID, 95 SubscriptionManager.INVALID_PHONE_INDEX); 96 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId); 97 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX || 98 extraPhoneId != getPhoneId()) { 99 return; 100 } 101 } 102 103 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) { 104 mImsServiceReady = true; 105 updateImsPhone(); 106 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) { 107 mImsServiceReady = false; 108 updateImsPhone(); 109 } 110 } 111 }; 112 113 // Key used to read and write the saved network selection numeric value 114 public static final String NETWORK_SELECTION_KEY = "network_selection_key"; 115 // Key used to read and write the saved network selection operator name 116 public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key"; 117 118 119 // Key used to read/write "disable data connection on boot" pref (used for testing) 120 public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key"; 121 122 /* Event Constants */ 123 protected static final int EVENT_RADIO_AVAILABLE = 1; 124 /** Supplementary Service Notification received. */ 125 protected static final int EVENT_SSN = 2; 126 protected static final int EVENT_SIM_RECORDS_LOADED = 3; 127 protected static final int EVENT_MMI_DONE = 4; 128 protected static final int EVENT_RADIO_ON = 5; 129 protected static final int EVENT_GET_BASEBAND_VERSION_DONE = 6; 130 protected static final int EVENT_USSD = 7; 131 protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8; 132 protected static final int EVENT_GET_IMEI_DONE = 9; 133 protected static final int EVENT_GET_IMEISV_DONE = 10; 134 protected static final int EVENT_GET_SIM_STATUS_DONE = 11; 135 protected static final int EVENT_SET_CALL_FORWARD_DONE = 12; 136 protected static final int EVENT_GET_CALL_FORWARD_DONE = 13; 137 protected static final int EVENT_CALL_RING = 14; 138 protected static final int EVENT_CALL_RING_CONTINUE = 15; 139 140 // Used to intercept the carrier selection calls so that 141 // we can save the values. 142 protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 16; 143 protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17; 144 protected static final int EVENT_SET_CLIR_COMPLETE = 18; 145 protected static final int EVENT_REGISTERED_TO_NETWORK = 19; 146 protected static final int EVENT_SET_VM_NUMBER_DONE = 20; 147 // Events for CDMA support 148 protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 21; 149 protected static final int EVENT_RUIM_RECORDS_LOADED = 22; 150 protected static final int EVENT_NV_READY = 23; 151 protected static final int EVENT_SET_ENHANCED_VP = 24; 152 protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25; 153 protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26; 154 protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27; 155 // other 156 protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28; 157 protected static final int EVENT_ICC_RECORD_EVENTS = 29; 158 protected static final int EVENT_ICC_CHANGED = 30; 159 // Single Radio Voice Call Continuity 160 protected static final int EVENT_SRVCC_STATE_CHANGED = 31; 161 protected static final int EVENT_INITIATE_SILENT_REDIAL = 32; 162 protected static final int EVENT_RADIO_NOT_AVAILABLE = 33; 163 protected static final int EVENT_UNSOL_OEM_HOOK_RAW = 34; 164 protected static final int EVENT_GET_RADIO_CAPABILITY = 35; 165 protected static final int EVENT_SS = 36; 166 protected static final int EVENT_LAST = EVENT_SS; 167 168 // For shared prefs. 169 private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_"; 170 private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_"; 171 private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_"; 172 private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_"; 173 174 // Key used to read/write current CLIR setting 175 public static final String CLIR_KEY = "clir_key"; 176 177 // Key used for storing voice mail count 178 public static final String VM_COUNT = "vm_count_key"; 179 // Key used to read/write the ID for storing the voice mail 180 public static final String VM_ID = "vm_id_key"; 181 182 // Key used to read/write "disable DNS server check" pref (used for testing) 183 public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key"; 184 185 /** 186 * Small container class used to hold information relevant to 187 * the carrier selection process. operatorNumeric can be "" 188 * if we are looking for automatic selection. operatorAlphaLong is the 189 * corresponding operator name. 190 */ 191 protected static class NetworkSelectMessage { 192 public Message message; 193 public String operatorNumeric; 194 public String operatorAlphaLong; 195 } 196 197 /* Instance Variables */ 198 public CommandsInterface mCi; 199 private int mVmCount = 0; 200 boolean mDnsCheckDisabled; 201 public DcTrackerBase mDcTracker; 202 boolean mDoesRilSendMultipleCallRing; 203 int mCallRingContinueToken; 204 int mCallRingDelay; 205 public boolean mIsTheCurrentActivePhone = true; 206 boolean mIsVoiceCapable = true; 207 protected UiccController mUiccController = null; 208 public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>(); 209 public SmsStorageMonitor mSmsStorageMonitor; 210 public SmsUsageMonitor mSmsUsageMonitor; 211 protected AtomicReference<UiccCardApplication> mUiccApplication = 212 new AtomicReference<UiccCardApplication>(); 213 214 private TelephonyTester mTelephonyTester; 215 private final String mName; 216 private final String mActionDetached; 217 private final String mActionAttached; 218 219 protected int mPhoneId; 220 221 private final Object mImsLock = new Object(); 222 private boolean mImsServiceReady = false; 223 protected ImsPhone mImsPhone = null; 224 225 protected int mRadioAccessFamily = RadioAccessFamily.RAF_UNKNOWN; 226 227 @Override 228 public String getPhoneName() { 229 return mName; 230 } 231 232 public String getNai(){ 233 return null; 234 } 235 236 /** 237 * Return the ActionDetached string. When this action is received by components 238 * they are to simulate detaching from the network. 239 * 240 * @return com.android.internal.telephony.{mName}.action_detached 241 * {mName} is GSM, CDMA ... 242 */ 243 public String getActionDetached() { 244 return mActionDetached; 245 } 246 247 /** 248 * Return the ActionAttached string. When this action is received by components 249 * they are to simulate attaching to the network. 250 * 251 * @return com.android.internal.telephony.{mName}.action_detached 252 * {mName} is GSM, CDMA ... 253 */ 254 public String getActionAttached() { 255 return mActionAttached; 256 } 257 258 /** 259 * Set a system property, unless we're in unit test mode 260 */ 261 // CAF_MSIM TODO this need to be replated with TelephonyManager API ? 262 public void setSystemProperty(String property, String value) { 263 if(getUnitTestMode()) { 264 return; 265 } 266 SystemProperties.set(property, value); 267 } 268 269 /** 270 * Set a system property, unless we're in unit test mode 271 */ 272 // CAF_MSIM TODO this need to be replated with TelephonyManager API ? 273 public String getSystemProperty(String property, String defValue) { 274 if(getUnitTestMode()) { 275 return null; 276 } 277 return SystemProperties.get(property, defValue); 278 } 279 280 281 protected final RegistrantList mPreciseCallStateRegistrants 282 = new RegistrantList(); 283 284 protected final RegistrantList mHandoverRegistrants 285 = new RegistrantList(); 286 287 protected final RegistrantList mNewRingingConnectionRegistrants 288 = new RegistrantList(); 289 290 protected final RegistrantList mIncomingRingRegistrants 291 = new RegistrantList(); 292 293 protected final RegistrantList mDisconnectRegistrants 294 = new RegistrantList(); 295 296 protected final RegistrantList mServiceStateRegistrants 297 = new RegistrantList(); 298 299 protected final RegistrantList mMmiCompleteRegistrants 300 = new RegistrantList(); 301 302 protected final RegistrantList mMmiRegistrants 303 = new RegistrantList(); 304 305 protected final RegistrantList mUnknownConnectionRegistrants 306 = new RegistrantList(); 307 308 protected final RegistrantList mSuppServiceFailedRegistrants 309 = new RegistrantList(); 310 311 protected final RegistrantList mRadioOffOrNotAvailableRegistrants 312 = new RegistrantList(); 313 314 protected final RegistrantList mSimRecordsLoadedRegistrants 315 = new RegistrantList(); 316 317 protected Looper mLooper; /* to insure registrants are in correct thread*/ 318 319 protected final Context mContext; 320 321 /** 322 * PhoneNotifier is an abstraction for all system-wide 323 * state change notification. DefaultPhoneNotifier is 324 * used here unless running we're inside a unit test. 325 */ 326 protected PhoneNotifier mNotifier; 327 328 protected SimulatedRadioControl mSimulatedRadioControl; 329 330 boolean mUnitTestMode; 331 332 /** 333 * Constructs a PhoneBase in normal (non-unit test) mode. 334 * 335 * @param notifier An instance of DefaultPhoneNotifier, 336 * @param context Context object from hosting application 337 * unless unit testing. 338 * @param ci the CommandsInterface 339 */ 340 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci) { 341 this(name, notifier, context, ci, false); 342 } 343 344 /** 345 * Constructs a PhoneBase in normal (non-unit test) mode. 346 * 347 * @param notifier An instance of DefaultPhoneNotifier, 348 * @param context Context object from hosting application 349 * unless unit testing. 350 * @param ci is CommandsInterface 351 * @param unitTestMode when true, prevents notifications 352 * of state change events 353 */ 354 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 355 boolean unitTestMode) { 356 this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX); 357 } 358 359 /** 360 * Constructs a PhoneBase in normal (non-unit test) mode. 361 * 362 * @param notifier An instance of DefaultPhoneNotifier, 363 * @param context Context object from hosting application 364 * unless unit testing. 365 * @param ci is CommandsInterface 366 * @param unitTestMode when true, prevents notifications 367 * of state change events 368 * @param subscription is current phone subscription 369 */ 370 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 371 boolean unitTestMode, int phoneId) { 372 mPhoneId = phoneId; 373 mName = name; 374 mNotifier = notifier; 375 mContext = context; 376 mLooper = Looper.myLooper(); 377 mCi = ci; 378 mActionDetached = this.getClass().getPackage().getName() + ".action_detached"; 379 mActionAttached = this.getClass().getPackage().getName() + ".action_attached"; 380 381 if (Build.IS_DEBUGGABLE) { 382 mTelephonyTester = new TelephonyTester(this); 383 } 384 385 setUnitTestMode(unitTestMode); 386 387 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 388 mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); 389 mCi.setOnCallRing(this, EVENT_CALL_RING, null); 390 391 /* "Voice capable" means that this device supports circuit-switched 392 * (i.e. voice) phone calls over the telephony network, and is allowed 393 * to display the in-call UI while a cellular voice call is active. 394 * This will be false on "data only" devices which can't make voice 395 * calls and don't support any in-call UI. 396 */ 397 mIsVoiceCapable = mContext.getResources().getBoolean( 398 com.android.internal.R.bool.config_voice_capable); 399 400 /** 401 * Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs 402 * to be generated locally. Ideally all ring tones should be loops 403 * and this wouldn't be necessary. But to minimize changes to upper 404 * layers it is requested that it be generated by lower layers. 405 * 406 * By default old phones won't have the property set but do generate 407 * the RIL_UNSOL_CALL_RING so the default if there is no property is 408 * true. 409 */ 410 mDoesRilSendMultipleCallRing = SystemProperties.getBoolean( 411 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true); 412 Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 413 414 mCallRingDelay = SystemProperties.getInt( 415 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000); 416 Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay); 417 418 if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) return; 419 420 setPropertiesByCarrier(); 421 422 // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers. 423 mSmsStorageMonitor = new SmsStorageMonitor(this); 424 mSmsUsageMonitor = new SmsUsageMonitor(context); 425 mUiccController = UiccController.getInstance(); 426 mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); 427 428 // Monitor IMS service 429 IntentFilter filter = new IntentFilter(); 430 filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP); 431 filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN); 432 mContext.registerReceiver(mImsIntentReceiver, filter); 433 434 mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null); 435 mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null); 436 } 437 438 @Override 439 public void dispose() { 440 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 441 mContext.unregisterReceiver(mImsIntentReceiver); 442 mCi.unSetOnCallRing(this); 443 // Must cleanup all connectionS and needs to use sendMessage! 444 mDcTracker.cleanUpAllConnections(null); 445 mIsTheCurrentActivePhone = false; 446 // Dispose the SMS usage and storage monitors 447 mSmsStorageMonitor.dispose(); 448 mSmsUsageMonitor.dispose(); 449 mUiccController.unregisterForIccChanged(this); 450 mCi.unregisterForSrvccStateChanged(this); 451 mCi.unSetOnUnsolOemHookRaw(this); 452 453 if (mTelephonyTester != null) { 454 mTelephonyTester.dispose(); 455 } 456 457 ImsPhone imsPhone = mImsPhone; 458 if (imsPhone != null) { 459 imsPhone.unregisterForSilentRedial(this); 460 imsPhone.dispose(); 461 } 462 } 463 } 464 465 @Override 466 public void removeReferences() { 467 mSmsStorageMonitor = null; 468 mSmsUsageMonitor = null; 469 mIccRecords.set(null); 470 mUiccApplication.set(null); 471 mDcTracker = null; 472 mUiccController = null; 473 474 ImsPhone imsPhone = mImsPhone; 475 if (imsPhone != null) { 476 imsPhone.removeReferences(); 477 mImsPhone = null; 478 } 479 } 480 481 /** 482 * When overridden the derived class needs to call 483 * super.handleMessage(msg) so this method has a 484 * a chance to process the message. 485 * 486 * @param msg 487 */ 488 @Override 489 public void handleMessage(Message msg) { 490 AsyncResult ar; 491 492 // messages to be handled whether or not the phone is being destroyed 493 // should only include messages which are being re-directed and do not use 494 // resources of the phone being destroyed 495 // Note: make sure to add code in GSMPhone/CDMAPhone to re-direct here before 496 // they check if phone destroyed. 497 switch (msg.what) { 498 // handle the select network completion callbacks. 499 case EVENT_SET_NETWORK_MANUAL_COMPLETE: 500 case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE: 501 handleSetSelectNetwork((AsyncResult) msg.obj); 502 return; 503 } 504 505 if (!mIsTheCurrentActivePhone) { 506 Rlog.e(LOG_TAG, "Received message " + msg + 507 "[" + msg.what + "] while being destroyed. Ignoring."); 508 return; 509 } 510 switch(msg.what) { 511 case EVENT_CALL_RING: 512 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState()); 513 ar = (AsyncResult)msg.obj; 514 if (ar.exception == null) { 515 PhoneConstants.State state = getState(); 516 if ((!mDoesRilSendMultipleCallRing) 517 && ((state == PhoneConstants.State.RINGING) || 518 (state == PhoneConstants.State.IDLE))) { 519 mCallRingContinueToken += 1; 520 sendIncomingCallRingNotification(mCallRingContinueToken); 521 } else { 522 notifyIncomingRing(); 523 } 524 } 525 break; 526 527 case EVENT_CALL_RING_CONTINUE: 528 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState()); 529 if (getState() == PhoneConstants.State.RINGING) { 530 sendIncomingCallRingNotification(msg.arg1); 531 } 532 break; 533 534 case EVENT_ICC_CHANGED: 535 onUpdateIccAvailability(); 536 break; 537 538 case EVENT_INITIATE_SILENT_REDIAL: 539 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received"); 540 ar = (AsyncResult) msg.obj; 541 if ((ar.exception == null) && (ar.result != null)) { 542 String dialString = (String) ar.result; 543 if (TextUtils.isEmpty(dialString)) return; 544 try { 545 dialInternal(dialString, null, VideoProfile.VideoState.AUDIO_ONLY); 546 } catch (CallStateException e) { 547 Rlog.e(LOG_TAG, "silent redial failed: " + e); 548 } 549 } 550 break; 551 552 case EVENT_SRVCC_STATE_CHANGED: 553 ar = (AsyncResult)msg.obj; 554 if (ar.exception == null) { 555 handleSrvccStateChanged((int[]) ar.result); 556 } else { 557 Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception); 558 } 559 break; 560 561 case EVENT_UNSOL_OEM_HOOK_RAW: 562 ar = (AsyncResult)msg.obj; 563 if (ar.exception == null) { 564 byte[] data = (byte[])ar.result; 565 Rlog.d(LOG_TAG, "EVENT_UNSOL_OEM_HOOK_RAW data=" 566 + IccUtils.bytesToHexString(data)); 567 mNotifier.notifyOemHookRawEventForSubscriber(getSubId(), data); 568 } else { 569 Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception); 570 } 571 break; 572 573 case EVENT_GET_RADIO_CAPABILITY: 574 ar = (AsyncResult) msg.obj; 575 RadioCapability rc = (RadioCapability) ar.result; 576 if (ar.exception != null) { 577 Rlog.d(LOG_TAG, "get phone radio capability fail," 578 + "no need to change mRadioAccessFamily"); 579 } else { 580 mRadioAccessFamily = rc.getRadioAccessFamily(); 581 } 582 Rlog.d(LOG_TAG, "EVENT_GET_RADIO_CAPABILITY :" 583 + "phone RAF : " + mRadioAccessFamily); 584 break; 585 586 default: 587 throw new RuntimeException("unexpected event not handled"); 588 } 589 } 590 591 private void handleSrvccStateChanged(int[] ret) { 592 Rlog.d(LOG_TAG, "handleSrvccStateChanged"); 593 594 ArrayList<Connection> conn = null; 595 ImsPhone imsPhone = mImsPhone; 596 Call.SrvccState srvccState = Call.SrvccState.NONE; 597 if (ret != null && ret.length != 0) { 598 int state = ret[0]; 599 switch(state) { 600 case VoLteServiceState.HANDOVER_STARTED: 601 srvccState = Call.SrvccState.STARTED; 602 if (imsPhone != null) { 603 conn = imsPhone.getHandoverConnection(); 604 migrateFrom(imsPhone); 605 } else { 606 Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null"); 607 } 608 break; 609 case VoLteServiceState.HANDOVER_COMPLETED: 610 srvccState = Call.SrvccState.COMPLETED; 611 if (imsPhone != null) { 612 imsPhone.notifySrvccState(srvccState); 613 } else { 614 Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null"); 615 } 616 break; 617 case VoLteServiceState.HANDOVER_FAILED: 618 case VoLteServiceState.HANDOVER_CANCELED: 619 srvccState = Call.SrvccState.FAILED; 620 break; 621 622 default: 623 //ignore invalid state 624 return; 625 } 626 627 getCallTracker().notifySrvccState(srvccState, conn); 628 629 VoLteServiceState lteState = new VoLteServiceState(state); 630 notifyVoLteServiceStateChanged(lteState); 631 } 632 } 633 634 // Inherited documentation suffices. 635 @Override 636 public Context getContext() { 637 return mContext; 638 } 639 640 // Will be called when icc changed 641 protected abstract void onUpdateIccAvailability(); 642 643 /** 644 * Disables the DNS check (i.e., allows "0.0.0.0"). 645 * Useful for lab testing environment. 646 * @param b true disables the check, false enables. 647 */ 648 @Override 649 public void disableDnsCheck(boolean b) { 650 mDnsCheckDisabled = b; 651 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 652 SharedPreferences.Editor editor = sp.edit(); 653 editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); 654 editor.apply(); 655 } 656 657 /** 658 * Returns true if the DNS check is currently disabled. 659 */ 660 @Override 661 public boolean isDnsCheckDisabled() { 662 return mDnsCheckDisabled; 663 } 664 665 // Inherited documentation suffices. 666 @Override 667 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { 668 checkCorrectThread(h); 669 670 mPreciseCallStateRegistrants.addUnique(h, what, obj); 671 } 672 673 // Inherited documentation suffices. 674 @Override 675 public void unregisterForPreciseCallStateChanged(Handler h) { 676 mPreciseCallStateRegistrants.remove(h); 677 } 678 679 /** 680 * Subclasses of Phone probably want to replace this with a 681 * version scoped to their packages 682 */ 683 protected void notifyPreciseCallStateChangedP() { 684 AsyncResult ar = new AsyncResult(null, this, null); 685 mPreciseCallStateRegistrants.notifyRegistrants(ar); 686 687 mNotifier.notifyPreciseCallState(this); 688 } 689 690 @Override 691 public void registerForHandoverStateChanged(Handler h, int what, Object obj) { 692 checkCorrectThread(h); 693 mHandoverRegistrants.addUnique(h, what, obj); 694 } 695 696 @Override 697 public void unregisterForHandoverStateChanged(Handler h) { 698 mHandoverRegistrants.remove(h); 699 } 700 701 /** 702 * Subclasses of Phone probably want to replace this with a 703 * version scoped to their packages 704 */ 705 public void notifyHandoverStateChanged(Connection cn) { 706 AsyncResult ar = new AsyncResult(null, cn, null); 707 mHandoverRegistrants.notifyRegistrants(ar); 708 } 709 710 public void migrateFrom(PhoneBase from) { 711 migrate(mHandoverRegistrants, from.mHandoverRegistrants); 712 migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants); 713 migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants); 714 migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants); 715 migrate(mDisconnectRegistrants, from.mDisconnectRegistrants); 716 migrate(mServiceStateRegistrants, from.mServiceStateRegistrants); 717 migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants); 718 migrate(mMmiRegistrants, from.mMmiRegistrants); 719 migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants); 720 migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants); 721 } 722 723 public void migrate(RegistrantList to, RegistrantList from) { 724 from.removeCleared(); 725 for (int i = 0, n = from.size(); i < n; i++) { 726 to.add((Registrant) from.get(i)); 727 } 728 } 729 730 // Inherited documentation suffices. 731 @Override 732 public void registerForUnknownConnection(Handler h, int what, Object obj) { 733 checkCorrectThread(h); 734 735 mUnknownConnectionRegistrants.addUnique(h, what, obj); 736 } 737 738 // Inherited documentation suffices. 739 @Override 740 public void unregisterForUnknownConnection(Handler h) { 741 mUnknownConnectionRegistrants.remove(h); 742 } 743 744 // Inherited documentation suffices. 745 @Override 746 public void registerForNewRingingConnection( 747 Handler h, int what, Object obj) { 748 checkCorrectThread(h); 749 750 mNewRingingConnectionRegistrants.addUnique(h, what, obj); 751 } 752 753 // Inherited documentation suffices. 754 @Override 755 public void unregisterForNewRingingConnection(Handler h) { 756 mNewRingingConnectionRegistrants.remove(h); 757 } 758 759 // Inherited documentation suffices. 760 @Override 761 public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ 762 mCi.registerForInCallVoicePrivacyOn(h, what, obj); 763 } 764 765 // Inherited documentation suffices. 766 @Override 767 public void unregisterForInCallVoicePrivacyOn(Handler h){ 768 mCi.unregisterForInCallVoicePrivacyOn(h); 769 } 770 771 // Inherited documentation suffices. 772 @Override 773 public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ 774 mCi.registerForInCallVoicePrivacyOff(h, what, obj); 775 } 776 777 // Inherited documentation suffices. 778 @Override 779 public void unregisterForInCallVoicePrivacyOff(Handler h){ 780 mCi.unregisterForInCallVoicePrivacyOff(h); 781 } 782 783 // Inherited documentation suffices. 784 @Override 785 public void registerForIncomingRing( 786 Handler h, int what, Object obj) { 787 checkCorrectThread(h); 788 789 mIncomingRingRegistrants.addUnique(h, what, obj); 790 } 791 792 // Inherited documentation suffices. 793 @Override 794 public void unregisterForIncomingRing(Handler h) { 795 mIncomingRingRegistrants.remove(h); 796 } 797 798 // Inherited documentation suffices. 799 @Override 800 public void registerForDisconnect(Handler h, int what, Object obj) { 801 checkCorrectThread(h); 802 803 mDisconnectRegistrants.addUnique(h, what, obj); 804 } 805 806 // Inherited documentation suffices. 807 @Override 808 public void unregisterForDisconnect(Handler h) { 809 mDisconnectRegistrants.remove(h); 810 } 811 812 // Inherited documentation suffices. 813 @Override 814 public void registerForSuppServiceFailed(Handler h, int what, Object obj) { 815 checkCorrectThread(h); 816 817 mSuppServiceFailedRegistrants.addUnique(h, what, obj); 818 } 819 820 // Inherited documentation suffices. 821 @Override 822 public void unregisterForSuppServiceFailed(Handler h) { 823 mSuppServiceFailedRegistrants.remove(h); 824 } 825 826 // Inherited documentation suffices. 827 @Override 828 public void registerForMmiInitiate(Handler h, int what, Object obj) { 829 checkCorrectThread(h); 830 831 mMmiRegistrants.addUnique(h, what, obj); 832 } 833 834 // Inherited documentation suffices. 835 @Override 836 public void unregisterForMmiInitiate(Handler h) { 837 mMmiRegistrants.remove(h); 838 } 839 840 // Inherited documentation suffices. 841 @Override 842 public void registerForMmiComplete(Handler h, int what, Object obj) { 843 checkCorrectThread(h); 844 845 mMmiCompleteRegistrants.addUnique(h, what, obj); 846 } 847 848 // Inherited documentation suffices. 849 @Override 850 public void unregisterForMmiComplete(Handler h) { 851 checkCorrectThread(h); 852 853 mMmiCompleteRegistrants.remove(h); 854 } 855 856 public void registerForSimRecordsLoaded(Handler h, int what, Object obj) { 857 logUnexpectedCdmaMethodCall("registerForSimRecordsLoaded"); 858 } 859 860 public void unregisterForSimRecordsLoaded(Handler h) { 861 logUnexpectedCdmaMethodCall("unregisterForSimRecordsLoaded"); 862 } 863 864 @Override 865 public void setNetworkSelectionModeAutomatic(Message response) { 866 // wrap the response message in our own message along with 867 // an empty string (to indicate automatic selection) for the 868 // operator's id. 869 NetworkSelectMessage nsm = new NetworkSelectMessage(); 870 nsm.message = response; 871 nsm.operatorNumeric = ""; 872 nsm.operatorAlphaLong = ""; 873 874 Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm); 875 mCi.setNetworkSelectionModeAutomatic(msg); 876 877 updateSavedNetworkOperator(nsm); 878 } 879 880 @Override 881 public void getNetworkSelectionMode(Message message) { 882 mCi.getNetworkSelectionMode(message); 883 } 884 885 @Override 886 public void selectNetworkManually(OperatorInfo network, Message response) { 887 // wrap the response message in our own message along with 888 // the operator's id. 889 NetworkSelectMessage nsm = new NetworkSelectMessage(); 890 nsm.message = response; 891 nsm.operatorNumeric = network.getOperatorNumeric(); 892 nsm.operatorAlphaLong = network.getOperatorAlphaLong(); 893 894 Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); 895 mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg); 896 897 updateSavedNetworkOperator(nsm); 898 } 899 900 private void updateSavedNetworkOperator(NetworkSelectMessage nsm) { 901 // open the shared preferences editor, and write the value. 902 // nsm.operatorNumeric is "" if we're in automatic.selection. 903 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 904 SharedPreferences.Editor editor = sp.edit(); 905 editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric); 906 editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong); 907 908 // commit and log the result. 909 if (!editor.commit()) { 910 Rlog.e(LOG_TAG, "failed to commit network selection preference"); 911 } 912 } 913 914 /** 915 * Used to track the settings upon completion of the network change. 916 */ 917 private void handleSetSelectNetwork(AsyncResult ar) { 918 // look for our wrapper within the asyncresult, skip the rest if it 919 // is null. 920 if (!(ar.userObj instanceof NetworkSelectMessage)) { 921 Rlog.e(LOG_TAG, "unexpected result from user object."); 922 return; 923 } 924 925 NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj; 926 927 // found the object, now we send off the message we had originally 928 // attached to the request. 929 if (nsm.message != null) { 930 AsyncResult.forMessage(nsm.message, ar.result, ar.exception); 931 nsm.message.sendToTarget(); 932 } 933 } 934 935 /** 936 * Method to retrieve the saved operator id from the Shared Preferences 937 */ 938 private String getSavedNetworkSelection() { 939 // open the shared preferences and search with our key. 940 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 941 return sp.getString(NETWORK_SELECTION_KEY, ""); 942 } 943 944 /** 945 * Method to restore the previously saved operator id, or reset to 946 * automatic selection, all depending upon the value in the shared 947 * preferences. 948 */ 949 public void restoreSavedNetworkSelection(Message response) { 950 // retrieve the operator id 951 String networkSelection = getSavedNetworkSelection(); 952 953 // set to auto if the id is empty, otherwise select the network. 954 if (TextUtils.isEmpty(networkSelection)) { 955 mCi.setNetworkSelectionModeAutomatic(response); 956 } else { 957 mCi.setNetworkSelectionModeManual(networkSelection, response); 958 } 959 } 960 961 // Inherited documentation suffices. 962 @Override 963 public void setUnitTestMode(boolean f) { 964 mUnitTestMode = f; 965 } 966 967 // Inherited documentation suffices. 968 @Override 969 public boolean getUnitTestMode() { 970 return mUnitTestMode; 971 } 972 973 /** 974 * To be invoked when a voice call Connection disconnects. 975 * 976 * Subclasses of Phone probably want to replace this with a 977 * version scoped to their packages 978 */ 979 protected void notifyDisconnectP(Connection cn) { 980 AsyncResult ar = new AsyncResult(null, cn, null); 981 mDisconnectRegistrants.notifyRegistrants(ar); 982 } 983 984 // Inherited documentation suffices. 985 @Override 986 public void registerForServiceStateChanged( 987 Handler h, int what, Object obj) { 988 checkCorrectThread(h); 989 990 mServiceStateRegistrants.add(h, what, obj); 991 } 992 993 // Inherited documentation suffices. 994 @Override 995 public void unregisterForServiceStateChanged(Handler h) { 996 mServiceStateRegistrants.remove(h); 997 } 998 999 // Inherited documentation suffices. 1000 @Override 1001 public void registerForRingbackTone(Handler h, int what, Object obj) { 1002 mCi.registerForRingbackTone(h, what, obj); 1003 } 1004 1005 // Inherited documentation suffices. 1006 @Override 1007 public void unregisterForRingbackTone(Handler h) { 1008 mCi.unregisterForRingbackTone(h); 1009 } 1010 1011 // Inherited documentation suffices. 1012 @Override 1013 public void registerForOnHoldTone(Handler h, int what, Object obj) { 1014 } 1015 1016 // Inherited documentation suffices. 1017 @Override 1018 public void unregisterForOnHoldTone(Handler h) { 1019 } 1020 1021 // Inherited documentation suffices. 1022 @Override 1023 public void registerForResendIncallMute(Handler h, int what, Object obj) { 1024 mCi.registerForResendIncallMute(h, what, obj); 1025 } 1026 1027 // Inherited documentation suffices. 1028 @Override 1029 public void unregisterForResendIncallMute(Handler h) { 1030 mCi.unregisterForResendIncallMute(h); 1031 } 1032 1033 @Override 1034 public void setEchoSuppressionEnabled() { 1035 // no need for regular phone 1036 } 1037 1038 /** 1039 * Subclasses of Phone probably want to replace this with a 1040 * version scoped to their packages 1041 */ 1042 protected void notifyServiceStateChangedP(ServiceState ss) { 1043 AsyncResult ar = new AsyncResult(null, ss, null); 1044 mServiceStateRegistrants.notifyRegistrants(ar); 1045 1046 mNotifier.notifyServiceState(this); 1047 } 1048 1049 // Inherited documentation suffices. 1050 @Override 1051 public SimulatedRadioControl getSimulatedRadioControl() { 1052 return mSimulatedRadioControl; 1053 } 1054 1055 /** 1056 * Verifies the current thread is the same as the thread originally 1057 * used in the initialization of this instance. Throws RuntimeException 1058 * if not. 1059 * 1060 * @exception RuntimeException if the current thread is not 1061 * the thread that originally obtained this PhoneBase instance. 1062 */ 1063 private void checkCorrectThread(Handler h) { 1064 if (h.getLooper() != mLooper) { 1065 throw new RuntimeException( 1066 "com.android.internal.telephony.Phone must be used from within one thread"); 1067 } 1068 } 1069 1070 /** 1071 * Set the properties by matching the carrier string in 1072 * a string-array resource 1073 */ 1074 private void setPropertiesByCarrier() { 1075 String carrier = SystemProperties.get("ro.carrier"); 1076 1077 if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { 1078 return; 1079 } 1080 1081 CharSequence[] carrierLocales = mContext. 1082 getResources().getTextArray(R.array.carrier_properties); 1083 1084 for (int i = 0; i < carrierLocales.length; i+=3) { 1085 String c = carrierLocales[i].toString(); 1086 if (carrier.equals(c)) { 1087 final Locale l = Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-')); 1088 final String country = l.getCountry(); 1089 MccTable.setSystemLocale(mContext, l.getLanguage(), country); 1090 1091 if (!country.isEmpty()) { 1092 try { 1093 Settings.Global.getInt(mContext.getContentResolver(), 1094 Settings.Global.WIFI_COUNTRY_CODE); 1095 } catch (Settings.SettingNotFoundException e) { 1096 // note this is not persisting 1097 WifiManager wM = (WifiManager) 1098 mContext.getSystemService(Context.WIFI_SERVICE); 1099 wM.setCountryCode(country, false); 1100 } 1101 } 1102 return; 1103 } 1104 } 1105 } 1106 1107 /** 1108 * Get state 1109 */ 1110 @Override 1111 public abstract PhoneConstants.State getState(); 1112 1113 /** 1114 * Retrieves the IccFileHandler of the Phone instance 1115 */ 1116 public IccFileHandler getIccFileHandler(){ 1117 UiccCardApplication uiccApplication = mUiccApplication.get(); 1118 IccFileHandler fh; 1119 1120 if (uiccApplication == null) { 1121 Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null"); 1122 fh = null; 1123 } else { 1124 fh = uiccApplication.getIccFileHandler(); 1125 } 1126 1127 Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh); 1128 return fh; 1129 } 1130 1131 /* 1132 * Retrieves the Handler of the Phone instance 1133 */ 1134 public Handler getHandler() { 1135 return this; 1136 } 1137 1138 @Override 1139 public void updatePhoneObject(int voiceRadioTech) { 1140 // Only the PhoneProxy can update the phone object. 1141 PhoneFactory.getDefaultPhone().updatePhoneObject(voiceRadioTech); 1142 } 1143 1144 /** 1145 * Retrieves the ServiceStateTracker of the phone instance. 1146 */ 1147 public ServiceStateTracker getServiceStateTracker() { 1148 return null; 1149 } 1150 1151 /** 1152 * Get call tracker 1153 */ 1154 public CallTracker getCallTracker() { 1155 return null; 1156 } 1157 1158 public AppType getCurrentUiccAppType() { 1159 UiccCardApplication currentApp = mUiccApplication.get(); 1160 if (currentApp != null) { 1161 return currentApp.getType(); 1162 } 1163 return AppType.APPTYPE_UNKNOWN; 1164 } 1165 1166 @Override 1167 public IccCard getIccCard() { 1168 return null; 1169 //throw new Exception("getIccCard Shouldn't be called from PhoneBase"); 1170 } 1171 1172 @Override 1173 public String getIccSerialNumber() { 1174 IccRecords r = mIccRecords.get(); 1175 return (r != null) ? r.getIccId() : null; 1176 } 1177 1178 @Override 1179 public boolean getIccRecordsLoaded() { 1180 IccRecords r = mIccRecords.get(); 1181 return (r != null) ? r.getRecordsLoaded() : false; 1182 } 1183 1184 /** 1185 * @return all available cell information or null if none. 1186 */ 1187 @Override 1188 public List<CellInfo> getAllCellInfo() { 1189 List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo(); 1190 return privatizeCellInfoList(cellInfoList); 1191 } 1192 1193 /** 1194 * Clear CDMA base station lat/long values if location setting is disabled. 1195 * @param cellInfoList the original cell info list from the RIL 1196 * @return the original list with CDMA lat/long cleared if necessary 1197 */ 1198 private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) { 1199 int mode = Settings.Secure.getInt(getContext().getContentResolver(), 1200 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 1201 if (mode == Settings.Secure.LOCATION_MODE_OFF) { 1202 ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size()); 1203 // clear lat/lon values for location privacy 1204 for (CellInfo c : cellInfoList) { 1205 if (c instanceof CellInfoCdma) { 1206 CellInfoCdma cellInfoCdma = (CellInfoCdma) c; 1207 CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity(); 1208 CellIdentityCdma maskedCellIdentity = new CellIdentityCdma( 1209 cellIdentity.getNetworkId(), 1210 cellIdentity.getSystemId(), 1211 cellIdentity.getBasestationId(), 1212 Integer.MAX_VALUE, Integer.MAX_VALUE); 1213 CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma); 1214 privateCellInfoCdma.setCellIdentity(maskedCellIdentity); 1215 privateCellInfoList.add(privateCellInfoCdma); 1216 } else { 1217 privateCellInfoList.add(c); 1218 } 1219 } 1220 cellInfoList = privateCellInfoList; 1221 } 1222 return cellInfoList; 1223 } 1224 1225 /** 1226 * {@inheritDoc} 1227 */ 1228 @Override 1229 public void setCellInfoListRate(int rateInMillis) { 1230 mCi.setCellInfoListRate(rateInMillis, null); 1231 } 1232 1233 @Override 1234 /** @return true if there are messages waiting, false otherwise. */ 1235 public boolean getMessageWaitingIndicator() { 1236 return mVmCount != 0; 1237 } 1238 1239 @Override 1240 public boolean getCallForwardingIndicator() { 1241 IccRecords r = mIccRecords.get(); 1242 return (r != null) ? r.getVoiceCallForwardingFlag() : false; 1243 } 1244 1245 /** 1246 * Query the status of the CDMA roaming preference 1247 */ 1248 @Override 1249 public void queryCdmaRoamingPreference(Message response) { 1250 mCi.queryCdmaRoamingPreference(response); 1251 } 1252 1253 /** 1254 * Get the signal strength 1255 */ 1256 @Override 1257 public SignalStrength getSignalStrength() { 1258 ServiceStateTracker sst = getServiceStateTracker(); 1259 if (sst == null) { 1260 return new SignalStrength(); 1261 } else { 1262 return sst.getSignalStrength(); 1263 } 1264 } 1265 1266 /** 1267 * Set the status of the CDMA roaming preference 1268 */ 1269 @Override 1270 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 1271 mCi.setCdmaRoamingPreference(cdmaRoamingType, response); 1272 } 1273 1274 /** 1275 * Set the status of the CDMA subscription mode 1276 */ 1277 @Override 1278 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 1279 mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 1280 } 1281 1282 /** 1283 * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only 1284 */ 1285 @Override 1286 public void setPreferredNetworkType(int networkType, Message response) { 1287 mCi.setPreferredNetworkType(networkType, response); 1288 } 1289 1290 @Override 1291 public void getPreferredNetworkType(Message response) { 1292 mCi.getPreferredNetworkType(response); 1293 } 1294 1295 @Override 1296 public void getSmscAddress(Message result) { 1297 mCi.getSmscAddress(result); 1298 } 1299 1300 @Override 1301 public void setSmscAddress(String address, Message result) { 1302 mCi.setSmscAddress(address, result); 1303 } 1304 1305 @Override 1306 public void setTTYMode(int ttyMode, Message onComplete) { 1307 mCi.setTTYMode(ttyMode, onComplete); 1308 } 1309 1310 @Override 1311 public void setUiTTYMode(int uiTtyMode, Message onComplete) { 1312 Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call"); 1313 } 1314 1315 @Override 1316 public void queryTTYMode(Message onComplete) { 1317 mCi.queryTTYMode(onComplete); 1318 } 1319 1320 @Override 1321 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 1322 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1323 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 1324 } 1325 1326 @Override 1327 public void getEnhancedVoicePrivacy(Message onComplete) { 1328 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1329 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 1330 } 1331 1332 @Override 1333 public void setBandMode(int bandMode, Message response) { 1334 mCi.setBandMode(bandMode, response); 1335 } 1336 1337 @Override 1338 public void queryAvailableBandMode(Message response) { 1339 mCi.queryAvailableBandMode(response); 1340 } 1341 1342 @Override 1343 public void invokeOemRilRequestRaw(byte[] data, Message response) { 1344 mCi.invokeOemRilRequestRaw(data, response); 1345 } 1346 1347 @Override 1348 public void invokeOemRilRequestStrings(String[] strings, Message response) { 1349 mCi.invokeOemRilRequestStrings(strings, response); 1350 } 1351 1352 @Override 1353 public void nvReadItem(int itemID, Message response) { 1354 mCi.nvReadItem(itemID, response); 1355 } 1356 1357 @Override 1358 public void nvWriteItem(int itemID, String itemValue, Message response) { 1359 mCi.nvWriteItem(itemID, itemValue, response); 1360 } 1361 1362 @Override 1363 public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) { 1364 mCi.nvWriteCdmaPrl(preferredRoamingList, response); 1365 } 1366 1367 @Override 1368 public void nvResetConfig(int resetType, Message response) { 1369 mCi.nvResetConfig(resetType, response); 1370 } 1371 1372 @Override 1373 public void notifyDataActivity() { 1374 mNotifier.notifyDataActivity(this); 1375 } 1376 1377 public void notifyMessageWaitingIndicator() { 1378 // Do not notify voice mail waiting if device doesn't support voice 1379 if (!mIsVoiceCapable) 1380 return; 1381 1382 // This function is added to send the notification to DefaultPhoneNotifier. 1383 mNotifier.notifyMessageWaitingChanged(this); 1384 } 1385 1386 public void notifyDataConnection(String reason, String apnType, 1387 PhoneConstants.DataState state) { 1388 mNotifier.notifyDataConnection(this, reason, apnType, state); 1389 } 1390 1391 public void notifyDataConnection(String reason, String apnType) { 1392 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 1393 } 1394 1395 public void notifyDataConnection(String reason) { 1396 String types[] = getActiveApnTypes(); 1397 for (String apnType : types) { 1398 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 1399 } 1400 } 1401 1402 public void notifyOtaspChanged(int otaspMode) { 1403 mNotifier.notifyOtaspChanged(this, otaspMode); 1404 } 1405 1406 public void notifySignalStrength() { 1407 mNotifier.notifySignalStrength(this); 1408 } 1409 1410 public void notifyCellInfo(List<CellInfo> cellInfo) { 1411 mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo)); 1412 } 1413 1414 public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) { 1415 mNotifier.notifyDataConnectionRealTimeInfo(this, dcRtInfo); 1416 } 1417 1418 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1419 mNotifier.notifyVoLteServiceStateChanged(this, lteState); 1420 } 1421 1422 /** 1423 * @return true if a mobile originating emergency call is active 1424 */ 1425 public boolean isInEmergencyCall() { 1426 return false; 1427 } 1428 1429 /** 1430 * @return true if we are in the emergency call back mode. This is a period where 1431 * the phone should be using as little power as possible and be ready to receive an 1432 * incoming call from the emergency operator. 1433 */ 1434 public boolean isInEcm() { 1435 return false; 1436 } 1437 1438 @Override 1439 public abstract int getPhoneType(); 1440 1441 /** @hide */ 1442 /** @return number of voicemails */ 1443 @Override 1444 public int getVoiceMessageCount(){ 1445 return mVmCount; 1446 } 1447 1448 /** sets the voice mail count of the phone and notifies listeners. */ 1449 public void setVoiceMessageCount(int countWaiting) { 1450 mVmCount = countWaiting; 1451 // notify listeners of voice mail 1452 notifyMessageWaitingIndicator(); 1453 } 1454 1455 /** gets the voice mail count from preferences */ 1456 protected int getStoredVoiceMessageCount() { 1457 int countVoiceMessages = 0; 1458 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 1459 String subscriberId = sp.getString(VM_ID, null); 1460 String currentSubscriberId = getSubscriberId(); 1461 1462 Rlog.d(LOG_TAG, "Voicemail count retrieval for subscriberId = " + subscriberId + 1463 " current subscriberId = " + currentSubscriberId); 1464 1465 if ((subscriberId != null) && (currentSubscriberId != null) 1466 && (currentSubscriberId.equals(subscriberId))) { 1467 // get voice mail count from preferences 1468 countVoiceMessages = sp.getInt(VM_COUNT, 0); 1469 Rlog.d(LOG_TAG, "Voice Mail Count from preference = " + countVoiceMessages); 1470 } 1471 return countVoiceMessages; 1472 } 1473 1474 /** 1475 * Returns the CDMA ERI icon index to display 1476 */ 1477 @Override 1478 public int getCdmaEriIconIndex() { 1479 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 1480 return -1; 1481 } 1482 1483 /** 1484 * Returns the CDMA ERI icon mode, 1485 * 0 - ON 1486 * 1 - FLASHING 1487 */ 1488 @Override 1489 public int getCdmaEriIconMode() { 1490 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 1491 return -1; 1492 } 1493 1494 /** 1495 * Returns the CDMA ERI text, 1496 */ 1497 @Override 1498 public String getCdmaEriText() { 1499 logUnexpectedCdmaMethodCall("getCdmaEriText"); 1500 return "GSM nw, no ERI"; 1501 } 1502 1503 @Override 1504 public String getCdmaMin() { 1505 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1506 logUnexpectedCdmaMethodCall("getCdmaMin"); 1507 return null; 1508 } 1509 1510 @Override 1511 public boolean isMinInfoReady() { 1512 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1513 logUnexpectedCdmaMethodCall("isMinInfoReady"); 1514 return false; 1515 } 1516 1517 @Override 1518 public String getCdmaPrlVersion(){ 1519 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1520 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 1521 return null; 1522 } 1523 1524 @Override 1525 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 1526 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1527 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 1528 } 1529 1530 @Override 1531 public void exitEmergencyCallbackMode() { 1532 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1533 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 1534 } 1535 1536 @Override 1537 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 1538 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1539 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 1540 } 1541 1542 @Override 1543 public void unregisterForCdmaOtaStatusChange(Handler h) { 1544 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1545 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 1546 } 1547 1548 @Override 1549 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 1550 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1551 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 1552 } 1553 1554 @Override 1555 public void unregisterForSubscriptionInfoReady(Handler h) { 1556 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1557 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 1558 } 1559 1560 /** 1561 * Returns true if OTA Service Provisioning needs to be performed. 1562 * If not overridden return false. 1563 */ 1564 @Override 1565 public boolean needsOtaServiceProvisioning() { 1566 return false; 1567 } 1568 1569 /** 1570 * Return true if number is an OTASP number. 1571 * If not overridden return false. 1572 */ 1573 @Override 1574 public boolean isOtaSpNumber(String dialStr) { 1575 return false; 1576 } 1577 1578 @Override 1579 public void registerForCallWaiting(Handler h, int what, Object obj){ 1580 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1581 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 1582 } 1583 1584 @Override 1585 public void unregisterForCallWaiting(Handler h){ 1586 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1587 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 1588 } 1589 1590 @Override 1591 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 1592 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1593 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 1594 } 1595 1596 @Override 1597 public void unregisterForEcmTimerReset(Handler h) { 1598 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1599 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 1600 } 1601 1602 @Override 1603 public void registerForSignalInfo(Handler h, int what, Object obj) { 1604 mCi.registerForSignalInfo(h, what, obj); 1605 } 1606 1607 @Override 1608 public void unregisterForSignalInfo(Handler h) { 1609 mCi.unregisterForSignalInfo(h); 1610 } 1611 1612 @Override 1613 public void registerForDisplayInfo(Handler h, int what, Object obj) { 1614 mCi.registerForDisplayInfo(h, what, obj); 1615 } 1616 1617 @Override 1618 public void unregisterForDisplayInfo(Handler h) { 1619 mCi.unregisterForDisplayInfo(h); 1620 } 1621 1622 @Override 1623 public void registerForNumberInfo(Handler h, int what, Object obj) { 1624 mCi.registerForNumberInfo(h, what, obj); 1625 } 1626 1627 @Override 1628 public void unregisterForNumberInfo(Handler h) { 1629 mCi.unregisterForNumberInfo(h); 1630 } 1631 1632 @Override 1633 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 1634 mCi.registerForRedirectedNumberInfo(h, what, obj); 1635 } 1636 1637 @Override 1638 public void unregisterForRedirectedNumberInfo(Handler h) { 1639 mCi.unregisterForRedirectedNumberInfo(h); 1640 } 1641 1642 @Override 1643 public void registerForLineControlInfo(Handler h, int what, Object obj) { 1644 mCi.registerForLineControlInfo( h, what, obj); 1645 } 1646 1647 @Override 1648 public void unregisterForLineControlInfo(Handler h) { 1649 mCi.unregisterForLineControlInfo(h); 1650 } 1651 1652 @Override 1653 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 1654 mCi.registerFoT53ClirlInfo(h, what, obj); 1655 } 1656 1657 @Override 1658 public void unregisterForT53ClirInfo(Handler h) { 1659 mCi.unregisterForT53ClirInfo(h); 1660 } 1661 1662 @Override 1663 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 1664 mCi.registerForT53AudioControlInfo( h, what, obj); 1665 } 1666 1667 @Override 1668 public void unregisterForT53AudioControlInfo(Handler h) { 1669 mCi.unregisterForT53AudioControlInfo(h); 1670 } 1671 1672 @Override 1673 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 1674 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1675 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 1676 } 1677 1678 @Override 1679 public void unsetOnEcbModeExitResponse(Handler h){ 1680 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1681 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 1682 } 1683 1684 @Override 1685 public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) { 1686 mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj); 1687 } 1688 1689 @Override 1690 public void unregisterForRadioOffOrNotAvailable(Handler h) { 1691 mRadioOffOrNotAvailableRegistrants.remove(h); 1692 } 1693 1694 @Override 1695 public String[] getActiveApnTypes() { 1696 return mDcTracker.getActiveApnTypes(); 1697 } 1698 1699 @Override 1700 public boolean hasMatchedTetherApnSetting() { 1701 return mDcTracker.hasMatchedTetherApnSetting(); 1702 } 1703 1704 @Override 1705 public String getActiveApnHost(String apnType) { 1706 return mDcTracker.getActiveApnString(apnType); 1707 } 1708 1709 @Override 1710 public LinkProperties getLinkProperties(String apnType) { 1711 return mDcTracker.getLinkProperties(apnType); 1712 } 1713 1714 @Override 1715 public NetworkCapabilities getNetworkCapabilities(String apnType) { 1716 return mDcTracker.getNetworkCapabilities(apnType); 1717 } 1718 1719 @Override 1720 public boolean isDataConnectivityPossible() { 1721 return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT); 1722 } 1723 1724 @Override 1725 public boolean isDataConnectivityPossible(String apnType) { 1726 return ((mDcTracker != null) && 1727 (mDcTracker.isDataPossible(apnType))); 1728 } 1729 1730 /** 1731 * Notify registrants of a new ringing Connection. 1732 * Subclasses of Phone probably want to replace this with a 1733 * version scoped to their packages 1734 */ 1735 public void notifyNewRingingConnectionP(Connection cn) { 1736 if (!mIsVoiceCapable) 1737 return; 1738 AsyncResult ar = new AsyncResult(null, cn, null); 1739 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 1740 } 1741 1742 /** 1743 * Notify registrants of a RING event. 1744 */ 1745 private void notifyIncomingRing() { 1746 if (!mIsVoiceCapable) 1747 return; 1748 AsyncResult ar = new AsyncResult(null, this, null); 1749 mIncomingRingRegistrants.notifyRegistrants(ar); 1750 } 1751 1752 /** 1753 * Send the incoming call Ring notification if conditions are right. 1754 */ 1755 private void sendIncomingCallRingNotification(int token) { 1756 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 1757 (token == mCallRingContinueToken)) { 1758 Rlog.d(LOG_TAG, "Sending notifyIncomingRing"); 1759 notifyIncomingRing(); 1760 sendMessageDelayed( 1761 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1762 } else { 1763 Rlog.d(LOG_TAG, "Ignoring ring notification request," 1764 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1765 + " token=" + token 1766 + " mCallRingContinueToken=" + mCallRingContinueToken 1767 + " mIsVoiceCapable=" + mIsVoiceCapable); 1768 } 1769 } 1770 1771 @Override 1772 public boolean isCspPlmnEnabled() { 1773 // This function should be overridden by the class GSMPhone. 1774 // Not implemented in CDMAPhone. 1775 logUnexpectedGsmMethodCall("isCspPlmnEnabled"); 1776 return false; 1777 } 1778 1779 @Override 1780 public IsimRecords getIsimRecords() { 1781 Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 1782 return null; 1783 } 1784 1785 @Override 1786 public String getMsisdn() { 1787 logUnexpectedGsmMethodCall("getMsisdn"); 1788 return null; 1789 } 1790 1791 /** 1792 * Common error logger method for unexpected calls to CDMA-only methods. 1793 */ 1794 private static void logUnexpectedCdmaMethodCall(String name) 1795 { 1796 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1797 "called, CDMAPhone inactive."); 1798 } 1799 1800 @Override 1801 public PhoneConstants.DataState getDataConnectionState() { 1802 return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT); 1803 } 1804 1805 /** 1806 * Common error logger method for unexpected calls to GSM/WCDMA-only methods. 1807 */ 1808 private static void logUnexpectedGsmMethodCall(String name) { 1809 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1810 "called, GSMPhone inactive."); 1811 } 1812 1813 // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone. 1814 public void notifyCallForwardingIndicator() { 1815 // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone. 1816 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); 1817 } 1818 1819 public void notifyDataConnectionFailed(String reason, String apnType) { 1820 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 1821 } 1822 1823 public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, 1824 String failCause) { 1825 mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause); 1826 } 1827 1828 /** 1829 * {@inheritDoc} 1830 */ 1831 @Override 1832 public int getLteOnCdmaMode() { 1833 return mCi.getLteOnCdmaMode(); 1834 } 1835 1836 public void setVoiceMessageWaiting(int line, int countWaiting) { 1837 // This function should be overridden by class GSMPhone and CDMAPhone. 1838 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone."); 1839 } 1840 1841 /** 1842 * Gets the USIM service table from the UICC, if present and available. 1843 * @return an interface to the UsimServiceTable record, or null if not available 1844 */ 1845 @Override 1846 public UsimServiceTable getUsimServiceTable() { 1847 IccRecords r = mIccRecords.get(); 1848 return (r != null) ? r.getUsimServiceTable() : null; 1849 } 1850 1851 /** 1852 * Gets the Uicc card corresponding to this phone. 1853 * @return the UiccCard object corresponding to the phone ID. 1854 */ 1855 @Override 1856 public UiccCard getUiccCard() { 1857 return mUiccController.getUiccCard(mPhoneId); 1858 } 1859 1860 /** 1861 * Get P-CSCF address from PCO after data connection is established or modified. 1862 * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN 1863 */ 1864 @Override 1865 public String[] getPcscfAddress(String apnType) { 1866 return mDcTracker.getPcscfAddress(apnType); 1867 } 1868 1869 /** 1870 * Set IMS registration state 1871 */ 1872 @Override 1873 public void setImsRegistrationState(boolean registered) { 1874 mDcTracker.setImsRegistrationState(registered); 1875 } 1876 1877 /** 1878 * Return an instance of a IMS phone 1879 */ 1880 @Override 1881 public Phone getImsPhone() { 1882 return mImsPhone; 1883 } 1884 1885 @Override 1886 public ImsPhone relinquishOwnershipOfImsPhone() { 1887 synchronized (mImsLock) { 1888 if (mImsPhone == null) 1889 return null; 1890 1891 ImsPhone imsPhone = mImsPhone; 1892 mImsPhone = null; 1893 1894 CallManager.getInstance().unregisterPhone(imsPhone); 1895 imsPhone.unregisterForSilentRedial(this); 1896 1897 return imsPhone; 1898 } 1899 } 1900 1901 @Override 1902 public void acquireOwnershipOfImsPhone(ImsPhone imsPhone) { 1903 synchronized (mImsLock) { 1904 if (imsPhone == null) 1905 return; 1906 1907 if (mImsPhone != null) { 1908 Rlog.e(LOG_TAG, "acquireOwnershipOfImsPhone: non-null mImsPhone." + 1909 " Shouldn't happen - but disposing"); 1910 mImsPhone.dispose(); 1911 // Potential GC issue if someone keeps a reference to ImsPhone. 1912 // However: this change will make sure that such a reference does 1913 // not access functions through NULL pointer. 1914 //mImsPhone.removeReferences(); 1915 } 1916 1917 mImsPhone = imsPhone; 1918 1919 mImsServiceReady = true; 1920 mImsPhone.updateParentPhone(this); 1921 CallManager.getInstance().registerPhone(mImsPhone); 1922 mImsPhone.registerForSilentRedial( 1923 this, EVENT_INITIATE_SILENT_REDIAL, null); 1924 } 1925 } 1926 1927 protected void updateImsPhone() { 1928 synchronized (mImsLock) { 1929 Rlog.d(LOG_TAG, "updateImsPhone" 1930 + " mImsServiceReady=" + mImsServiceReady); 1931 1932 if (mImsServiceReady && (mImsPhone == null)) { 1933 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this); 1934 CallManager.getInstance().registerPhone(mImsPhone); 1935 mImsPhone.registerForSilentRedial( 1936 this, EVENT_INITIATE_SILENT_REDIAL, null); 1937 } else if (!mImsServiceReady && (mImsPhone != null)) { 1938 CallManager.getInstance().unregisterPhone(mImsPhone); 1939 mImsPhone.unregisterForSilentRedial(this); 1940 1941 mImsPhone.dispose(); 1942 // Potential GC issue if someone keeps a reference to ImsPhone. 1943 // However: this change will make sure that such a reference does 1944 // not access functions through NULL pointer. 1945 //mImsPhone.removeReferences(); 1946 mImsPhone = null; 1947 } 1948 } 1949 } 1950 1951 /** 1952 * Dials a number. 1953 * 1954 * @param dialString The number to dial. 1955 * @param uusInfo The UUSInfo. 1956 * @param videoState The video state for the call. 1957 * @return The Connection. 1958 * @throws CallStateException 1959 */ 1960 protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState) 1961 throws CallStateException { 1962 // dialInternal shall be overriden by GSMPhone and CDMAPhone 1963 return null; 1964 } 1965 1966 /** 1967 * Returns the subscription id. 1968 */ 1969 public int getSubId() { 1970 return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId); 1971 } 1972 1973 /** 1974 * Returns the phone id. 1975 */ 1976 public int getPhoneId() { 1977 return mPhoneId; 1978 } 1979 1980 /** 1981 * Return the service state of mImsPhone if it is STATE_IN_SERVICE 1982 * otherwise return the current voice service state 1983 */ 1984 @Override 1985 public int getVoicePhoneServiceState() { 1986 ImsPhone imsPhone = mImsPhone; 1987 if (imsPhone != null 1988 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) { 1989 return ServiceState.STATE_IN_SERVICE; 1990 } 1991 return getServiceState().getState(); 1992 } 1993 1994 @Override 1995 public boolean setOperatorBrandOverride(String brand) { 1996 return false; 1997 } 1998 1999 @Override 2000 public boolean setRoamingOverride(List<String> gsmRoamingList, 2001 List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 2002 List<String> cdmaNonRoamingList) { 2003 String iccId = getIccSerialNumber(); 2004 if (TextUtils.isEmpty(iccId)) { 2005 return false; 2006 } 2007 2008 setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2009 setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2010 setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2011 setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2012 2013 // Refresh. 2014 ServiceStateTracker tracker = getServiceStateTracker(); 2015 if (tracker != null) { 2016 tracker.pollState(); 2017 } 2018 return true; 2019 } 2020 2021 private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) { 2022 SharedPreferences.Editor spEditor = 2023 PreferenceManager.getDefaultSharedPreferences(mContext).edit(); 2024 String key = prefix + iccId; 2025 if (list == null || list.isEmpty()) { 2026 spEditor.remove(key).commit(); 2027 } else { 2028 spEditor.putStringSet(key, new HashSet<String>(list)).commit(); 2029 } 2030 } 2031 2032 public boolean isMccMncMarkedAsRoaming(String mccMnc) { 2033 return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 2034 } 2035 2036 public boolean isMccMncMarkedAsNonRoaming(String mccMnc) { 2037 return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 2038 } 2039 2040 public boolean isSidMarkedAsRoaming(int SID) { 2041 return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX, 2042 Integer.toString(SID)); 2043 } 2044 2045 public boolean isSidMarkedAsNonRoaming(int SID) { 2046 return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, 2047 Integer.toString(SID)); 2048 } 2049 2050 private boolean getRoamingOverrideHelper(String prefix, String key) { 2051 String iccId = getIccSerialNumber(); 2052 if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) { 2053 return false; 2054 } 2055 2056 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 2057 Set<String> value = sp.getStringSet(prefix + iccId, null); 2058 if (value == null) { 2059 return false; 2060 } 2061 return value.contains(key); 2062 } 2063 2064 @Override 2065 public boolean isRadioAvailable() { 2066 return mCi.getRadioState().isAvailable(); 2067 } 2068 2069 @Override 2070 public void shutdownRadio() { 2071 getServiceStateTracker().requestShutdown(); 2072 } 2073 2074 @Override 2075 public void setRadioCapability(RadioCapability rc, Message response) { 2076 mCi.setRadioCapability(rc, response); 2077 } 2078 2079 @Override 2080 public int getRadioAccessFamily() { 2081 return mRadioAccessFamily; 2082 } 2083 2084 @Override 2085 public int getSupportedRadioAccessFamily() { 2086 return mCi.getSupportedRadioAccessFamily(); 2087 } 2088 2089 @Override 2090 public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) { 2091 mCi.registerForRadioCapabilityChanged(h, what, obj); 2092 } 2093 2094 @Override 2095 public void unregisterForRadioCapabilityChanged(Handler h) { 2096 mCi.unregisterForRadioCapabilityChanged(this); 2097 } 2098 2099 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2100 pw.println("PhoneBase: subId=" + getSubId()); 2101 pw.println(" mPhoneId=" + mPhoneId); 2102 pw.println(" mCi=" + mCi); 2103 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 2104 pw.println(" mDcTracker=" + mDcTracker); 2105 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 2106 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 2107 pw.println(" mCallRingDelay=" + mCallRingDelay); 2108 pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone); 2109 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 2110 pw.println(" mIccRecords=" + mIccRecords.get()); 2111 pw.println(" mUiccApplication=" + mUiccApplication.get()); 2112 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 2113 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 2114 pw.flush(); 2115 pw.println(" mLooper=" + mLooper); 2116 pw.println(" mContext=" + mContext); 2117 pw.println(" mNotifier=" + mNotifier); 2118 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 2119 pw.println(" mUnitTestMode=" + mUnitTestMode); 2120 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 2121 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 2122 pw.println(" getState()=" + getState()); 2123 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 2124 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 2125 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 2126 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 2127 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 2128 pw.flush(); 2129 pw.println(" isInEcm()=" + isInEcm()); 2130 pw.println(" getPhoneName()=" + getPhoneName()); 2131 pw.println(" getPhoneType()=" + getPhoneType()); 2132 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 2133 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 2134 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 2135 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 2136 pw.flush(); 2137 pw.println("++++++++++++++++++++++++++++++++"); 2138 2139 try { 2140 mDcTracker.dump(fd, pw, args); 2141 } catch (Exception e) { 2142 e.printStackTrace(); 2143 } 2144 pw.flush(); 2145 pw.println("++++++++++++++++++++++++++++++++"); 2146 2147 try { 2148 getServiceStateTracker().dump(fd, pw, args); 2149 } catch (Exception e) { 2150 e.printStackTrace(); 2151 } 2152 pw.flush(); 2153 pw.println("++++++++++++++++++++++++++++++++"); 2154 2155 try { 2156 getCallTracker().dump(fd, pw, args); 2157 } catch (Exception e) { 2158 e.printStackTrace(); 2159 } 2160 pw.flush(); 2161 pw.println("++++++++++++++++++++++++++++++++"); 2162 2163 try { 2164 ((RIL)mCi).dump(fd, pw, args); 2165 } catch (Exception e) { 2166 e.printStackTrace(); 2167 } 2168 pw.flush(); 2169 pw.println("++++++++++++++++++++++++++++++++"); 2170 } 2171} 2172