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