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