1 /* 2 * Copyright (C) 2015 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.Uri; 27 import android.net.wifi.WifiManager; 28 import android.os.AsyncResult; 29 import android.os.Build; 30 import android.os.Bundle; 31 import android.os.Handler; 32 import android.os.Looper; 33 import android.os.Message; 34 import android.os.Registrant; 35 import android.os.RegistrantList; 36 import android.os.SystemProperties; 37 import android.os.WorkSource; 38 import android.preference.PreferenceManager; 39 import android.provider.Settings; 40 import android.service.carrier.CarrierIdentifier; 41 import android.telecom.VideoProfile; 42 import android.telephony.CellIdentityCdma; 43 import android.telephony.CellInfo; 44 import android.telephony.CellInfoCdma; 45 import android.telephony.CellLocation; 46 import android.telephony.ClientRequestStats; 47 import android.telephony.PhoneStateListener; 48 import android.telephony.RadioAccessFamily; 49 import android.telephony.Rlog; 50 import android.telephony.ServiceState; 51 import android.telephony.SignalStrength; 52 import android.telephony.SubscriptionManager; 53 import android.telephony.VoLteServiceState; 54 import android.text.TextUtils; 55 56 import com.android.ims.ImsCall; 57 import com.android.ims.ImsConfig; 58 import com.android.ims.ImsManager; 59 import com.android.internal.R; 60 import com.android.internal.telephony.dataconnection.DcTracker; 61 import com.android.internal.telephony.imsphone.ImsPhone; 62 import com.android.internal.telephony.imsphone.ImsPhoneCall; 63 import com.android.internal.telephony.test.SimulatedRadioControl; 64 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 65 import com.android.internal.telephony.uicc.IccFileHandler; 66 import com.android.internal.telephony.uicc.IccRecords; 67 import com.android.internal.telephony.uicc.IsimRecords; 68 import com.android.internal.telephony.uicc.UiccCard; 69 import com.android.internal.telephony.uicc.UiccCardApplication; 70 import com.android.internal.telephony.uicc.UiccController; 71 import com.android.internal.telephony.uicc.UsimServiceTable; 72 73 import java.io.FileDescriptor; 74 import java.io.PrintWriter; 75 import java.util.ArrayList; 76 import java.util.HashSet; 77 import java.util.List; 78 import java.util.Locale; 79 import java.util.Set; 80 import java.util.concurrent.atomic.AtomicReference; 81 82 /** 83 * (<em>Not for SDK use</em>) 84 * A base implementation for the com.android.internal.telephony.Phone interface. 85 * 86 * Note that implementations of Phone.java are expected to be used 87 * from a single application thread. This should be the same thread that 88 * originally called PhoneFactory to obtain the interface. 89 * 90 * {@hide} 91 * 92 */ 93 94 public abstract class Phone extends Handler implements PhoneInternalInterface { 95 private static final String LOG_TAG = "Phone"; 96 97 protected final static Object lockForRadioTechnologyChange = new Object(); 98 99 protected final int USSD_MAX_QUEUE = 10; 100 101 private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() { 102 @Override 103 public void onReceive(Context context, Intent intent) { 104 Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction()); 105 if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) { 106 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID, 107 SubscriptionManager.INVALID_PHONE_INDEX); 108 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId); 109 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX || 110 extraPhoneId != getPhoneId()) { 111 return; 112 } 113 } 114 115 synchronized (Phone.lockForRadioTechnologyChange) { 116 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) { 117 mImsServiceReady = true; 118 updateImsPhone(); 119 ImsManager.updateImsServiceConfig(mContext, mPhoneId, false); 120 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) { 121 mImsServiceReady = false; 122 updateImsPhone(); 123 } else if (intent.getAction().equals(ImsConfig.ACTION_IMS_CONFIG_CHANGED)) { 124 int item = intent.getIntExtra(ImsConfig.EXTRA_CHANGED_ITEM, -1); 125 String value = intent.getStringExtra(ImsConfig.EXTRA_NEW_VALUE); 126 ImsManager.onProvisionedValueChanged(context, item, value); 127 } 128 } 129 } 130 }; 131 132 // Key used to read and write the saved network selection numeric value 133 public static final String NETWORK_SELECTION_KEY = "network_selection_key"; 134 // Key used to read and write the saved network selection operator name 135 public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key"; 136 // Key used to read and write the saved network selection operator short name 137 public static final String NETWORK_SELECTION_SHORT_KEY = "network_selection_short_key"; 138 139 140 // Key used to read/write "disable data connection on boot" pref (used for testing) 141 public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key"; 142 143 /* Event Constants */ 144 protected static final int EVENT_RADIO_AVAILABLE = 1; 145 /** Supplementary Service Notification received. */ 146 protected static final int EVENT_SSN = 2; 147 protected static final int EVENT_SIM_RECORDS_LOADED = 3; 148 private static final int EVENT_MMI_DONE = 4; 149 protected static final int EVENT_RADIO_ON = 5; 150 protected static final int EVENT_GET_BASEBAND_VERSION_DONE = 6; 151 protected static final int EVENT_USSD = 7; 152 protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8; 153 protected static final int EVENT_GET_IMEI_DONE = 9; 154 protected static final int EVENT_GET_IMEISV_DONE = 10; 155 private static final int EVENT_GET_SIM_STATUS_DONE = 11; 156 protected static final int EVENT_SET_CALL_FORWARD_DONE = 12; 157 protected static final int EVENT_GET_CALL_FORWARD_DONE = 13; 158 protected static final int EVENT_CALL_RING = 14; 159 private static final int EVENT_CALL_RING_CONTINUE = 15; 160 161 // Used to intercept the carrier selection calls so that 162 // we can save the values. 163 private static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 16; 164 private static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17; 165 protected static final int EVENT_SET_CLIR_COMPLETE = 18; 166 protected static final int EVENT_REGISTERED_TO_NETWORK = 19; 167 protected static final int EVENT_SET_VM_NUMBER_DONE = 20; 168 // Events for CDMA support 169 protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 21; 170 protected static final int EVENT_RUIM_RECORDS_LOADED = 22; 171 protected static final int EVENT_NV_READY = 23; 172 private static final int EVENT_SET_ENHANCED_VP = 24; 173 protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25; 174 protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26; 175 protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27; 176 // other 177 protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28; 178 protected static final int EVENT_ICC_RECORD_EVENTS = 29; 179 private static final int EVENT_ICC_CHANGED = 30; 180 // Single Radio Voice Call Continuity 181 private static final int EVENT_SRVCC_STATE_CHANGED = 31; 182 private static final int EVENT_INITIATE_SILENT_REDIAL = 32; 183 private static final int EVENT_RADIO_NOT_AVAILABLE = 33; 184 private static final int EVENT_UNSOL_OEM_HOOK_RAW = 34; 185 protected static final int EVENT_GET_RADIO_CAPABILITY = 35; 186 protected static final int EVENT_SS = 36; 187 private static final int EVENT_CONFIG_LCE = 37; 188 private static final int EVENT_CHECK_FOR_NETWORK_AUTOMATIC = 38; 189 protected static final int EVENT_VOICE_RADIO_TECH_CHANGED = 39; 190 protected static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE = 40; 191 protected static final int EVENT_RIL_CONNECTED = 41; 192 protected static final int EVENT_UPDATE_PHONE_OBJECT = 42; 193 protected static final int EVENT_CARRIER_CONFIG_CHANGED = 43; 194 // Carrier's CDMA prefer mode setting 195 protected static final int EVENT_SET_ROAMING_PREFERENCE_DONE = 44; 196 197 protected static final int EVENT_LAST = EVENT_SET_ROAMING_PREFERENCE_DONE; 198 199 // For shared prefs. 200 private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_"; 201 private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_"; 202 private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_"; 203 private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_"; 204 205 // Key used to read/write current CLIR setting 206 public static final String CLIR_KEY = "clir_key"; 207 208 // Key used for storing voice mail count 209 private static final String VM_COUNT = "vm_count_key"; 210 // Key used to read/write the ID for storing the voice mail 211 private static final String VM_ID = "vm_id_key"; 212 213 // Key used for storing call forwarding status 214 public static final String CF_STATUS = "cf_status_key"; 215 // Key used to read/write the ID for storing the call forwarding status 216 public static final String CF_ID = "cf_id_key"; 217 218 // Key used to read/write "disable DNS server check" pref (used for testing) 219 private static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key"; 220 221 /** 222 * Small container class used to hold information relevant to 223 * the carrier selection process. operatorNumeric can be "" 224 * if we are looking for automatic selection. operatorAlphaLong is the 225 * corresponding operator name. 226 */ 227 private static class NetworkSelectMessage { 228 public Message message; 229 public String operatorNumeric; 230 public String operatorAlphaLong; 231 public String operatorAlphaShort; 232 } 233 234 /* Instance Variables */ 235 public CommandsInterface mCi; 236 protected int mVmCount = 0; 237 private boolean mDnsCheckDisabled; 238 public DcTracker mDcTracker; 239 /* Used for dispatching signals to configured carrier apps */ 240 private CarrierSignalAgent mCarrierSignalAgent; 241 /* Used for dispatching carrier action from carrier apps */ 242 private CarrierActionAgent mCarrierActionAgent; 243 private boolean mDoesRilSendMultipleCallRing; 244 private int mCallRingContinueToken; 245 private int mCallRingDelay; 246 private boolean mIsVoiceCapable = true; 247 private final AppSmsManager mAppSmsManager; 248 private SimActivationTracker mSimActivationTracker; 249 // Keep track of whether or not the phone is in Emergency Callback Mode for Phone and 250 // subclasses 251 protected boolean mIsPhoneInEcmState = false; 252 253 // Variable to cache the video capability. When RAT changes, we lose this info and are unable 254 // to recover from the state. We cache it and notify listeners when they register. 255 protected boolean mIsVideoCapable = false; 256 protected UiccController mUiccController = null; 257 protected final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>(); 258 public SmsStorageMonitor mSmsStorageMonitor; 259 public SmsUsageMonitor mSmsUsageMonitor; 260 protected AtomicReference<UiccCardApplication> mUiccApplication = 261 new AtomicReference<UiccCardApplication>(); 262 263 private TelephonyTester mTelephonyTester; 264 private String mName; 265 private final String mActionDetached; 266 private final String mActionAttached; 267 268 protected int mPhoneId; 269 270 private boolean mImsServiceReady = false; 271 protected Phone mImsPhone = null; 272 273 private final AtomicReference<RadioCapability> mRadioCapability = 274 new AtomicReference<RadioCapability>(); 275 276 private static final int DEFAULT_REPORT_INTERVAL_MS = 200; 277 private static final boolean LCE_PULL_MODE = true; 278 private int mLceStatus = RILConstants.LCE_NOT_AVAILABLE; 279 protected TelephonyComponentFactory mTelephonyComponentFactory; 280 281 //IMS 282 /** 283 * {@link CallStateException} message text used to indicate that an IMS call has failed because 284 * it needs to be retried using GSM or CDMA (e.g. CS fallback). 285 * TODO: Replace this with a proper exception; {@link CallStateException} doesn't make sense. 286 */ 287 public static final String CS_FALLBACK = "cs_fallback"; 288 public static final String EXTRA_KEY_ALERT_TITLE = "alertTitle"; 289 public static final String EXTRA_KEY_ALERT_MESSAGE = "alertMessage"; 290 public static final String EXTRA_KEY_ALERT_SHOW = "alertShow"; 291 public static final String EXTRA_KEY_NOTIFICATION_MESSAGE = "notificationMessage"; 292 293 private final RegistrantList mPreciseCallStateRegistrants 294 = new RegistrantList(); 295 296 private final RegistrantList mHandoverRegistrants 297 = new RegistrantList(); 298 299 private final RegistrantList mNewRingingConnectionRegistrants 300 = new RegistrantList(); 301 302 private final RegistrantList mIncomingRingRegistrants 303 = new RegistrantList(); 304 305 protected final RegistrantList mDisconnectRegistrants 306 = new RegistrantList(); 307 308 private final RegistrantList mServiceStateRegistrants 309 = new RegistrantList(); 310 311 protected final RegistrantList mMmiCompleteRegistrants 312 = new RegistrantList(); 313 314 protected final RegistrantList mMmiRegistrants 315 = new RegistrantList(); 316 317 protected final RegistrantList mUnknownConnectionRegistrants 318 = new RegistrantList(); 319 320 protected final RegistrantList mSuppServiceFailedRegistrants 321 = new RegistrantList(); 322 323 protected final RegistrantList mRadioOffOrNotAvailableRegistrants 324 = new RegistrantList(); 325 326 protected final RegistrantList mSimRecordsLoadedRegistrants 327 = new RegistrantList(); 328 329 private final RegistrantList mVideoCapabilityChangedRegistrants 330 = new RegistrantList(); 331 332 protected final RegistrantList mEmergencyCallToggledRegistrants 333 = new RegistrantList(); 334 335 protected Registrant mPostDialHandler; 336 337 private Looper mLooper; /* to insure registrants are in correct thread*/ 338 339 protected final Context mContext; 340 341 /** 342 * PhoneNotifier is an abstraction for all system-wide 343 * state change notification. DefaultPhoneNotifier is 344 * used here unless running we're inside a unit test. 345 */ 346 protected PhoneNotifier mNotifier; 347 348 protected SimulatedRadioControl mSimulatedRadioControl; 349 350 private boolean mUnitTestMode; 351 getIccRecords()352 public IccRecords getIccRecords() { 353 return mIccRecords.get(); 354 } 355 356 /** 357 * Returns a string identifier for this phone interface for parties 358 * outside the phone app process. 359 * @return The string name. 360 */ getPhoneName()361 public String getPhoneName() { 362 return mName; 363 } 364 setPhoneName(String name)365 protected void setPhoneName(String name) { 366 mName = name; 367 } 368 369 /** 370 * Retrieves Nai for phones. Returns null if Nai is not set. 371 */ getNai()372 public String getNai(){ 373 return null; 374 } 375 376 /** 377 * Return the ActionDetached string. When this action is received by components 378 * they are to simulate detaching from the network. 379 * 380 * @return com.android.internal.telephony.{mName}.action_detached 381 * {mName} is GSM, CDMA ... 382 */ getActionDetached()383 public String getActionDetached() { 384 return mActionDetached; 385 } 386 387 /** 388 * Return the ActionAttached string. When this action is received by components 389 * they are to simulate attaching to the network. 390 * 391 * @return com.android.internal.telephony.{mName}.action_detached 392 * {mName} is GSM, CDMA ... 393 */ getActionAttached()394 public String getActionAttached() { 395 return mActionAttached; 396 } 397 398 /** 399 * Set a system property, unless we're in unit test mode 400 */ 401 // CAF_MSIM TODO this need to be replated with TelephonyManager API ? setSystemProperty(String property, String value)402 public void setSystemProperty(String property, String value) { 403 if(getUnitTestMode()) { 404 return; 405 } 406 SystemProperties.set(property, value); 407 } 408 409 /** 410 * Set a system property, unless we're in unit test mode 411 */ 412 // CAF_MSIM TODO this need to be replated with TelephonyManager API ? getSystemProperty(String property, String defValue)413 public String getSystemProperty(String property, String defValue) { 414 if(getUnitTestMode()) { 415 return null; 416 } 417 return SystemProperties.get(property, defValue); 418 } 419 420 /** 421 * Constructs a Phone in normal (non-unit test) mode. 422 * 423 * @param notifier An instance of DefaultPhoneNotifier, 424 * @param context Context object from hosting application 425 * unless unit testing. 426 * @param ci is CommandsInterface 427 * @param unitTestMode when true, prevents notifications 428 * of state change events 429 */ Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode)430 protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 431 boolean unitTestMode) { 432 this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX, 433 TelephonyComponentFactory.getInstance()); 434 } 435 436 /** 437 * Constructs a Phone in normal (non-unit test) mode. 438 * 439 * @param notifier An instance of DefaultPhoneNotifier, 440 * @param context Context object from hosting application 441 * unless unit testing. 442 * @param ci is CommandsInterface 443 * @param unitTestMode when true, prevents notifications 444 * of state change events 445 * @param phoneId the phone-id of this phone. 446 */ Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode, int phoneId, TelephonyComponentFactory telephonyComponentFactory)447 protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 448 boolean unitTestMode, int phoneId, 449 TelephonyComponentFactory telephonyComponentFactory) { 450 mPhoneId = phoneId; 451 mName = name; 452 mNotifier = notifier; 453 mContext = context; 454 mLooper = Looper.myLooper(); 455 mCi = ci; 456 mActionDetached = this.getClass().getPackage().getName() + ".action_detached"; 457 mActionAttached = this.getClass().getPackage().getName() + ".action_attached"; 458 mAppSmsManager = telephonyComponentFactory.makeAppSmsManager(context); 459 460 if (Build.IS_DEBUGGABLE) { 461 mTelephonyTester = new TelephonyTester(this); 462 } 463 464 setUnitTestMode(unitTestMode); 465 466 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 467 mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); 468 mCi.setOnCallRing(this, EVENT_CALL_RING, null); 469 470 /* "Voice capable" means that this device supports circuit-switched 471 * (i.e. voice) phone calls over the telephony network, and is allowed 472 * to display the in-call UI while a cellular voice call is active. 473 * This will be false on "data only" devices which can't make voice 474 * calls and don't support any in-call UI. 475 */ 476 mIsVoiceCapable = mContext.getResources().getBoolean( 477 com.android.internal.R.bool.config_voice_capable); 478 479 /** 480 * Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs 481 * to be generated locally. Ideally all ring tones should be loops 482 * and this wouldn't be necessary. But to minimize changes to upper 483 * layers it is requested that it be generated by lower layers. 484 * 485 * By default old phones won't have the property set but do generate 486 * the RIL_UNSOL_CALL_RING so the default if there is no property is 487 * true. 488 */ 489 mDoesRilSendMultipleCallRing = SystemProperties.getBoolean( 490 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true); 491 Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 492 493 mCallRingDelay = SystemProperties.getInt( 494 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000); 495 Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay); 496 497 if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 498 return; 499 } 500 501 // The locale from the "ro.carrier" system property or R.array.carrier_properties. 502 // This will be overwritten by the Locale from the SIM language settings (EF-PL, EF-LI) 503 // if applicable. 504 final Locale carrierLocale = getLocaleFromCarrierProperties(mContext); 505 if (carrierLocale != null && !TextUtils.isEmpty(carrierLocale.getCountry())) { 506 final String country = carrierLocale.getCountry(); 507 try { 508 Settings.Global.getInt(mContext.getContentResolver(), 509 Settings.Global.WIFI_COUNTRY_CODE); 510 } catch (Settings.SettingNotFoundException e) { 511 // note this is not persisting 512 WifiManager wM = (WifiManager) 513 mContext.getSystemService(Context.WIFI_SERVICE); 514 wM.setCountryCode(country, false); 515 } 516 } 517 518 // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers. 519 mTelephonyComponentFactory = telephonyComponentFactory; 520 mSmsStorageMonitor = mTelephonyComponentFactory.makeSmsStorageMonitor(this); 521 mSmsUsageMonitor = mTelephonyComponentFactory.makeSmsUsageMonitor(context); 522 mUiccController = UiccController.getInstance(); 523 mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); 524 mCarrierSignalAgent = mTelephonyComponentFactory.makeCarrierSignalAgent(this); 525 mCarrierActionAgent = mTelephonyComponentFactory.makeCarrierActionAgent(this); 526 mSimActivationTracker = mTelephonyComponentFactory.makeSimActivationTracker(this); 527 if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) { 528 mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null); 529 } 530 mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null); 531 mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE, 532 obtainMessage(EVENT_CONFIG_LCE)); 533 } 534 535 /** 536 * Start listening for IMS service UP/DOWN events. If using the new ImsResolver APIs, we should 537 * always be setting up ImsPhones. 538 */ startMonitoringImsService()539 public void startMonitoringImsService() { 540 if (getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) { 541 return; 542 } 543 544 synchronized(Phone.lockForRadioTechnologyChange) { 545 IntentFilter filter = new IntentFilter(); 546 ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId()); 547 // Don't listen to deprecated intents using the new dynamic binding. 548 if (imsManager != null && !imsManager.isDynamicBinding()) { 549 filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP); 550 filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN); 551 } 552 filter.addAction(ImsConfig.ACTION_IMS_CONFIG_CHANGED); 553 mContext.registerReceiver(mImsIntentReceiver, filter); 554 555 // Monitor IMS service - but first poll to see if already up (could miss 556 // intent). Also, when using new ImsResolver APIs, the service will be available soon, 557 // so start trying to bind. 558 if (imsManager != null) { 559 // If it is dynamic binding, kick off ImsPhone creation now instead of waiting for 560 // the service to be available. 561 if (imsManager.isDynamicBinding() || imsManager.isServiceAvailable()) { 562 mImsServiceReady = true; 563 updateImsPhone(); 564 ImsManager.updateImsServiceConfig(mContext, mPhoneId, false); 565 } 566 } 567 } 568 } 569 570 /** 571 * When overridden the derived class needs to call 572 * super.handleMessage(msg) so this method has a 573 * a chance to process the message. 574 * 575 * @param msg 576 */ 577 @Override handleMessage(Message msg)578 public void handleMessage(Message msg) { 579 AsyncResult ar; 580 581 // messages to be handled whether or not the phone is being destroyed 582 // should only include messages which are being re-directed and do not use 583 // resources of the phone being destroyed 584 switch (msg.what) { 585 // handle the select network completion callbacks. 586 case EVENT_SET_NETWORK_MANUAL_COMPLETE: 587 case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE: 588 handleSetSelectNetwork((AsyncResult) msg.obj); 589 return; 590 } 591 592 switch(msg.what) { 593 case EVENT_CALL_RING: 594 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState()); 595 ar = (AsyncResult)msg.obj; 596 if (ar.exception == null) { 597 PhoneConstants.State state = getState(); 598 if ((!mDoesRilSendMultipleCallRing) 599 && ((state == PhoneConstants.State.RINGING) || 600 (state == PhoneConstants.State.IDLE))) { 601 mCallRingContinueToken += 1; 602 sendIncomingCallRingNotification(mCallRingContinueToken); 603 } else { 604 notifyIncomingRing(); 605 } 606 } 607 break; 608 609 case EVENT_CALL_RING_CONTINUE: 610 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received state=" + getState()); 611 if (getState() == PhoneConstants.State.RINGING) { 612 sendIncomingCallRingNotification(msg.arg1); 613 } 614 break; 615 616 case EVENT_ICC_CHANGED: 617 onUpdateIccAvailability(); 618 break; 619 620 case EVENT_INITIATE_SILENT_REDIAL: 621 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received"); 622 ar = (AsyncResult) msg.obj; 623 if ((ar.exception == null) && (ar.result != null)) { 624 String dialString = (String) ar.result; 625 if (TextUtils.isEmpty(dialString)) return; 626 try { 627 dialInternal(dialString, null, VideoProfile.STATE_AUDIO_ONLY, null); 628 } catch (CallStateException e) { 629 Rlog.e(LOG_TAG, "silent redial failed: " + e); 630 } 631 } 632 break; 633 634 case EVENT_SRVCC_STATE_CHANGED: 635 ar = (AsyncResult)msg.obj; 636 if (ar.exception == null) { 637 handleSrvccStateChanged((int[]) ar.result); 638 } else { 639 Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception); 640 } 641 break; 642 643 case EVENT_UNSOL_OEM_HOOK_RAW: 644 ar = (AsyncResult)msg.obj; 645 if (ar.exception == null) { 646 byte[] data = (byte[])ar.result; 647 mNotifier.notifyOemHookRawEventForSubscriber(getSubId(), data); 648 } else { 649 Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception); 650 } 651 break; 652 653 case EVENT_CONFIG_LCE: 654 ar = (AsyncResult) msg.obj; 655 if (ar.exception != null) { 656 Rlog.d(LOG_TAG, "config LCE service failed: " + ar.exception); 657 } else { 658 final ArrayList<Integer> statusInfo = (ArrayList<Integer>)ar.result; 659 mLceStatus = statusInfo.get(0); 660 } 661 break; 662 663 case EVENT_CHECK_FOR_NETWORK_AUTOMATIC: { 664 onCheckForNetworkSelectionModeAutomatic(msg); 665 break; 666 } 667 default: 668 throw new RuntimeException("unexpected event not handled"); 669 } 670 } 671 getHandoverConnection()672 public ArrayList<Connection> getHandoverConnection() { 673 return null; 674 } 675 notifySrvccState(Call.SrvccState state)676 public void notifySrvccState(Call.SrvccState state) { 677 } 678 registerForSilentRedial(Handler h, int what, Object obj)679 public void registerForSilentRedial(Handler h, int what, Object obj) { 680 } 681 unregisterForSilentRedial(Handler h)682 public void unregisterForSilentRedial(Handler h) { 683 } 684 handleSrvccStateChanged(int[] ret)685 private void handleSrvccStateChanged(int[] ret) { 686 Rlog.d(LOG_TAG, "handleSrvccStateChanged"); 687 688 ArrayList<Connection> conn = null; 689 Phone imsPhone = mImsPhone; 690 Call.SrvccState srvccState = Call.SrvccState.NONE; 691 if (ret != null && ret.length != 0) { 692 int state = ret[0]; 693 switch(state) { 694 case VoLteServiceState.HANDOVER_STARTED: 695 srvccState = Call.SrvccState.STARTED; 696 if (imsPhone != null) { 697 conn = imsPhone.getHandoverConnection(); 698 migrateFrom(imsPhone); 699 } else { 700 Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null"); 701 } 702 break; 703 case VoLteServiceState.HANDOVER_COMPLETED: 704 srvccState = Call.SrvccState.COMPLETED; 705 if (imsPhone != null) { 706 imsPhone.notifySrvccState(srvccState); 707 } else { 708 Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null"); 709 } 710 break; 711 case VoLteServiceState.HANDOVER_FAILED: 712 case VoLteServiceState.HANDOVER_CANCELED: 713 srvccState = Call.SrvccState.FAILED; 714 break; 715 716 default: 717 //ignore invalid state 718 return; 719 } 720 721 getCallTracker().notifySrvccState(srvccState, conn); 722 723 VoLteServiceState lteState = new VoLteServiceState(state); 724 notifyVoLteServiceStateChanged(lteState); 725 } 726 } 727 728 /** 729 * Gets the context for the phone, as set at initialization time. 730 */ getContext()731 public Context getContext() { 732 return mContext; 733 } 734 735 // Will be called when icc changed onUpdateIccAvailability()736 protected abstract void onUpdateIccAvailability(); 737 738 /** 739 * Disables the DNS check (i.e., allows "0.0.0.0"). 740 * Useful for lab testing environment. 741 * @param b true disables the check, false enables. 742 */ disableDnsCheck(boolean b)743 public void disableDnsCheck(boolean b) { 744 mDnsCheckDisabled = b; 745 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 746 SharedPreferences.Editor editor = sp.edit(); 747 editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); 748 editor.apply(); 749 } 750 751 /** 752 * Returns true if the DNS check is currently disabled. 753 */ isDnsCheckDisabled()754 public boolean isDnsCheckDisabled() { 755 return mDnsCheckDisabled; 756 } 757 758 /** 759 * Register for getting notifications for change in the Call State {@link Call.State} 760 * This is called PreciseCallState because the call state is more precise than the 761 * {@link PhoneConstants.State} which can be obtained using the {@link PhoneStateListener} 762 * 763 * Resulting events will have an AsyncResult in <code>Message.obj</code>. 764 * AsyncResult.userData will be set to the obj argument here. 765 * The <em>h</em> parameter is held only by a weak reference. 766 */ registerForPreciseCallStateChanged(Handler h, int what, Object obj)767 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { 768 checkCorrectThread(h); 769 770 mPreciseCallStateRegistrants.addUnique(h, what, obj); 771 } 772 773 /** 774 * Unregisters for voice call state change notifications. 775 * Extraneous calls are tolerated silently. 776 */ unregisterForPreciseCallStateChanged(Handler h)777 public void unregisterForPreciseCallStateChanged(Handler h) { 778 mPreciseCallStateRegistrants.remove(h); 779 } 780 781 /** 782 * Subclasses of Phone probably want to replace this with a 783 * version scoped to their packages 784 */ notifyPreciseCallStateChangedP()785 protected void notifyPreciseCallStateChangedP() { 786 AsyncResult ar = new AsyncResult(null, this, null); 787 mPreciseCallStateRegistrants.notifyRegistrants(ar); 788 789 mNotifier.notifyPreciseCallState(this); 790 } 791 792 /** 793 * Notifies when a Handover happens due to SRVCC or Silent Redial 794 */ registerForHandoverStateChanged(Handler h, int what, Object obj)795 public void registerForHandoverStateChanged(Handler h, int what, Object obj) { 796 checkCorrectThread(h); 797 mHandoverRegistrants.addUnique(h, what, obj); 798 } 799 800 /** 801 * Unregisters for handover state notifications 802 */ unregisterForHandoverStateChanged(Handler h)803 public void unregisterForHandoverStateChanged(Handler h) { 804 mHandoverRegistrants.remove(h); 805 } 806 807 /** 808 * Subclasses of Phone probably want to replace this with a 809 * version scoped to their packages 810 */ notifyHandoverStateChanged(Connection cn)811 public void notifyHandoverStateChanged(Connection cn) { 812 AsyncResult ar = new AsyncResult(null, cn, null); 813 mHandoverRegistrants.notifyRegistrants(ar); 814 } 815 setIsInEmergencyCall()816 protected void setIsInEmergencyCall() { 817 } 818 migrateFrom(Phone from)819 protected void migrateFrom(Phone from) { 820 migrate(mHandoverRegistrants, from.mHandoverRegistrants); 821 migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants); 822 migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants); 823 migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants); 824 migrate(mDisconnectRegistrants, from.mDisconnectRegistrants); 825 migrate(mServiceStateRegistrants, from.mServiceStateRegistrants); 826 migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants); 827 migrate(mMmiRegistrants, from.mMmiRegistrants); 828 migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants); 829 migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants); 830 if (from.isInEmergencyCall()) { 831 setIsInEmergencyCall(); 832 } 833 } 834 migrate(RegistrantList to, RegistrantList from)835 protected void migrate(RegistrantList to, RegistrantList from) { 836 from.removeCleared(); 837 for (int i = 0, n = from.size(); i < n; i++) { 838 Registrant r = (Registrant) from.get(i); 839 Message msg = r.messageForRegistrant(); 840 // Since CallManager has already registered with both CS and IMS phones, 841 // the migrate should happen only for those registrants which are not 842 // registered with CallManager.Hence the below check is needed to add 843 // only those registrants to the registrant list which are not 844 // coming from the CallManager. 845 if (msg != null) { 846 if (msg.obj == CallManager.getInstance().getRegistrantIdentifier()) { 847 continue; 848 } else { 849 to.add((Registrant) from.get(i)); 850 } 851 } else { 852 Rlog.d(LOG_TAG, "msg is null"); 853 } 854 } 855 } 856 857 /** 858 * Notifies when a previously untracked non-ringing/waiting connection has appeared. 859 * This is likely due to some other entity (eg, SIM card application) initiating a call. 860 */ registerForUnknownConnection(Handler h, int what, Object obj)861 public void registerForUnknownConnection(Handler h, int what, Object obj) { 862 checkCorrectThread(h); 863 864 mUnknownConnectionRegistrants.addUnique(h, what, obj); 865 } 866 867 /** 868 * Unregisters for unknown connection notifications. 869 */ unregisterForUnknownConnection(Handler h)870 public void unregisterForUnknownConnection(Handler h) { 871 mUnknownConnectionRegistrants.remove(h); 872 } 873 874 /** 875 * Notifies when a new ringing or waiting connection has appeared.<p> 876 * 877 * Messages received from this: 878 * Message.obj will be an AsyncResult 879 * AsyncResult.userObj = obj 880 * AsyncResult.result = a Connection. <p> 881 * Please check Connection.isRinging() to make sure the Connection 882 * has not dropped since this message was posted. 883 * If Connection.isRinging() is true, then 884 * Connection.getCall() == Phone.getRingingCall() 885 */ registerForNewRingingConnection( Handler h, int what, Object obj)886 public void registerForNewRingingConnection( 887 Handler h, int what, Object obj) { 888 checkCorrectThread(h); 889 890 mNewRingingConnectionRegistrants.addUnique(h, what, obj); 891 } 892 893 /** 894 * Unregisters for new ringing connection notification. 895 * Extraneous calls are tolerated silently 896 */ unregisterForNewRingingConnection(Handler h)897 public void unregisterForNewRingingConnection(Handler h) { 898 mNewRingingConnectionRegistrants.remove(h); 899 } 900 901 /** 902 * Notifies when phone's video capabilities changes <p> 903 * 904 * Messages received from this: 905 * Message.obj will be an AsyncResult 906 * AsyncResult.userObj = obj 907 * AsyncResult.result = true if phone supports video calling <p> 908 */ registerForVideoCapabilityChanged( Handler h, int what, Object obj)909 public void registerForVideoCapabilityChanged( 910 Handler h, int what, Object obj) { 911 checkCorrectThread(h); 912 913 mVideoCapabilityChangedRegistrants.addUnique(h, what, obj); 914 915 // Notify any registrants of the cached video capability as soon as they register. 916 notifyForVideoCapabilityChanged(mIsVideoCapable); 917 } 918 919 /** 920 * Unregisters for video capability changed notification. 921 * Extraneous calls are tolerated silently 922 */ unregisterForVideoCapabilityChanged(Handler h)923 public void unregisterForVideoCapabilityChanged(Handler h) { 924 mVideoCapabilityChangedRegistrants.remove(h); 925 } 926 927 /** 928 * Register for notifications when a sInCall VoicePrivacy is enabled 929 * 930 * @param h Handler that receives the notification message. 931 * @param what User-defined message code. 932 * @param obj User object. 933 */ registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)934 public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ 935 mCi.registerForInCallVoicePrivacyOn(h, what, obj); 936 } 937 938 /** 939 * Unegister for notifications when a sInCall VoicePrivacy is enabled 940 * 941 * @param h Handler to be removed from the registrant list. 942 */ unregisterForInCallVoicePrivacyOn(Handler h)943 public void unregisterForInCallVoicePrivacyOn(Handler h){ 944 mCi.unregisterForInCallVoicePrivacyOn(h); 945 } 946 947 /** 948 * Register for notifications when a sInCall VoicePrivacy is disabled 949 * 950 * @param h Handler that receives the notification message. 951 * @param what User-defined message code. 952 * @param obj User object. 953 */ registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)954 public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ 955 mCi.registerForInCallVoicePrivacyOff(h, what, obj); 956 } 957 958 /** 959 * Unregister for notifications when a sInCall VoicePrivacy is disabled 960 * 961 * @param h Handler to be removed from the registrant list. 962 */ unregisterForInCallVoicePrivacyOff(Handler h)963 public void unregisterForInCallVoicePrivacyOff(Handler h){ 964 mCi.unregisterForInCallVoicePrivacyOff(h); 965 } 966 967 /** 968 * Notifies when an incoming call rings.<p> 969 * 970 * Messages received from this: 971 * Message.obj will be an AsyncResult 972 * AsyncResult.userObj = obj 973 * AsyncResult.result = a Connection. <p> 974 */ registerForIncomingRing( Handler h, int what, Object obj)975 public void registerForIncomingRing( 976 Handler h, int what, Object obj) { 977 checkCorrectThread(h); 978 979 mIncomingRingRegistrants.addUnique(h, what, obj); 980 } 981 982 /** 983 * Unregisters for ring notification. 984 * Extraneous calls are tolerated silently 985 */ unregisterForIncomingRing(Handler h)986 public void unregisterForIncomingRing(Handler h) { 987 mIncomingRingRegistrants.remove(h); 988 } 989 990 /** 991 * Notifies when a voice connection has disconnected, either due to local 992 * or remote hangup or error. 993 * 994 * Messages received from this will have the following members:<p> 995 * <ul><li>Message.obj will be an AsyncResult</li> 996 * <li>AsyncResult.userObj = obj</li> 997 * <li>AsyncResult.result = a Connection object that is 998 * no longer connected.</li></ul> 999 */ registerForDisconnect(Handler h, int what, Object obj)1000 public void registerForDisconnect(Handler h, int what, Object obj) { 1001 checkCorrectThread(h); 1002 1003 mDisconnectRegistrants.addUnique(h, what, obj); 1004 } 1005 1006 /** 1007 * Unregisters for voice disconnection notification. 1008 * Extraneous calls are tolerated silently 1009 */ unregisterForDisconnect(Handler h)1010 public void unregisterForDisconnect(Handler h) { 1011 mDisconnectRegistrants.remove(h); 1012 } 1013 1014 /** 1015 * Register for notifications when a supplementary service attempt fails. 1016 * Message.obj will contain an AsyncResult. 1017 * 1018 * @param h Handler that receives the notification message. 1019 * @param what User-defined message code. 1020 * @param obj User object. 1021 */ registerForSuppServiceFailed(Handler h, int what, Object obj)1022 public void registerForSuppServiceFailed(Handler h, int what, Object obj) { 1023 checkCorrectThread(h); 1024 1025 mSuppServiceFailedRegistrants.addUnique(h, what, obj); 1026 } 1027 1028 /** 1029 * Unregister for notifications when a supplementary service attempt fails. 1030 * Extraneous calls are tolerated silently 1031 * 1032 * @param h Handler to be removed from the registrant list. 1033 */ unregisterForSuppServiceFailed(Handler h)1034 public void unregisterForSuppServiceFailed(Handler h) { 1035 mSuppServiceFailedRegistrants.remove(h); 1036 } 1037 1038 /** 1039 * Register for notifications of initiation of a new MMI code request. 1040 * MMI codes for GSM are discussed in 3GPP TS 22.030.<p> 1041 * 1042 * Example: If Phone.dial is called with "*#31#", then the app will 1043 * be notified here.<p> 1044 * 1045 * The returned <code>Message.obj</code> will contain an AsyncResult. 1046 * 1047 * <code>obj.result</code> will be an "MmiCode" object. 1048 */ registerForMmiInitiate(Handler h, int what, Object obj)1049 public void registerForMmiInitiate(Handler h, int what, Object obj) { 1050 checkCorrectThread(h); 1051 1052 mMmiRegistrants.addUnique(h, what, obj); 1053 } 1054 1055 /** 1056 * Unregisters for new MMI initiate notification. 1057 * Extraneous calls are tolerated silently 1058 */ unregisterForMmiInitiate(Handler h)1059 public void unregisterForMmiInitiate(Handler h) { 1060 mMmiRegistrants.remove(h); 1061 } 1062 1063 /** 1064 * Register for notifications that an MMI request has completed 1065 * its network activity and is in its final state. This may mean a state 1066 * of COMPLETE, FAILED, or CANCELLED. 1067 * 1068 * <code>Message.obj</code> will contain an AsyncResult. 1069 * <code>obj.result</code> will be an "MmiCode" object 1070 */ registerForMmiComplete(Handler h, int what, Object obj)1071 public void registerForMmiComplete(Handler h, int what, Object obj) { 1072 checkCorrectThread(h); 1073 1074 mMmiCompleteRegistrants.addUnique(h, what, obj); 1075 } 1076 1077 /** 1078 * Unregisters for MMI complete notification. 1079 * Extraneous calls are tolerated silently 1080 */ unregisterForMmiComplete(Handler h)1081 public void unregisterForMmiComplete(Handler h) { 1082 checkCorrectThread(h); 1083 1084 mMmiCompleteRegistrants.remove(h); 1085 } 1086 1087 /** 1088 * Registration point for Sim records loaded 1089 * @param h handler to notify 1090 * @param what what code of message when delivered 1091 * @param obj placed in Message.obj 1092 */ registerForSimRecordsLoaded(Handler h, int what, Object obj)1093 public void registerForSimRecordsLoaded(Handler h, int what, Object obj) { 1094 } 1095 1096 /** 1097 * Unregister for notifications for Sim records loaded 1098 * @param h Handler to be removed from the registrant list. 1099 */ unregisterForSimRecordsLoaded(Handler h)1100 public void unregisterForSimRecordsLoaded(Handler h) { 1101 } 1102 1103 /** 1104 * Register for TTY mode change notifications from the network. 1105 * Message.obj will contain an AsyncResult. 1106 * AsyncResult.result will be an Integer containing new mode. 1107 * 1108 * @param h Handler that receives the notification message. 1109 * @param what User-defined message code. 1110 * @param obj User object. 1111 */ registerForTtyModeReceived(Handler h, int what, Object obj)1112 public void registerForTtyModeReceived(Handler h, int what, Object obj) { 1113 } 1114 1115 /** 1116 * Unregisters for TTY mode change notifications. 1117 * Extraneous calls are tolerated silently 1118 * 1119 * @param h Handler to be removed from the registrant list. 1120 */ unregisterForTtyModeReceived(Handler h)1121 public void unregisterForTtyModeReceived(Handler h) { 1122 } 1123 1124 /** 1125 * Switches network selection mode to "automatic", re-scanning and 1126 * re-selecting a network if appropriate. 1127 * 1128 * @param response The message to dispatch when the network selection 1129 * is complete. 1130 * 1131 * @see #selectNetworkManually(OperatorInfo, boolean, android.os.Message) 1132 */ setNetworkSelectionModeAutomatic(Message response)1133 public void setNetworkSelectionModeAutomatic(Message response) { 1134 Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode"); 1135 // we don't want to do this unecesarily - it acutally causes 1136 // the radio to repeate network selection and is costly 1137 // first check if we're already in automatic mode 1138 Message msg = obtainMessage(EVENT_CHECK_FOR_NETWORK_AUTOMATIC); 1139 msg.obj = response; 1140 mCi.getNetworkSelectionMode(msg); 1141 } 1142 onCheckForNetworkSelectionModeAutomatic(Message fromRil)1143 private void onCheckForNetworkSelectionModeAutomatic(Message fromRil) { 1144 AsyncResult ar = (AsyncResult)fromRil.obj; 1145 Message response = (Message)ar.userObj; 1146 boolean doAutomatic = true; 1147 if (ar.exception == null && ar.result != null) { 1148 try { 1149 int[] modes = (int[])ar.result; 1150 if (modes[0] == 0) { 1151 // already confirmed to be in automatic mode - don't resend 1152 doAutomatic = false; 1153 } 1154 } catch (Exception e) { 1155 // send the setting on error 1156 } 1157 } 1158 1159 // wrap the response message in our own message along with 1160 // an empty string (to indicate automatic selection) for the 1161 // operator's id. 1162 NetworkSelectMessage nsm = new NetworkSelectMessage(); 1163 nsm.message = response; 1164 nsm.operatorNumeric = ""; 1165 nsm.operatorAlphaLong = ""; 1166 nsm.operatorAlphaShort = ""; 1167 1168 if (doAutomatic) { 1169 Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm); 1170 mCi.setNetworkSelectionModeAutomatic(msg); 1171 } else { 1172 Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - already auto, ignoring"); 1173 ar.userObj = nsm; 1174 handleSetSelectNetwork(ar); 1175 } 1176 1177 updateSavedNetworkOperator(nsm); 1178 } 1179 1180 /** 1181 * Query the radio for the current network selection mode. 1182 * 1183 * Return values: 1184 * 0 - automatic. 1185 * 1 - manual. 1186 */ getNetworkSelectionMode(Message message)1187 public void getNetworkSelectionMode(Message message) { 1188 mCi.getNetworkSelectionMode(message); 1189 } 1190 getClientRequestStats()1191 public List<ClientRequestStats> getClientRequestStats() { 1192 return mCi.getClientRequestStats(); 1193 } 1194 1195 /** 1196 * Manually selects a network. <code>response</code> is 1197 * dispatched when this is complete. <code>response.obj</code> will be 1198 * an AsyncResult, and <code>response.obj.exception</code> will be non-null 1199 * on failure. 1200 * 1201 * @see #setNetworkSelectionModeAutomatic(Message) 1202 */ selectNetworkManually(OperatorInfo network, boolean persistSelection, Message response)1203 public void selectNetworkManually(OperatorInfo network, boolean persistSelection, 1204 Message response) { 1205 // wrap the response message in our own message along with 1206 // the operator's id. 1207 NetworkSelectMessage nsm = new NetworkSelectMessage(); 1208 nsm.message = response; 1209 nsm.operatorNumeric = network.getOperatorNumeric(); 1210 nsm.operatorAlphaLong = network.getOperatorAlphaLong(); 1211 nsm.operatorAlphaShort = network.getOperatorAlphaShort(); 1212 1213 Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); 1214 mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg); 1215 1216 if (persistSelection) { 1217 updateSavedNetworkOperator(nsm); 1218 } else { 1219 clearSavedNetworkSelection(); 1220 } 1221 } 1222 1223 /** 1224 * Registration point for emergency call/callback mode start. Message.obj is AsyncResult and 1225 * Message.obj.result will be Integer indicating start of call by value 1 or end of call by 1226 * value 0 1227 * @param h handler to notify 1228 * @param what what code of message when delivered 1229 * @param obj placed in Message.obj.userObj 1230 */ registerForEmergencyCallToggle(Handler h, int what, Object obj)1231 public void registerForEmergencyCallToggle(Handler h, int what, Object obj) { 1232 Registrant r = new Registrant(h, what, obj); 1233 mEmergencyCallToggledRegistrants.add(r); 1234 } 1235 unregisterForEmergencyCallToggle(Handler h)1236 public void unregisterForEmergencyCallToggle(Handler h) { 1237 mEmergencyCallToggledRegistrants.remove(h); 1238 } 1239 updateSavedNetworkOperator(NetworkSelectMessage nsm)1240 private void updateSavedNetworkOperator(NetworkSelectMessage nsm) { 1241 int subId = getSubId(); 1242 if (SubscriptionManager.isValidSubscriptionId(subId)) { 1243 // open the shared preferences editor, and write the value. 1244 // nsm.operatorNumeric is "" if we're in automatic.selection. 1245 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1246 SharedPreferences.Editor editor = sp.edit(); 1247 editor.putString(NETWORK_SELECTION_KEY + subId, nsm.operatorNumeric); 1248 editor.putString(NETWORK_SELECTION_NAME_KEY + subId, nsm.operatorAlphaLong); 1249 editor.putString(NETWORK_SELECTION_SHORT_KEY + subId, nsm.operatorAlphaShort); 1250 1251 // commit and log the result. 1252 if (!editor.commit()) { 1253 Rlog.e(LOG_TAG, "failed to commit network selection preference"); 1254 } 1255 } else { 1256 Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " + 1257 subId); 1258 } 1259 } 1260 1261 /** 1262 * Used to track the settings upon completion of the network change. 1263 */ handleSetSelectNetwork(AsyncResult ar)1264 private void handleSetSelectNetwork(AsyncResult ar) { 1265 // look for our wrapper within the asyncresult, skip the rest if it 1266 // is null. 1267 if (!(ar.userObj instanceof NetworkSelectMessage)) { 1268 Rlog.e(LOG_TAG, "unexpected result from user object."); 1269 return; 1270 } 1271 1272 NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj; 1273 1274 // found the object, now we send off the message we had originally 1275 // attached to the request. 1276 if (nsm.message != null) { 1277 AsyncResult.forMessage(nsm.message, ar.result, ar.exception); 1278 nsm.message.sendToTarget(); 1279 } 1280 } 1281 1282 /** 1283 * Method to retrieve the saved operator from the Shared Preferences 1284 */ getSavedNetworkSelection()1285 private OperatorInfo getSavedNetworkSelection() { 1286 // open the shared preferences and search with our key. 1287 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1288 String numeric = sp.getString(NETWORK_SELECTION_KEY + getSubId(), ""); 1289 String name = sp.getString(NETWORK_SELECTION_NAME_KEY + getSubId(), ""); 1290 String shrt = sp.getString(NETWORK_SELECTION_SHORT_KEY + getSubId(), ""); 1291 return new OperatorInfo(name, shrt, numeric); 1292 } 1293 1294 /** 1295 * Clears the saved network selection. 1296 */ clearSavedNetworkSelection()1297 private void clearSavedNetworkSelection() { 1298 // open the shared preferences and search with our key. 1299 PreferenceManager.getDefaultSharedPreferences(getContext()).edit(). 1300 remove(NETWORK_SELECTION_KEY + getSubId()). 1301 remove(NETWORK_SELECTION_NAME_KEY + getSubId()). 1302 remove(NETWORK_SELECTION_SHORT_KEY + getSubId()).commit(); 1303 } 1304 1305 /** 1306 * Method to restore the previously saved operator id, or reset to 1307 * automatic selection, all depending upon the value in the shared 1308 * preferences. 1309 */ restoreSavedNetworkSelection(Message response)1310 private void restoreSavedNetworkSelection(Message response) { 1311 // retrieve the operator 1312 OperatorInfo networkSelection = getSavedNetworkSelection(); 1313 1314 // set to auto if the id is empty, otherwise select the network. 1315 if (networkSelection == null || TextUtils.isEmpty(networkSelection.getOperatorNumeric())) { 1316 setNetworkSelectionModeAutomatic(response); 1317 } else { 1318 selectNetworkManually(networkSelection, true, response); 1319 } 1320 } 1321 1322 /** 1323 * Saves CLIR setting so that we can re-apply it as necessary 1324 * (in case the RIL resets it across reboots). 1325 */ saveClirSetting(int commandInterfaceCLIRMode)1326 public void saveClirSetting(int commandInterfaceCLIRMode) { 1327 // Open the shared preferences editor, and write the value. 1328 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1329 SharedPreferences.Editor editor = sp.edit(); 1330 editor.putInt(CLIR_KEY + getPhoneId(), commandInterfaceCLIRMode); 1331 Rlog.i(LOG_TAG, "saveClirSetting: " + CLIR_KEY + getPhoneId() + "=" + 1332 commandInterfaceCLIRMode); 1333 1334 // Commit and log the result. 1335 if (!editor.commit()) { 1336 Rlog.e(LOG_TAG, "Failed to commit CLIR preference"); 1337 } 1338 } 1339 1340 /** 1341 * For unit tests; don't send notifications to "Phone" 1342 * mailbox registrants if true. 1343 */ setUnitTestMode(boolean f)1344 private void setUnitTestMode(boolean f) { 1345 mUnitTestMode = f; 1346 } 1347 1348 /** 1349 * @return true If unit test mode is enabled 1350 */ getUnitTestMode()1351 public boolean getUnitTestMode() { 1352 return mUnitTestMode; 1353 } 1354 1355 /** 1356 * To be invoked when a voice call Connection disconnects. 1357 * 1358 * Subclasses of Phone probably want to replace this with a 1359 * version scoped to their packages 1360 */ notifyDisconnectP(Connection cn)1361 protected void notifyDisconnectP(Connection cn) { 1362 AsyncResult ar = new AsyncResult(null, cn, null); 1363 mDisconnectRegistrants.notifyRegistrants(ar); 1364 } 1365 1366 /** 1367 * Register for ServiceState changed. 1368 * Message.obj will contain an AsyncResult. 1369 * AsyncResult.result will be a ServiceState instance 1370 */ registerForServiceStateChanged( Handler h, int what, Object obj)1371 public void registerForServiceStateChanged( 1372 Handler h, int what, Object obj) { 1373 checkCorrectThread(h); 1374 1375 mServiceStateRegistrants.add(h, what, obj); 1376 } 1377 1378 /** 1379 * Unregisters for ServiceStateChange notification. 1380 * Extraneous calls are tolerated silently 1381 */ unregisterForServiceStateChanged(Handler h)1382 public void unregisterForServiceStateChanged(Handler h) { 1383 mServiceStateRegistrants.remove(h); 1384 } 1385 1386 /** 1387 * Notifies when out-band ringback tone is needed.<p> 1388 * 1389 * Messages received from this: 1390 * Message.obj will be an AsyncResult 1391 * AsyncResult.userObj = obj 1392 * AsyncResult.result = boolean, true to start play ringback tone 1393 * and false to stop. <p> 1394 */ registerForRingbackTone(Handler h, int what, Object obj)1395 public void registerForRingbackTone(Handler h, int what, Object obj) { 1396 mCi.registerForRingbackTone(h, what, obj); 1397 } 1398 1399 /** 1400 * Unregisters for ringback tone notification. 1401 */ unregisterForRingbackTone(Handler h)1402 public void unregisterForRingbackTone(Handler h) { 1403 mCi.unregisterForRingbackTone(h); 1404 } 1405 1406 /** 1407 * Notifies when out-band on-hold tone is needed.<p> 1408 * 1409 * Messages received from this: 1410 * Message.obj will be an AsyncResult 1411 * AsyncResult.userObj = obj 1412 * AsyncResult.result = boolean, true to start play on-hold tone 1413 * and false to stop. <p> 1414 */ registerForOnHoldTone(Handler h, int what, Object obj)1415 public void registerForOnHoldTone(Handler h, int what, Object obj) { 1416 } 1417 1418 /** 1419 * Unregisters for on-hold tone notification. 1420 */ unregisterForOnHoldTone(Handler h)1421 public void unregisterForOnHoldTone(Handler h) { 1422 } 1423 1424 /** 1425 * Registers the handler to reset the uplink mute state to get 1426 * uplink audio. 1427 */ registerForResendIncallMute(Handler h, int what, Object obj)1428 public void registerForResendIncallMute(Handler h, int what, Object obj) { 1429 mCi.registerForResendIncallMute(h, what, obj); 1430 } 1431 1432 /** 1433 * Unregisters for resend incall mute notifications. 1434 */ unregisterForResendIncallMute(Handler h)1435 public void unregisterForResendIncallMute(Handler h) { 1436 mCi.unregisterForResendIncallMute(h); 1437 } 1438 1439 /** 1440 * Enables or disables echo suppression. 1441 */ setEchoSuppressionEnabled()1442 public void setEchoSuppressionEnabled() { 1443 // no need for regular phone 1444 } 1445 1446 /** 1447 * Subclasses of Phone probably want to replace this with a 1448 * version scoped to their packages 1449 */ notifyServiceStateChangedP(ServiceState ss)1450 protected void notifyServiceStateChangedP(ServiceState ss) { 1451 AsyncResult ar = new AsyncResult(null, ss, null); 1452 mServiceStateRegistrants.notifyRegistrants(ar); 1453 1454 mNotifier.notifyServiceState(this); 1455 } 1456 1457 /** 1458 * If this is a simulated phone interface, returns a SimulatedRadioControl. 1459 * @return SimulatedRadioControl if this is a simulated interface; 1460 * otherwise, null. 1461 */ getSimulatedRadioControl()1462 public SimulatedRadioControl getSimulatedRadioControl() { 1463 return mSimulatedRadioControl; 1464 } 1465 1466 /** 1467 * Verifies the current thread is the same as the thread originally 1468 * used in the initialization of this instance. Throws RuntimeException 1469 * if not. 1470 * 1471 * @exception RuntimeException if the current thread is not 1472 * the thread that originally obtained this Phone instance. 1473 */ checkCorrectThread(Handler h)1474 private void checkCorrectThread(Handler h) { 1475 if (h.getLooper() != mLooper) { 1476 throw new RuntimeException( 1477 "com.android.internal.telephony.Phone must be used from within one thread"); 1478 } 1479 } 1480 1481 /** 1482 * Set the properties by matching the carrier string in 1483 * a string-array resource 1484 */ getLocaleFromCarrierProperties(Context ctx)1485 private static Locale getLocaleFromCarrierProperties(Context ctx) { 1486 String carrier = SystemProperties.get("ro.carrier"); 1487 1488 if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { 1489 return null; 1490 } 1491 1492 CharSequence[] carrierLocales = ctx.getResources().getTextArray(R.array.carrier_properties); 1493 1494 for (int i = 0; i < carrierLocales.length; i+=3) { 1495 String c = carrierLocales[i].toString(); 1496 if (carrier.equals(c)) { 1497 return Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-')); 1498 } 1499 } 1500 1501 return null; 1502 } 1503 1504 /** 1505 * Get current coarse-grained voice call state. 1506 * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object) 1507 * registerForPreciseCallStateChanged()} for change notification. <p> 1508 * If the phone has an active call and call waiting occurs, 1509 * then the phone state is RINGING not OFFHOOK 1510 * <strong>Note:</strong> 1511 * This registration point provides notification of finer-grained 1512 * changes.<p> 1513 */ getState()1514 public abstract PhoneConstants.State getState(); 1515 1516 /** 1517 * Retrieves the IccFileHandler of the Phone instance 1518 */ getIccFileHandler()1519 public IccFileHandler getIccFileHandler(){ 1520 UiccCardApplication uiccApplication = mUiccApplication.get(); 1521 IccFileHandler fh; 1522 1523 if (uiccApplication == null) { 1524 Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null"); 1525 fh = null; 1526 } else { 1527 fh = uiccApplication.getIccFileHandler(); 1528 } 1529 1530 Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh); 1531 return fh; 1532 } 1533 1534 /* 1535 * Retrieves the Handler of the Phone instance 1536 */ getHandler()1537 public Handler getHandler() { 1538 return this; 1539 } 1540 1541 /** 1542 * Update the phone object if the voice radio technology has changed 1543 * 1544 * @param voiceRadioTech The new voice radio technology 1545 */ updatePhoneObject(int voiceRadioTech)1546 public void updatePhoneObject(int voiceRadioTech) { 1547 } 1548 1549 /** 1550 * Retrieves the ServiceStateTracker of the phone instance. 1551 */ getServiceStateTracker()1552 public ServiceStateTracker getServiceStateTracker() { 1553 return null; 1554 } 1555 1556 /** 1557 * Get call tracker 1558 */ getCallTracker()1559 public CallTracker getCallTracker() { 1560 return null; 1561 } 1562 1563 /** 1564 * Update voice activation state 1565 */ setVoiceActivationState(int state)1566 public void setVoiceActivationState(int state) { 1567 mSimActivationTracker.setVoiceActivationState(state); 1568 } 1569 /** 1570 * Update data activation state 1571 */ setDataActivationState(int state)1572 public void setDataActivationState(int state) { 1573 mSimActivationTracker.setDataActivationState(state); 1574 } 1575 1576 /** 1577 * Returns voice activation state 1578 */ getVoiceActivationState()1579 public int getVoiceActivationState() { 1580 return mSimActivationTracker.getVoiceActivationState(); 1581 } 1582 /** 1583 * Returns data activation state 1584 */ getDataActivationState()1585 public int getDataActivationState() { 1586 return mSimActivationTracker.getDataActivationState(); 1587 } 1588 1589 /** 1590 * Update voice mail count related fields and notify listeners 1591 */ updateVoiceMail()1592 public void updateVoiceMail() { 1593 Rlog.e(LOG_TAG, "updateVoiceMail() should be overridden"); 1594 } 1595 getCurrentUiccAppType()1596 public AppType getCurrentUiccAppType() { 1597 UiccCardApplication currentApp = mUiccApplication.get(); 1598 if (currentApp != null) { 1599 return currentApp.getType(); 1600 } 1601 return AppType.APPTYPE_UNKNOWN; 1602 } 1603 1604 /** 1605 * Returns the ICC card interface for this phone, or null 1606 * if not applicable to underlying technology. 1607 */ getIccCard()1608 public IccCard getIccCard() { 1609 return null; 1610 //throw new Exception("getIccCard Shouldn't be called from Phone"); 1611 } 1612 1613 /** 1614 * Retrieves the serial number of the ICC, if applicable. Returns only the decimal digits before 1615 * the first hex digit in the ICC ID. 1616 */ getIccSerialNumber()1617 public String getIccSerialNumber() { 1618 IccRecords r = mIccRecords.get(); 1619 return (r != null) ? r.getIccId() : null; 1620 } 1621 1622 /** 1623 * Retrieves the full serial number of the ICC (including hex digits), if applicable. 1624 */ getFullIccSerialNumber()1625 public String getFullIccSerialNumber() { 1626 IccRecords r = mIccRecords.get(); 1627 return (r != null) ? r.getFullIccId() : null; 1628 } 1629 1630 /** 1631 * Returns SIM record load state. Use 1632 * <code>getSimCard().registerForReady()</code> for change notification. 1633 * 1634 * @return true if records from the SIM have been loaded and are 1635 * available (if applicable). If not applicable to the underlying 1636 * technology, returns true as well. 1637 */ getIccRecordsLoaded()1638 public boolean getIccRecordsLoaded() { 1639 IccRecords r = mIccRecords.get(); 1640 return (r != null) ? r.getRecordsLoaded() : false; 1641 } 1642 1643 /** 1644 * @param workSource calling WorkSource 1645 * @return all available cell information or null if none. 1646 */ getAllCellInfo(WorkSource workSource)1647 public List<CellInfo> getAllCellInfo(WorkSource workSource) { 1648 List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo(workSource); 1649 return privatizeCellInfoList(cellInfoList); 1650 } 1651 getCellLocation()1652 public CellLocation getCellLocation() { 1653 return getCellLocation(null); 1654 } 1655 1656 /** 1657 * Clear CDMA base station lat/long values if location setting is disabled. 1658 * @param cellInfoList the original cell info list from the RIL 1659 * @return the original list with CDMA lat/long cleared if necessary 1660 */ privatizeCellInfoList(List<CellInfo> cellInfoList)1661 private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) { 1662 if (cellInfoList == null) return null; 1663 int mode = Settings.Secure.getInt(getContext().getContentResolver(), 1664 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 1665 if (mode == Settings.Secure.LOCATION_MODE_OFF) { 1666 ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size()); 1667 // clear lat/lon values for location privacy 1668 for (CellInfo c : cellInfoList) { 1669 if (c instanceof CellInfoCdma) { 1670 CellInfoCdma cellInfoCdma = (CellInfoCdma) c; 1671 CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity(); 1672 CellIdentityCdma maskedCellIdentity = new CellIdentityCdma( 1673 cellIdentity.getNetworkId(), 1674 cellIdentity.getSystemId(), 1675 cellIdentity.getBasestationId(), 1676 Integer.MAX_VALUE, Integer.MAX_VALUE); 1677 CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma); 1678 privateCellInfoCdma.setCellIdentity(maskedCellIdentity); 1679 privateCellInfoList.add(privateCellInfoCdma); 1680 } else { 1681 privateCellInfoList.add(c); 1682 } 1683 } 1684 cellInfoList = privateCellInfoList; 1685 } 1686 return cellInfoList; 1687 } 1688 1689 /** 1690 * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged 1691 * PhoneStateListener.onCellInfoChanged} will be invoked. 1692 * 1693 * The default, 0, means invoke onCellInfoChanged when any of the reported 1694 * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue 1695 * A onCellInfoChanged. 1696 * 1697 * @param rateInMillis the rate 1698 * @param workSource calling WorkSource 1699 */ setCellInfoListRate(int rateInMillis, WorkSource workSource)1700 public void setCellInfoListRate(int rateInMillis, WorkSource workSource) { 1701 mCi.setCellInfoListRate(rateInMillis, null, workSource); 1702 } 1703 1704 /** 1705 * Get voice message waiting indicator status. No change notification 1706 * available on this interface. Use PhoneStateNotifier or similar instead. 1707 * 1708 * @return true if there is a voice message waiting 1709 */ getMessageWaitingIndicator()1710 public boolean getMessageWaitingIndicator() { 1711 return mVmCount != 0; 1712 } 1713 getCallForwardingIndicatorFromSharedPref()1714 private int getCallForwardingIndicatorFromSharedPref() { 1715 int status = IccRecords.CALL_FORWARDING_STATUS_DISABLED; 1716 int subId = getSubId(); 1717 if (SubscriptionManager.isValidSubscriptionId(subId)) { 1718 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 1719 status = sp.getInt(CF_STATUS + subId, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN); 1720 Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " + 1721 status); 1722 // Check for old preference if status is UNKNOWN for current subId. This part of the 1723 // code is needed only when upgrading from M to N. 1724 if (status == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) { 1725 String subscriberId = sp.getString(CF_ID, null); 1726 if (subscriberId != null) { 1727 String currentSubscriberId = getSubscriberId(); 1728 1729 if (subscriberId.equals(currentSubscriberId)) { 1730 // get call forwarding status from preferences 1731 status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED); 1732 setCallForwardingIndicatorInSharedPref( 1733 status == IccRecords.CALL_FORWARDING_STATUS_ENABLED ? true : false); 1734 Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: " + status); 1735 } else { 1736 Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: returning " + 1737 "DISABLED as status for matching subscriberId not found"); 1738 } 1739 1740 // get rid of old preferences. 1741 SharedPreferences.Editor editor = sp.edit(); 1742 editor.remove(CF_ID); 1743 editor.remove(CF_STATUS); 1744 editor.apply(); 1745 } 1746 } 1747 } else { 1748 Rlog.e(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId); 1749 } 1750 return status; 1751 } 1752 setCallForwardingIndicatorInSharedPref(boolean enable)1753 private void setCallForwardingIndicatorInSharedPref(boolean enable) { 1754 int status = enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED : 1755 IccRecords.CALL_FORWARDING_STATUS_DISABLED; 1756 int subId = getSubId(); 1757 Rlog.d(LOG_TAG, "setCallForwardingIndicatorInSharedPref: Storing status = " + status + 1758 " in pref " + CF_STATUS + subId); 1759 1760 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 1761 SharedPreferences.Editor editor = sp.edit(); 1762 editor.putInt(CF_STATUS + subId, status); 1763 editor.apply(); 1764 } 1765 setVoiceCallForwardingFlag(int line, boolean enable, String number)1766 public void setVoiceCallForwardingFlag(int line, boolean enable, String number) { 1767 setCallForwardingIndicatorInSharedPref(enable); 1768 IccRecords r = mIccRecords.get(); 1769 if (r != null) { 1770 r.setVoiceCallForwardingFlag(line, enable, number); 1771 } 1772 } 1773 setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, String number)1774 protected void setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, 1775 String number) { 1776 setCallForwardingIndicatorInSharedPref(enable); 1777 r.setVoiceCallForwardingFlag(line, enable, number); 1778 } 1779 1780 /** 1781 * Get voice call forwarding indicator status. No change notification 1782 * available on this interface. Use PhoneStateNotifier or similar instead. 1783 * 1784 * @return true if there is a voice call forwarding 1785 */ getCallForwardingIndicator()1786 public boolean getCallForwardingIndicator() { 1787 if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1788 Rlog.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA"); 1789 return false; 1790 } 1791 IccRecords r = mIccRecords.get(); 1792 int callForwardingIndicator = IccRecords.CALL_FORWARDING_STATUS_UNKNOWN; 1793 if (r != null) { 1794 callForwardingIndicator = r.getVoiceCallForwardingFlag(); 1795 } 1796 if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) { 1797 callForwardingIndicator = getCallForwardingIndicatorFromSharedPref(); 1798 } 1799 return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED); 1800 } 1801 getCarrierSignalAgent()1802 public CarrierSignalAgent getCarrierSignalAgent() { 1803 return mCarrierSignalAgent; 1804 } 1805 getCarrierActionAgent()1806 public CarrierActionAgent getCarrierActionAgent() { 1807 return mCarrierActionAgent; 1808 } 1809 1810 /** 1811 * Query the CDMA roaming preference setting 1812 * 1813 * @param response is callback message to report one of CDMA_RM_* 1814 */ queryCdmaRoamingPreference(Message response)1815 public void queryCdmaRoamingPreference(Message response) { 1816 mCi.queryCdmaRoamingPreference(response); 1817 } 1818 1819 /** 1820 * Get current signal strength. No change notification available on this 1821 * interface. Use <code>PhoneStateNotifier</code> or an equivalent. 1822 * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu). 1823 * The following special values are defined:</p> 1824 * <ul><li>0 means "-113 dBm or less".</li> 1825 * <li>31 means "-51 dBm or greater".</li></ul> 1826 * 1827 * @return Current signal strength as SignalStrength 1828 */ getSignalStrength()1829 public SignalStrength getSignalStrength() { 1830 ServiceStateTracker sst = getServiceStateTracker(); 1831 if (sst == null) { 1832 return new SignalStrength(); 1833 } else { 1834 return sst.getSignalStrength(); 1835 } 1836 } 1837 1838 /** 1839 * @return true, if the device is in a state where both voice and data 1840 * are supported simultaneously. This can change based on location or network condition. 1841 */ isConcurrentVoiceAndDataAllowed()1842 public boolean isConcurrentVoiceAndDataAllowed() { 1843 ServiceStateTracker sst = getServiceStateTracker(); 1844 return sst == null ? false : sst.isConcurrentVoiceAndDataAllowed(); 1845 } 1846 1847 /** 1848 * Requests to set the CDMA roaming preference 1849 * @param cdmaRoamingType one of CDMA_RM_* 1850 * @param response is callback message 1851 */ setCdmaRoamingPreference(int cdmaRoamingType, Message response)1852 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 1853 mCi.setCdmaRoamingPreference(cdmaRoamingType, response); 1854 } 1855 1856 /** 1857 * Requests to set the CDMA subscription mode 1858 * @param cdmaSubscriptionType one of CDMA_SUBSCRIPTION_* 1859 * @param response is callback message 1860 */ setCdmaSubscription(int cdmaSubscriptionType, Message response)1861 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 1862 mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 1863 } 1864 1865 /** 1866 * Requests to set the preferred network type for searching and registering 1867 * (CS/PS domain, RAT, and operation mode) 1868 * @param networkType one of NT_*_TYPE 1869 * @param response is callback message 1870 */ setPreferredNetworkType(int networkType, Message response)1871 public void setPreferredNetworkType(int networkType, Message response) { 1872 // Only set preferred network types to that which the modem supports 1873 int modemRaf = getRadioAccessFamily(); 1874 int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType); 1875 1876 if (modemRaf == RadioAccessFamily.RAF_UNKNOWN 1877 || rafFromType == RadioAccessFamily.RAF_UNKNOWN) { 1878 Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: " 1879 + modemRaf + " " + rafFromType); 1880 if (response != null) { 1881 CommandException ex; 1882 1883 ex = new CommandException(CommandException.Error.GENERIC_FAILURE); 1884 AsyncResult.forMessage(response, null, ex); 1885 response.sendToTarget(); 1886 } 1887 return; 1888 } 1889 1890 int filteredRaf = (rafFromType & modemRaf); 1891 int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf); 1892 1893 Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType 1894 + " modemRaf = " + modemRaf 1895 + " rafFromType = " + rafFromType 1896 + " filteredType = " + filteredType); 1897 1898 mCi.setPreferredNetworkType(filteredType, response); 1899 } 1900 1901 /** 1902 * Query the preferred network type setting 1903 * 1904 * @param response is callback message to report one of NT_*_TYPE 1905 */ getPreferredNetworkType(Message response)1906 public void getPreferredNetworkType(Message response) { 1907 mCi.getPreferredNetworkType(response); 1908 } 1909 1910 /** 1911 * Gets the default SMSC address. 1912 * 1913 * @param result Callback message contains the SMSC address. 1914 */ getSmscAddress(Message result)1915 public void getSmscAddress(Message result) { 1916 mCi.getSmscAddress(result); 1917 } 1918 1919 /** 1920 * Sets the default SMSC address. 1921 * 1922 * @param address new SMSC address 1923 * @param result Callback message is empty on completion 1924 */ setSmscAddress(String address, Message result)1925 public void setSmscAddress(String address, Message result) { 1926 mCi.setSmscAddress(address, result); 1927 } 1928 1929 /** 1930 * setTTYMode 1931 * sets a TTY mode option. 1932 * @param ttyMode is a one of the following: 1933 * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} 1934 * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} 1935 * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} 1936 * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} 1937 * @param onComplete a callback message when the action is completed 1938 */ setTTYMode(int ttyMode, Message onComplete)1939 public void setTTYMode(int ttyMode, Message onComplete) { 1940 mCi.setTTYMode(ttyMode, onComplete); 1941 } 1942 1943 /** 1944 * setUiTTYMode 1945 * sets a TTY mode option. 1946 * @param ttyMode is a one of the following: 1947 * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} 1948 * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} 1949 * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} 1950 * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} 1951 * @param onComplete a callback message when the action is completed 1952 */ setUiTTYMode(int uiTtyMode, Message onComplete)1953 public void setUiTTYMode(int uiTtyMode, Message onComplete) { 1954 Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call"); 1955 } 1956 1957 /** 1958 * queryTTYMode 1959 * query the status of the TTY mode 1960 * 1961 * @param onComplete a callback message when the action is completed. 1962 */ queryTTYMode(Message onComplete)1963 public void queryTTYMode(Message onComplete) { 1964 mCi.queryTTYMode(onComplete); 1965 } 1966 1967 /** 1968 * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is 1969 * disabled, normal VP is enabled. 1970 * 1971 * @param enable whether true or false to enable or disable. 1972 * @param onComplete a callback message when the action is completed. 1973 */ enableEnhancedVoicePrivacy(boolean enable, Message onComplete)1974 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 1975 } 1976 1977 /** 1978 * Get the currently set Voice Privacy (VP) mode. 1979 * 1980 * @param onComplete a callback message when the action is completed. 1981 */ getEnhancedVoicePrivacy(Message onComplete)1982 public void getEnhancedVoicePrivacy(Message onComplete) { 1983 } 1984 1985 /** 1986 * Assign a specified band for RF configuration. 1987 * 1988 * @param bandMode one of BM_*_BAND 1989 * @param response is callback message 1990 */ setBandMode(int bandMode, Message response)1991 public void setBandMode(int bandMode, Message response) { 1992 mCi.setBandMode(bandMode, response); 1993 } 1994 1995 /** 1996 * Query the list of band mode supported by RF. 1997 * 1998 * @param response is callback message 1999 * ((AsyncResult)response.obj).result is an int[] where int[0] is 2000 * the size of the array and the rest of each element representing 2001 * one available BM_*_BAND 2002 */ queryAvailableBandMode(Message response)2003 public void queryAvailableBandMode(Message response) { 2004 mCi.queryAvailableBandMode(response); 2005 } 2006 2007 /** 2008 * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation. 2009 * 2010 * @param data The data for the request. 2011 * @param response <strong>On success</strong>, 2012 * (byte[])(((AsyncResult)response.obj).result) 2013 * <strong>On failure</strong>, 2014 * (((AsyncResult)response.obj).result) == null and 2015 * (((AsyncResult)response.obj).exception) being an instance of 2016 * com.android.internal.telephony.gsm.CommandException 2017 * 2018 * @see #invokeOemRilRequestRaw(byte[], android.os.Message) 2019 * @deprecated OEM needs a vendor-extension hal and their apps should use that instead 2020 */ 2021 @Deprecated invokeOemRilRequestRaw(byte[] data, Message response)2022 public void invokeOemRilRequestRaw(byte[] data, Message response) { 2023 mCi.invokeOemRilRequestRaw(data, response); 2024 } 2025 2026 /** 2027 * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation. 2028 * 2029 * @param strings The strings to make available as the request data. 2030 * @param response <strong>On success</strong>, "response" bytes is 2031 * made available as: 2032 * (String[])(((AsyncResult)response.obj).result). 2033 * <strong>On failure</strong>, 2034 * (((AsyncResult)response.obj).result) == null and 2035 * (((AsyncResult)response.obj).exception) being an instance of 2036 * com.android.internal.telephony.gsm.CommandException 2037 * 2038 * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message) 2039 * @deprecated OEM needs a vendor-extension hal and their apps should use that instead 2040 */ 2041 @Deprecated invokeOemRilRequestStrings(String[] strings, Message response)2042 public void invokeOemRilRequestStrings(String[] strings, Message response) { 2043 mCi.invokeOemRilRequestStrings(strings, response); 2044 } 2045 2046 /** 2047 * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}. 2048 * Used for device configuration by some CDMA operators. 2049 * 2050 * @param itemID the ID of the item to read 2051 * @param response callback message with the String response in the obj field 2052 */ nvReadItem(int itemID, Message response)2053 public void nvReadItem(int itemID, Message response) { 2054 mCi.nvReadItem(itemID, response); 2055 } 2056 2057 /** 2058 * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}. 2059 * Used for device configuration by some CDMA operators. 2060 * 2061 * @param itemID the ID of the item to read 2062 * @param itemValue the value to write, as a String 2063 * @param response Callback message. 2064 */ nvWriteItem(int itemID, String itemValue, Message response)2065 public void nvWriteItem(int itemID, String itemValue, Message response) { 2066 mCi.nvWriteItem(itemID, itemValue, response); 2067 } 2068 2069 /** 2070 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 2071 * Used for device configuration by some CDMA operators. 2072 * 2073 * @param preferredRoamingList byte array containing the new PRL 2074 * @param response Callback message. 2075 */ nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)2076 public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) { 2077 mCi.nvWriteCdmaPrl(preferredRoamingList, response); 2078 } 2079 2080 /** 2081 * Perform the specified type of NV config reset. The radio will be taken offline 2082 * and the device must be rebooted after erasing the NV. Used for device 2083 * configuration by some CDMA operators. 2084 * 2085 * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset 2086 * @param response Callback message. 2087 */ nvResetConfig(int resetType, Message response)2088 public void nvResetConfig(int resetType, Message response) { 2089 mCi.nvResetConfig(resetType, response); 2090 } 2091 notifyDataActivity()2092 public void notifyDataActivity() { 2093 mNotifier.notifyDataActivity(this); 2094 } 2095 notifyMessageWaitingIndicator()2096 private void notifyMessageWaitingIndicator() { 2097 // Do not notify voice mail waiting if device doesn't support voice 2098 if (!mIsVoiceCapable) 2099 return; 2100 2101 // This function is added to send the notification to DefaultPhoneNotifier. 2102 mNotifier.notifyMessageWaitingChanged(this); 2103 } 2104 notifyDataConnection(String reason, String apnType, PhoneConstants.DataState state)2105 public void notifyDataConnection(String reason, String apnType, 2106 PhoneConstants.DataState state) { 2107 mNotifier.notifyDataConnection(this, reason, apnType, state); 2108 } 2109 notifyDataConnection(String reason, String apnType)2110 public void notifyDataConnection(String reason, String apnType) { 2111 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 2112 } 2113 notifyDataConnection(String reason)2114 public void notifyDataConnection(String reason) { 2115 String types[] = getActiveApnTypes(); 2116 for (String apnType : types) { 2117 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 2118 } 2119 } 2120 notifyOtaspChanged(int otaspMode)2121 public void notifyOtaspChanged(int otaspMode) { 2122 mNotifier.notifyOtaspChanged(this, otaspMode); 2123 } 2124 notifyVoiceActivationStateChanged(int state)2125 public void notifyVoiceActivationStateChanged(int state) { 2126 mNotifier.notifyVoiceActivationStateChanged(this, state); 2127 } 2128 notifyDataActivationStateChanged(int state)2129 public void notifyDataActivationStateChanged(int state) { 2130 mNotifier.notifyDataActivationStateChanged(this, state); 2131 } 2132 notifySignalStrength()2133 public void notifySignalStrength() { 2134 mNotifier.notifySignalStrength(this); 2135 } 2136 notifyCellInfo(List<CellInfo> cellInfo)2137 public void notifyCellInfo(List<CellInfo> cellInfo) { 2138 mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo)); 2139 } 2140 notifyVoLteServiceStateChanged(VoLteServiceState lteState)2141 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 2142 mNotifier.notifyVoLteServiceStateChanged(this, lteState); 2143 } 2144 2145 /** 2146 * @return true if a mobile originating emergency call is active 2147 */ isInEmergencyCall()2148 public boolean isInEmergencyCall() { 2149 return false; 2150 } 2151 2152 // This property is used to handle phone process crashes, and is the same for CDMA and IMS 2153 // phones getInEcmMode()2154 protected static boolean getInEcmMode() { 2155 return SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false); 2156 } 2157 2158 /** 2159 * @return {@code true} if we are in emergency call back mode. This is a period where the phone 2160 * should be using as little power as possible and be ready to receive an incoming call from the 2161 * emergency operator. 2162 * 2163 * This method is overridden for GSM phones to return false always 2164 */ isInEcm()2165 public boolean isInEcm() { 2166 return mIsPhoneInEcmState; 2167 } 2168 setIsInEcm(boolean isInEcm)2169 public void setIsInEcm(boolean isInEcm) { 2170 setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, String.valueOf(isInEcm)); 2171 mIsPhoneInEcmState = isInEcm; 2172 } 2173 getVideoState(Call call)2174 private static int getVideoState(Call call) { 2175 int videoState = VideoProfile.STATE_AUDIO_ONLY; 2176 Connection conn = call.getEarliestConnection(); 2177 if (conn != null) { 2178 videoState = conn.getVideoState(); 2179 } 2180 return videoState; 2181 } 2182 2183 /** 2184 * Determines if the specified call currently is or was at some point a video call, or if it is 2185 * a conference call. 2186 * @param call The call. 2187 * @return {@code true} if the call is or was a video call or is a conference call, 2188 * {@code false} otherwise. 2189 */ isVideoCallOrConference(Call call)2190 private boolean isVideoCallOrConference(Call call) { 2191 if (call.isMultiparty()) { 2192 return true; 2193 } 2194 2195 boolean isDowngradedVideoCall = false; 2196 if (call instanceof ImsPhoneCall) { 2197 ImsPhoneCall imsPhoneCall = (ImsPhoneCall) call; 2198 ImsCall imsCall = imsPhoneCall.getImsCall(); 2199 return imsCall != null && (imsCall.isVideoCall() || 2200 imsCall.wasVideoCall()); 2201 } 2202 return isDowngradedVideoCall; 2203 } 2204 2205 /** 2206 * @return {@code true} if an IMS video call or IMS conference is present, false otherwise. 2207 */ isImsVideoCallOrConferencePresent()2208 public boolean isImsVideoCallOrConferencePresent() { 2209 boolean isPresent = false; 2210 if (mImsPhone != null) { 2211 isPresent = isVideoCallOrConference(mImsPhone.getForegroundCall()) || 2212 isVideoCallOrConference(mImsPhone.getBackgroundCall()) || 2213 isVideoCallOrConference(mImsPhone.getRingingCall()); 2214 } 2215 Rlog.d(LOG_TAG, "isImsVideoCallOrConferencePresent: " + isPresent); 2216 return isPresent; 2217 } 2218 2219 /** 2220 * Return a numerical identifier for the phone radio interface. 2221 * @return PHONE_TYPE_XXX as defined above. 2222 */ getPhoneType()2223 public abstract int getPhoneType(); 2224 2225 /** 2226 * Returns unread voicemail count. This count is shown when the voicemail 2227 * notification is expanded.<p> 2228 */ getVoiceMessageCount()2229 public int getVoiceMessageCount(){ 2230 return mVmCount; 2231 } 2232 2233 /** sets the voice mail count of the phone and notifies listeners. */ setVoiceMessageCount(int countWaiting)2234 public void setVoiceMessageCount(int countWaiting) { 2235 mVmCount = countWaiting; 2236 int subId = getSubId(); 2237 if (SubscriptionManager.isValidSubscriptionId(subId)) { 2238 2239 Rlog.d(LOG_TAG, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting + 2240 " for mVmCountKey = " + VM_COUNT + subId + " in preferences."); 2241 2242 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 2243 SharedPreferences.Editor editor = sp.edit(); 2244 editor.putInt(VM_COUNT + subId, countWaiting); 2245 editor.apply(); 2246 } else { 2247 Rlog.e(LOG_TAG, "setVoiceMessageCount in sharedPreference: invalid subId " + subId); 2248 } 2249 // notify listeners of voice mail 2250 notifyMessageWaitingIndicator(); 2251 } 2252 2253 /** gets the voice mail count from preferences */ getStoredVoiceMessageCount()2254 protected int getStoredVoiceMessageCount() { 2255 int countVoiceMessages = 0; 2256 int subId = getSubId(); 2257 if (SubscriptionManager.isValidSubscriptionId(subId)) { 2258 int invalidCount = -2; //-1 is not really invalid. It is used for unknown number of vm 2259 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 2260 int countFromSP = sp.getInt(VM_COUNT + subId, invalidCount); 2261 if (countFromSP != invalidCount) { 2262 countVoiceMessages = countFromSP; 2263 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference for subId " + subId + 2264 "= " + countVoiceMessages); 2265 } else { 2266 // Check for old preference if count not found for current subId. This part of the 2267 // code is needed only when upgrading from M to N. 2268 String subscriberId = sp.getString(VM_ID, null); 2269 if (subscriberId != null) { 2270 String currentSubscriberId = getSubscriberId(); 2271 2272 if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) { 2273 // get voice mail count from preferences 2274 countVoiceMessages = sp.getInt(VM_COUNT, 0); 2275 setVoiceMessageCount(countVoiceMessages); 2276 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference = " + 2277 countVoiceMessages); 2278 } else { 2279 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: returning 0 as count for " + 2280 "matching subscriberId not found"); 2281 2282 } 2283 // get rid of old preferences. 2284 SharedPreferences.Editor editor = sp.edit(); 2285 editor.remove(VM_ID); 2286 editor.remove(VM_COUNT); 2287 editor.apply(); 2288 } 2289 } 2290 } else { 2291 Rlog.e(LOG_TAG, "getStoredVoiceMessageCount: invalid subId " + subId); 2292 } 2293 return countVoiceMessages; 2294 } 2295 2296 /** 2297 * send secret dialer codes to launch arbitrary activities. 2298 * an Intent is started with the android_secret_code://<code> URI. 2299 * 2300 * @param code stripped version of secret code without *#*# prefix and #*#* suffix 2301 */ sendDialerSpecialCode(String code)2302 public void sendDialerSpecialCode(String code) { 2303 if (!TextUtils.isEmpty(code)) { 2304 Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION, 2305 Uri.parse("android_secret_code://" + code)); 2306 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 2307 mContext.sendBroadcast(intent); 2308 } 2309 } 2310 2311 /** 2312 * Returns the CDMA ERI icon index to display 2313 */ getCdmaEriIconIndex()2314 public int getCdmaEriIconIndex() { 2315 return -1; 2316 } 2317 2318 /** 2319 * Returns the CDMA ERI icon mode, 2320 * 0 - ON 2321 * 1 - FLASHING 2322 */ getCdmaEriIconMode()2323 public int getCdmaEriIconMode() { 2324 return -1; 2325 } 2326 2327 /** 2328 * Returns the CDMA ERI text, 2329 */ getCdmaEriText()2330 public String getCdmaEriText() { 2331 return "GSM nw, no ERI"; 2332 } 2333 2334 /** 2335 * Retrieves the MIN for CDMA phones. 2336 */ getCdmaMin()2337 public String getCdmaMin() { 2338 return null; 2339 } 2340 2341 /** 2342 * Check if subscription data has been assigned to mMin 2343 * 2344 * return true if MIN info is ready; false otherwise. 2345 */ isMinInfoReady()2346 public boolean isMinInfoReady() { 2347 return false; 2348 } 2349 2350 /** 2351 * Retrieves PRL Version for CDMA phones 2352 */ getCdmaPrlVersion()2353 public String getCdmaPrlVersion(){ 2354 return null; 2355 } 2356 2357 /** 2358 * send burst DTMF tone, it can send the string as single character or multiple character 2359 * ignore if there is no active call or not valid digits string. 2360 * Valid digit means only includes characters ISO-LATIN characters 0-9, *, # 2361 * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character, 2362 * this api can send single character and multiple character, also, this api has response 2363 * back to caller. 2364 * 2365 * @param dtmfString is string representing the dialing digit(s) in the active call 2366 * @param on the DTMF ON length in milliseconds, or 0 for default 2367 * @param off the DTMF OFF length in milliseconds, or 0 for default 2368 * @param onComplete is the callback message when the action is processed by BP 2369 * 2370 */ sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)2371 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 2372 } 2373 2374 /** 2375 * Sets an event to be fired when the telephony system processes 2376 * a post-dial character on an outgoing call.<p> 2377 * 2378 * Messages of type <code>what</code> will be sent to <code>h</code>. 2379 * The <code>obj</code> field of these Message's will be instances of 2380 * <code>AsyncResult</code>. <code>Message.obj.result</code> will be 2381 * a Connection object.<p> 2382 * 2383 * Message.arg1 will be the post dial character being processed, 2384 * or 0 ('\0') if end of string.<p> 2385 * 2386 * If Connection.getPostDialState() == WAIT, 2387 * the application must call 2388 * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar() 2389 * Connection.proceedAfterWaitChar()} or 2390 * {@link com.android.internal.telephony.Connection#cancelPostDial() 2391 * Connection.cancelPostDial()} 2392 * for the telephony system to continue playing the post-dial 2393 * DTMF sequence.<p> 2394 * 2395 * If Connection.getPostDialState() == WILD, 2396 * the application must call 2397 * {@link com.android.internal.telephony.Connection#proceedAfterWildChar 2398 * Connection.proceedAfterWildChar()} 2399 * or 2400 * {@link com.android.internal.telephony.Connection#cancelPostDial() 2401 * Connection.cancelPostDial()} 2402 * for the telephony system to continue playing the 2403 * post-dial DTMF sequence.<p> 2404 * 2405 * Only one post dial character handler may be set. <p> 2406 * Calling this method with "h" equal to null unsets this handler.<p> 2407 */ setOnPostDialCharacter(Handler h, int what, Object obj)2408 public void setOnPostDialCharacter(Handler h, int what, Object obj) { 2409 mPostDialHandler = new Registrant(h, what, obj); 2410 } 2411 getPostDialHandler()2412 public Registrant getPostDialHandler() { 2413 return mPostDialHandler; 2414 } 2415 2416 /** 2417 * request to exit emergency call back mode 2418 * the caller should use setOnECMModeExitResponse 2419 * to receive the emergency callback mode exit response 2420 */ exitEmergencyCallbackMode()2421 public void exitEmergencyCallbackMode() { 2422 } 2423 2424 /** 2425 * Register for notifications when CDMA OTA Provision status change 2426 * 2427 * @param h Handler that receives the notification message. 2428 * @param what User-defined message code. 2429 * @param obj User object. 2430 */ registerForCdmaOtaStatusChange(Handler h, int what, Object obj)2431 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 2432 } 2433 2434 /** 2435 * Unregister for notifications when CDMA OTA Provision status change 2436 * @param h Handler to be removed from the registrant list. 2437 */ unregisterForCdmaOtaStatusChange(Handler h)2438 public void unregisterForCdmaOtaStatusChange(Handler h) { 2439 } 2440 2441 /** 2442 * Registration point for subscription info ready 2443 * @param h handler to notify 2444 * @param what what code of message when delivered 2445 * @param obj placed in Message.obj 2446 */ registerForSubscriptionInfoReady(Handler h, int what, Object obj)2447 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 2448 } 2449 2450 /** 2451 * Unregister for notifications for subscription info 2452 * @param h Handler to be removed from the registrant list. 2453 */ unregisterForSubscriptionInfoReady(Handler h)2454 public void unregisterForSubscriptionInfoReady(Handler h) { 2455 } 2456 2457 /** 2458 * Returns true if OTA Service Provisioning needs to be performed. 2459 */ needsOtaServiceProvisioning()2460 public boolean needsOtaServiceProvisioning() { 2461 return false; 2462 } 2463 2464 /** 2465 * this decides if the dial number is OTA(Over the air provision) number or not 2466 * @param dialStr is string representing the dialing digit(s) 2467 * @return true means the dialStr is OTA number, and false means the dialStr is not OTA number 2468 */ isOtaSpNumber(String dialStr)2469 public boolean isOtaSpNumber(String dialStr) { 2470 return false; 2471 } 2472 2473 /** 2474 * Register for notifications when CDMA call waiting comes 2475 * 2476 * @param h Handler that receives the notification message. 2477 * @param what User-defined message code. 2478 * @param obj User object. 2479 */ registerForCallWaiting(Handler h, int what, Object obj)2480 public void registerForCallWaiting(Handler h, int what, Object obj){ 2481 } 2482 2483 /** 2484 * Unegister for notifications when CDMA Call waiting comes 2485 * @param h Handler to be removed from the registrant list. 2486 */ unregisterForCallWaiting(Handler h)2487 public void unregisterForCallWaiting(Handler h){ 2488 } 2489 2490 /** 2491 * Registration point for Ecm timer reset 2492 * @param h handler to notify 2493 * @param what user-defined message code 2494 * @param obj placed in Message.obj 2495 */ registerForEcmTimerReset(Handler h, int what, Object obj)2496 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 2497 } 2498 2499 /** 2500 * Unregister for notification for Ecm timer reset 2501 * @param h Handler to be removed from the registrant list. 2502 */ unregisterForEcmTimerReset(Handler h)2503 public void unregisterForEcmTimerReset(Handler h) { 2504 } 2505 2506 /** 2507 * Register for signal information notifications from the network. 2508 * Message.obj will contain an AsyncResult. 2509 * AsyncResult.result will be a SuppServiceNotification instance. 2510 * 2511 * @param h Handler that receives the notification message. 2512 * @param what User-defined message code. 2513 * @param obj User object. 2514 */ registerForSignalInfo(Handler h, int what, Object obj)2515 public void registerForSignalInfo(Handler h, int what, Object obj) { 2516 mCi.registerForSignalInfo(h, what, obj); 2517 } 2518 2519 /** 2520 * Unregisters for signal information notifications. 2521 * Extraneous calls are tolerated silently 2522 * 2523 * @param h Handler to be removed from the registrant list. 2524 */ unregisterForSignalInfo(Handler h)2525 public void unregisterForSignalInfo(Handler h) { 2526 mCi.unregisterForSignalInfo(h); 2527 } 2528 2529 /** 2530 * Register for display information notifications from the network. 2531 * Message.obj will contain an AsyncResult. 2532 * AsyncResult.result will be a SuppServiceNotification instance. 2533 * 2534 * @param h Handler that receives the notification message. 2535 * @param what User-defined message code. 2536 * @param obj User object. 2537 */ registerForDisplayInfo(Handler h, int what, Object obj)2538 public void registerForDisplayInfo(Handler h, int what, Object obj) { 2539 mCi.registerForDisplayInfo(h, what, obj); 2540 } 2541 2542 /** 2543 * Unregisters for display information notifications. 2544 * Extraneous calls are tolerated silently 2545 * 2546 * @param h Handler to be removed from the registrant list. 2547 */ unregisterForDisplayInfo(Handler h)2548 public void unregisterForDisplayInfo(Handler h) { 2549 mCi.unregisterForDisplayInfo(h); 2550 } 2551 2552 /** 2553 * Register for CDMA number information record notification from the network. 2554 * Message.obj will contain an AsyncResult. 2555 * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec 2556 * instance. 2557 * 2558 * @param h Handler that receives the notification message. 2559 * @param what User-defined message code. 2560 * @param obj User object. 2561 */ registerForNumberInfo(Handler h, int what, Object obj)2562 public void registerForNumberInfo(Handler h, int what, Object obj) { 2563 mCi.registerForNumberInfo(h, what, obj); 2564 } 2565 2566 /** 2567 * Unregisters for number information record notifications. 2568 * Extraneous calls are tolerated silently 2569 * 2570 * @param h Handler to be removed from the registrant list. 2571 */ unregisterForNumberInfo(Handler h)2572 public void unregisterForNumberInfo(Handler h) { 2573 mCi.unregisterForNumberInfo(h); 2574 } 2575 2576 /** 2577 * Register for CDMA redirected number information record notification 2578 * from the network. 2579 * Message.obj will contain an AsyncResult. 2580 * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec 2581 * instance. 2582 * 2583 * @param h Handler that receives the notification message. 2584 * @param what User-defined message code. 2585 * @param obj User object. 2586 */ registerForRedirectedNumberInfo(Handler h, int what, Object obj)2587 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 2588 mCi.registerForRedirectedNumberInfo(h, what, obj); 2589 } 2590 2591 /** 2592 * Unregisters for redirected number information record notification. 2593 * Extraneous calls are tolerated silently 2594 * 2595 * @param h Handler to be removed from the registrant list. 2596 */ unregisterForRedirectedNumberInfo(Handler h)2597 public void unregisterForRedirectedNumberInfo(Handler h) { 2598 mCi.unregisterForRedirectedNumberInfo(h); 2599 } 2600 2601 /** 2602 * Register for CDMA line control information record notification 2603 * from the network. 2604 * Message.obj will contain an AsyncResult. 2605 * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec 2606 * instance. 2607 * 2608 * @param h Handler that receives the notification message. 2609 * @param what User-defined message code. 2610 * @param obj User object. 2611 */ registerForLineControlInfo(Handler h, int what, Object obj)2612 public void registerForLineControlInfo(Handler h, int what, Object obj) { 2613 mCi.registerForLineControlInfo(h, what, obj); 2614 } 2615 2616 /** 2617 * Unregisters for line control information notifications. 2618 * Extraneous calls are tolerated silently 2619 * 2620 * @param h Handler to be removed from the registrant list. 2621 */ unregisterForLineControlInfo(Handler h)2622 public void unregisterForLineControlInfo(Handler h) { 2623 mCi.unregisterForLineControlInfo(h); 2624 } 2625 2626 /** 2627 * Register for CDMA T53 CLIR information record notifications 2628 * from the network. 2629 * Message.obj will contain an AsyncResult. 2630 * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec 2631 * instance. 2632 * 2633 * @param h Handler that receives the notification message. 2634 * @param what User-defined message code. 2635 * @param obj User object. 2636 */ registerFoT53ClirlInfo(Handler h, int what, Object obj)2637 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 2638 mCi.registerFoT53ClirlInfo(h, what, obj); 2639 } 2640 2641 /** 2642 * Unregisters for T53 CLIR information record notification 2643 * Extraneous calls are tolerated silently 2644 * 2645 * @param h Handler to be removed from the registrant list. 2646 */ unregisterForT53ClirInfo(Handler h)2647 public void unregisterForT53ClirInfo(Handler h) { 2648 mCi.unregisterForT53ClirInfo(h); 2649 } 2650 2651 /** 2652 * Register for CDMA T53 audio control information record notifications 2653 * from the network. 2654 * Message.obj will contain an AsyncResult. 2655 * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec 2656 * instance. 2657 * 2658 * @param h Handler that receives the notification message. 2659 * @param what User-defined message code. 2660 * @param obj User object. 2661 */ registerForT53AudioControlInfo(Handler h, int what, Object obj)2662 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 2663 mCi.registerForT53AudioControlInfo(h, what, obj); 2664 } 2665 2666 /** 2667 * Unregisters for T53 audio control information record notifications. 2668 * Extraneous calls are tolerated silently 2669 * 2670 * @param h Handler to be removed from the registrant list. 2671 */ unregisterForT53AudioControlInfo(Handler h)2672 public void unregisterForT53AudioControlInfo(Handler h) { 2673 mCi.unregisterForT53AudioControlInfo(h); 2674 } 2675 2676 /** 2677 * registers for exit emergency call back mode request response 2678 * 2679 * @param h Handler that receives the notification message. 2680 * @param what User-defined message code. 2681 * @param obj User object. 2682 */ setOnEcbModeExitResponse(Handler h, int what, Object obj)2683 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 2684 } 2685 2686 /** 2687 * Unregisters for exit emergency call back mode request response 2688 * 2689 * @param h Handler to be removed from the registrant list. 2690 */ unsetOnEcbModeExitResponse(Handler h)2691 public void unsetOnEcbModeExitResponse(Handler h){ 2692 } 2693 2694 /** 2695 * Register for radio off or not available 2696 * 2697 * @param h Handler that receives the notification message. 2698 * @param what User-defined message code. 2699 * @param obj User object. 2700 */ registerForRadioOffOrNotAvailable(Handler h, int what, Object obj)2701 public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) { 2702 mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj); 2703 } 2704 2705 /** 2706 * Unregisters for radio off or not available 2707 * 2708 * @param h Handler to be removed from the registrant list. 2709 */ unregisterForRadioOffOrNotAvailable(Handler h)2710 public void unregisterForRadioOffOrNotAvailable(Handler h) { 2711 mRadioOffOrNotAvailableRegistrants.remove(h); 2712 } 2713 2714 /** 2715 * Returns an array of string identifiers for the APN types serviced by the 2716 * currently active. 2717 * @return The string array will always return at least one entry, Phone.APN_TYPE_DEFAULT. 2718 * TODO: Revisit if we always should return at least one entry. 2719 */ getActiveApnTypes()2720 public String[] getActiveApnTypes() { 2721 if (mDcTracker == null) { 2722 return null; 2723 } 2724 2725 return mDcTracker.getActiveApnTypes(); 2726 } 2727 2728 /** 2729 * Check if TETHER_DUN_APN setting or config_tether_apndata includes APN that matches 2730 * current operator. 2731 * @return true if there is a matching DUN APN. 2732 */ hasMatchedTetherApnSetting()2733 public boolean hasMatchedTetherApnSetting() { 2734 return mDcTracker.hasMatchedTetherApnSetting(); 2735 } 2736 2737 /** 2738 * Returns string for the active APN host. 2739 * @return type as a string or null if none. 2740 */ getActiveApnHost(String apnType)2741 public String getActiveApnHost(String apnType) { 2742 return mDcTracker.getActiveApnString(apnType); 2743 } 2744 2745 /** 2746 * Return the LinkProperties for the named apn or null if not available 2747 */ getLinkProperties(String apnType)2748 public LinkProperties getLinkProperties(String apnType) { 2749 return mDcTracker.getLinkProperties(apnType); 2750 } 2751 2752 /** 2753 * Return the NetworkCapabilities 2754 */ getNetworkCapabilities(String apnType)2755 public NetworkCapabilities getNetworkCapabilities(String apnType) { 2756 return mDcTracker.getNetworkCapabilities(apnType); 2757 } 2758 2759 /** 2760 * Report on whether data connectivity is allowed. 2761 */ isDataConnectivityPossible()2762 public boolean isDataConnectivityPossible() { 2763 return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT); 2764 } 2765 2766 /** 2767 * Report on whether data connectivity is allowed for an APN. 2768 */ isDataConnectivityPossible(String apnType)2769 public boolean isDataConnectivityPossible(String apnType) { 2770 return ((mDcTracker != null) && 2771 (mDcTracker.isDataPossible(apnType))); 2772 } 2773 2774 2775 /** 2776 * Action set from carrier signalling broadcast receivers to enable/disable metered apns. 2777 */ carrierActionSetMeteredApnsEnabled(boolean enabled)2778 public void carrierActionSetMeteredApnsEnabled(boolean enabled) { 2779 mCarrierActionAgent.carrierActionSetMeteredApnsEnabled(enabled); 2780 } 2781 2782 /** 2783 * Action set from carrier signalling broadcast receivers to enable/disable radio 2784 */ carrierActionSetRadioEnabled(boolean enabled)2785 public void carrierActionSetRadioEnabled(boolean enabled) { 2786 mCarrierActionAgent.carrierActionSetRadioEnabled(enabled); 2787 } 2788 2789 /** 2790 * Notify registrants of a new ringing Connection. 2791 * Subclasses of Phone probably want to replace this with a 2792 * version scoped to their packages 2793 */ notifyNewRingingConnectionP(Connection cn)2794 public void notifyNewRingingConnectionP(Connection cn) { 2795 if (!mIsVoiceCapable) 2796 return; 2797 AsyncResult ar = new AsyncResult(null, cn, null); 2798 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 2799 } 2800 2801 /** 2802 * Notify registrants of a new unknown connection. 2803 */ notifyUnknownConnectionP(Connection cn)2804 public void notifyUnknownConnectionP(Connection cn) { 2805 mUnknownConnectionRegistrants.notifyResult(cn); 2806 } 2807 2808 /** 2809 * Notify registrants if phone is video capable. 2810 */ notifyForVideoCapabilityChanged(boolean isVideoCallCapable)2811 public void notifyForVideoCapabilityChanged(boolean isVideoCallCapable) { 2812 // Cache the current video capability so that we don't lose the information. 2813 mIsVideoCapable = isVideoCallCapable; 2814 2815 AsyncResult ar = new AsyncResult(null, isVideoCallCapable, null); 2816 mVideoCapabilityChangedRegistrants.notifyRegistrants(ar); 2817 } 2818 2819 /** 2820 * Notify registrants of a RING event. 2821 */ notifyIncomingRing()2822 private void notifyIncomingRing() { 2823 if (!mIsVoiceCapable) 2824 return; 2825 AsyncResult ar = new AsyncResult(null, this, null); 2826 mIncomingRingRegistrants.notifyRegistrants(ar); 2827 } 2828 2829 /** 2830 * Send the incoming call Ring notification if conditions are right. 2831 */ sendIncomingCallRingNotification(int token)2832 private void sendIncomingCallRingNotification(int token) { 2833 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 2834 (token == mCallRingContinueToken)) { 2835 Rlog.d(LOG_TAG, "Sending notifyIncomingRing"); 2836 notifyIncomingRing(); 2837 sendMessageDelayed( 2838 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 2839 } else { 2840 Rlog.d(LOG_TAG, "Ignoring ring notification request," 2841 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 2842 + " token=" + token 2843 + " mCallRingContinueToken=" + mCallRingContinueToken 2844 + " mIsVoiceCapable=" + mIsVoiceCapable); 2845 } 2846 } 2847 2848 /** 2849 * TODO: Adding a function for each property is not good. 2850 * A fucntion of type getPhoneProp(propType) where propType is an 2851 * enum of GSM+CDMA+LTE props would be a better approach. 2852 * 2853 * Get "Restriction of menu options for manual PLMN selection" bit 2854 * status from EF_CSP data, this belongs to "Value Added Services Group". 2855 * @return true if this bit is set or EF_CSP data is unavailable, 2856 * false otherwise 2857 */ isCspPlmnEnabled()2858 public boolean isCspPlmnEnabled() { 2859 return false; 2860 } 2861 2862 /** 2863 * Return an interface to retrieve the ISIM records for IMS, if available. 2864 * @return the interface to retrieve the ISIM records, or null if not supported 2865 */ getIsimRecords()2866 public IsimRecords getIsimRecords() { 2867 Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 2868 return null; 2869 } 2870 2871 /** 2872 * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to 2873 * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns 2874 * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones. 2875 */ getMsisdn()2876 public String getMsisdn() { 2877 return null; 2878 } 2879 2880 /** 2881 * Get the current for the default apn DataState. No change notification 2882 * exists at this interface -- use 2883 * {@link android.telephony.PhoneStateListener} instead. 2884 */ getDataConnectionState()2885 public PhoneConstants.DataState getDataConnectionState() { 2886 return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT); 2887 } 2888 notifyCallForwardingIndicator()2889 public void notifyCallForwardingIndicator() { 2890 } 2891 notifyDataConnectionFailed(String reason, String apnType)2892 public void notifyDataConnectionFailed(String reason, String apnType) { 2893 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 2894 } 2895 notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause)2896 public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, 2897 String failCause) { 2898 mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause); 2899 } 2900 2901 /** 2902 * Return if the current radio is LTE on CDMA. This 2903 * is a tri-state return value as for a period of time 2904 * the mode may be unknown. 2905 * 2906 * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE} 2907 * or {@link PhoneConstants#LTE_ON_CDMA_TRUE} 2908 */ getLteOnCdmaMode()2909 public int getLteOnCdmaMode() { 2910 return mCi.getLteOnCdmaMode(); 2911 } 2912 2913 /** 2914 * Sets the SIM voice message waiting indicator records. 2915 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 2916 * @param countWaiting The number of messages waiting, if known. Use 2917 * -1 to indicate that an unknown number of 2918 * messages are waiting 2919 */ setVoiceMessageWaiting(int line, int countWaiting)2920 public void setVoiceMessageWaiting(int line, int countWaiting) { 2921 // This function should be overridden by class GsmCdmaPhone. 2922 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone."); 2923 } 2924 2925 /** 2926 * Gets the USIM service table from the UICC, if present and available. 2927 * @return an interface to the UsimServiceTable record, or null if not available 2928 */ getUsimServiceTable()2929 public UsimServiceTable getUsimServiceTable() { 2930 IccRecords r = mIccRecords.get(); 2931 return (r != null) ? r.getUsimServiceTable() : null; 2932 } 2933 2934 /** 2935 * Gets the Uicc card corresponding to this phone. 2936 * @return the UiccCard object corresponding to the phone ID. 2937 */ getUiccCard()2938 public UiccCard getUiccCard() { 2939 return mUiccController.getUiccCard(mPhoneId); 2940 } 2941 2942 /** 2943 * Get P-CSCF address from PCO after data connection is established or modified. 2944 * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN 2945 */ getPcscfAddress(String apnType)2946 public String[] getPcscfAddress(String apnType) { 2947 return mDcTracker.getPcscfAddress(apnType); 2948 } 2949 2950 /** 2951 * Set IMS registration state 2952 */ setImsRegistrationState(boolean registered)2953 public void setImsRegistrationState(boolean registered) { 2954 } 2955 2956 /** 2957 * Return an instance of a IMS phone 2958 */ getImsPhone()2959 public Phone getImsPhone() { 2960 return mImsPhone; 2961 } 2962 2963 /** 2964 * Return if UT capability of ImsPhone is enabled or not 2965 */ isUtEnabled()2966 public boolean isUtEnabled() { 2967 if (mImsPhone != null) { 2968 return mImsPhone.isUtEnabled(); 2969 } 2970 return false; 2971 } 2972 dispose()2973 public void dispose() { 2974 } 2975 updateImsPhone()2976 private void updateImsPhone() { 2977 Rlog.d(LOG_TAG, "updateImsPhone" 2978 + " mImsServiceReady=" + mImsServiceReady); 2979 2980 if (mImsServiceReady && (mImsPhone == null)) { 2981 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this); 2982 CallManager.getInstance().registerPhone(mImsPhone); 2983 mImsPhone.registerForSilentRedial( 2984 this, EVENT_INITIATE_SILENT_REDIAL, null); 2985 } else if (!mImsServiceReady && (mImsPhone != null)) { 2986 CallManager.getInstance().unregisterPhone(mImsPhone); 2987 mImsPhone.unregisterForSilentRedial(this); 2988 2989 mImsPhone.dispose(); 2990 // Potential GC issue if someone keeps a reference to ImsPhone. 2991 // However: this change will make sure that such a reference does 2992 // not access functions through NULL pointer. 2993 //mImsPhone.removeReferences(); 2994 mImsPhone = null; 2995 } 2996 } 2997 2998 /** 2999 * Dials a number. 3000 * 3001 * @param dialString The number to dial. 3002 * @param uusInfo The UUSInfo. 3003 * @param videoState The video state for the call. 3004 * @param intentExtras Extras from the original CALL intent. 3005 * @return The Connection. 3006 * @throws CallStateException 3007 */ dialInternal( String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras)3008 protected Connection dialInternal( 3009 String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras) 3010 throws CallStateException { 3011 // dialInternal shall be overriden by GsmCdmaPhone 3012 return null; 3013 } 3014 3015 /* 3016 * Returns the subscription id. 3017 */ getSubId()3018 public int getSubId() { 3019 return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId); 3020 } 3021 3022 /** 3023 * Returns the phone id. 3024 */ getPhoneId()3025 public int getPhoneId() { 3026 return mPhoneId; 3027 } 3028 3029 /** 3030 * Return the service state of mImsPhone if it is STATE_IN_SERVICE 3031 * otherwise return the current voice service state 3032 */ getVoicePhoneServiceState()3033 public int getVoicePhoneServiceState() { 3034 Phone imsPhone = mImsPhone; 3035 if (imsPhone != null 3036 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) { 3037 return ServiceState.STATE_IN_SERVICE; 3038 } 3039 return getServiceState().getState(); 3040 } 3041 3042 /** 3043 * Override the service provider name and the operator name for the current ICCID. 3044 */ setOperatorBrandOverride(String brand)3045 public boolean setOperatorBrandOverride(String brand) { 3046 return false; 3047 } 3048 3049 /** 3050 * Override the roaming indicator for the current ICCID. 3051 */ setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)3052 public boolean setRoamingOverride(List<String> gsmRoamingList, 3053 List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 3054 List<String> cdmaNonRoamingList) { 3055 String iccId = getIccSerialNumber(); 3056 if (TextUtils.isEmpty(iccId)) { 3057 return false; 3058 } 3059 3060 setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3061 setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3062 setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3063 setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3064 3065 // Refresh. 3066 ServiceStateTracker tracker = getServiceStateTracker(); 3067 if (tracker != null) { 3068 tracker.pollState(); 3069 } 3070 return true; 3071 } 3072 setRoamingOverrideHelper(List<String> list, String prefix, String iccId)3073 private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) { 3074 SharedPreferences.Editor spEditor = 3075 PreferenceManager.getDefaultSharedPreferences(mContext).edit(); 3076 String key = prefix + iccId; 3077 if (list == null || list.isEmpty()) { 3078 spEditor.remove(key).commit(); 3079 } else { 3080 spEditor.putStringSet(key, new HashSet<String>(list)).commit(); 3081 } 3082 } 3083 isMccMncMarkedAsRoaming(String mccMnc)3084 public boolean isMccMncMarkedAsRoaming(String mccMnc) { 3085 return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 3086 } 3087 isMccMncMarkedAsNonRoaming(String mccMnc)3088 public boolean isMccMncMarkedAsNonRoaming(String mccMnc) { 3089 return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 3090 } 3091 isSidMarkedAsRoaming(int SID)3092 public boolean isSidMarkedAsRoaming(int SID) { 3093 return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX, 3094 Integer.toString(SID)); 3095 } 3096 isSidMarkedAsNonRoaming(int SID)3097 public boolean isSidMarkedAsNonRoaming(int SID) { 3098 return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, 3099 Integer.toString(SID)); 3100 } 3101 3102 /** 3103 * Query the IMS Registration Status. 3104 * 3105 * @return true if IMS is Registered 3106 */ isImsRegistered()3107 public boolean isImsRegistered() { 3108 Phone imsPhone = mImsPhone; 3109 boolean isImsRegistered = false; 3110 if (imsPhone != null) { 3111 isImsRegistered = imsPhone.isImsRegistered(); 3112 } else { 3113 ServiceStateTracker sst = getServiceStateTracker(); 3114 if (sst != null) { 3115 isImsRegistered = sst.isImsRegistered(); 3116 } 3117 } 3118 Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered); 3119 return isImsRegistered; 3120 } 3121 3122 /** 3123 * Get Wifi Calling Feature Availability 3124 */ isWifiCallingEnabled()3125 public boolean isWifiCallingEnabled() { 3126 Phone imsPhone = mImsPhone; 3127 boolean isWifiCallingEnabled = false; 3128 if (imsPhone != null) { 3129 isWifiCallingEnabled = imsPhone.isWifiCallingEnabled(); 3130 } 3131 Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled); 3132 return isWifiCallingEnabled; 3133 } 3134 3135 /** 3136 * Get Volte Feature Availability 3137 */ isVolteEnabled()3138 public boolean isVolteEnabled() { 3139 Phone imsPhone = mImsPhone; 3140 boolean isVolteEnabled = false; 3141 if (imsPhone != null) { 3142 isVolteEnabled = imsPhone.isVolteEnabled(); 3143 } 3144 Rlog.d(LOG_TAG, "isImsRegistered =" + isVolteEnabled); 3145 return isVolteEnabled; 3146 } 3147 getRoamingOverrideHelper(String prefix, String key)3148 private boolean getRoamingOverrideHelper(String prefix, String key) { 3149 String iccId = getIccSerialNumber(); 3150 if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) { 3151 return false; 3152 } 3153 3154 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 3155 Set<String> value = sp.getStringSet(prefix + iccId, null); 3156 if (value == null) { 3157 return false; 3158 } 3159 return value.contains(key); 3160 } 3161 3162 /** 3163 * Is Radio Present on the device and is it accessible 3164 */ isRadioAvailable()3165 public boolean isRadioAvailable() { 3166 return mCi.getRadioState().isAvailable(); 3167 } 3168 3169 /** 3170 * Is Radio turned on 3171 */ isRadioOn()3172 public boolean isRadioOn() { 3173 return mCi.getRadioState().isOn(); 3174 } 3175 3176 /** 3177 * shutdown Radio gracefully 3178 */ shutdownRadio()3179 public void shutdownRadio() { 3180 getServiceStateTracker().requestShutdown(); 3181 } 3182 3183 /** 3184 * Return true if the device is shutting down. 3185 */ isShuttingDown()3186 public boolean isShuttingDown() { 3187 return getServiceStateTracker().isDeviceShuttingDown(); 3188 } 3189 3190 /** 3191 * Set phone radio capability 3192 * 3193 * @param rc the phone radio capability defined in 3194 * RadioCapability. It's a input object used to transfer parameter to logic modem 3195 * @param response Callback message. 3196 */ setRadioCapability(RadioCapability rc, Message response)3197 public void setRadioCapability(RadioCapability rc, Message response) { 3198 mCi.setRadioCapability(rc, response); 3199 } 3200 3201 /** 3202 * Get phone radio access family 3203 * 3204 * @return a bit mask to identify the radio access family. 3205 */ getRadioAccessFamily()3206 public int getRadioAccessFamily() { 3207 final RadioCapability rc = getRadioCapability(); 3208 return (rc == null ? RadioAccessFamily.RAF_UNKNOWN : rc.getRadioAccessFamily()); 3209 } 3210 3211 /** 3212 * Get the associated data modems Id. 3213 * 3214 * @return a String containing the id of the data modem 3215 */ getModemUuId()3216 public String getModemUuId() { 3217 final RadioCapability rc = getRadioCapability(); 3218 return (rc == null ? "" : rc.getLogicalModemUuid()); 3219 } 3220 3221 /** 3222 * Get phone radio capability 3223 * 3224 * @return the capability of the radio defined in RadioCapability 3225 */ getRadioCapability()3226 public RadioCapability getRadioCapability() { 3227 return mRadioCapability.get(); 3228 } 3229 3230 /** 3231 * The RadioCapability has changed. This comes up from the RIL and is called when radios first 3232 * become available or after a capability switch. The flow is we use setRadioCapability to 3233 * request a change with the RIL and get an UNSOL response with the new data which gets set 3234 * here. 3235 * 3236 * @param rc the phone radio capability currently in effect for this phone. 3237 */ radioCapabilityUpdated(RadioCapability rc)3238 public void radioCapabilityUpdated(RadioCapability rc) { 3239 // Called when radios first become available or after a capability switch 3240 // Update the cached value 3241 mRadioCapability.set(rc); 3242 3243 if (SubscriptionManager.isValidSubscriptionId(getSubId())) { 3244 sendSubscriptionSettings(true); 3245 } 3246 } 3247 sendSubscriptionSettings(boolean restoreNetworkSelection)3248 public void sendSubscriptionSettings(boolean restoreNetworkSelection) { 3249 // Send settings down 3250 int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId()); 3251 setPreferredNetworkType(type, null); 3252 3253 if (restoreNetworkSelection) { 3254 restoreSavedNetworkSelection(null); 3255 } 3256 } 3257 setPreferredNetworkTypeIfSimLoaded()3258 protected void setPreferredNetworkTypeIfSimLoaded() { 3259 int subId = getSubId(); 3260 if (SubscriptionManager.isValidSubscriptionId(subId)) { 3261 int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId()); 3262 setPreferredNetworkType(type, null); 3263 } 3264 } 3265 3266 /** 3267 * Registers the handler when phone radio capability is changed. 3268 * 3269 * @param h Handler for notification message. 3270 * @param what User-defined message code. 3271 * @param obj User object. 3272 */ registerForRadioCapabilityChanged(Handler h, int what, Object obj)3273 public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) { 3274 mCi.registerForRadioCapabilityChanged(h, what, obj); 3275 } 3276 3277 /** 3278 * Unregister for notifications when phone radio type and access technology is changed. 3279 * 3280 * @param h Handler to be removed from the registrant list. 3281 */ unregisterForRadioCapabilityChanged(Handler h)3282 public void unregisterForRadioCapabilityChanged(Handler h) { 3283 mCi.unregisterForRadioCapabilityChanged(this); 3284 } 3285 3286 /** 3287 * Determines if IMS is enabled for call. 3288 * 3289 * @return {@code true} if IMS calling is enabled. 3290 */ isImsUseEnabled()3291 public boolean isImsUseEnabled() { 3292 boolean imsUseEnabled = 3293 ((ImsManager.isVolteEnabledByPlatform(mContext) && 3294 ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext)) || 3295 (ImsManager.isWfcEnabledByPlatform(mContext) && 3296 ImsManager.isWfcEnabledByUser(mContext)) && 3297 ImsManager.isNonTtyOrTtyOnVolteEnabled(mContext)); 3298 return imsUseEnabled; 3299 } 3300 3301 /** 3302 * Determines if video calling is enabled for the phone. 3303 * 3304 * @return {@code true} if video calling is enabled, {@code false} otherwise. 3305 */ isVideoEnabled()3306 public boolean isVideoEnabled() { 3307 Phone imsPhone = mImsPhone; 3308 if ((imsPhone != null) 3309 && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)) { 3310 return imsPhone.isVideoEnabled(); 3311 } 3312 return false; 3313 } 3314 3315 /** 3316 * Returns the status of Link Capacity Estimation (LCE) service. 3317 */ getLceStatus()3318 public int getLceStatus() { 3319 return mLceStatus; 3320 } 3321 3322 /** 3323 * Returns the modem activity information 3324 */ getModemActivityInfo(Message response)3325 public void getModemActivityInfo(Message response) { 3326 mCi.getModemActivityInfo(response); 3327 } 3328 3329 /** 3330 * Starts LCE service after radio becomes available. 3331 * LCE service state may get destroyed on the modem when radio becomes unavailable. 3332 */ startLceAfterRadioIsAvailable()3333 public void startLceAfterRadioIsAvailable() { 3334 mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE, 3335 obtainMessage(EVENT_CONFIG_LCE)); 3336 } 3337 3338 /** 3339 * Set allowed carriers 3340 */ setAllowedCarriers(List<CarrierIdentifier> carriers, Message response)3341 public void setAllowedCarriers(List<CarrierIdentifier> carriers, Message response) { 3342 mCi.setAllowedCarriers(carriers, response); 3343 } 3344 3345 /** 3346 * Get allowed carriers 3347 */ getAllowedCarriers(Message response)3348 public void getAllowedCarriers(Message response) { 3349 mCi.getAllowedCarriers(response); 3350 } 3351 3352 /** 3353 * Returns the locale based on the carrier properties (such as {@code ro.carrier}) and 3354 * SIM preferences. 3355 */ getLocaleFromSimAndCarrierPrefs()3356 public Locale getLocaleFromSimAndCarrierPrefs() { 3357 final IccRecords records = mIccRecords.get(); 3358 if (records != null && records.getSimLanguage() != null) { 3359 return new Locale(records.getSimLanguage()); 3360 } 3361 3362 return getLocaleFromCarrierProperties(mContext); 3363 } 3364 updateDataConnectionTracker()3365 public void updateDataConnectionTracker() { 3366 mDcTracker.update(); 3367 } 3368 setInternalDataEnabled(boolean enable, Message onCompleteMsg)3369 public void setInternalDataEnabled(boolean enable, Message onCompleteMsg) { 3370 mDcTracker.setInternalDataEnabled(enable, onCompleteMsg); 3371 } 3372 updateCurrentCarrierInProvider()3373 public boolean updateCurrentCarrierInProvider() { 3374 return false; 3375 } 3376 registerForAllDataDisconnected(Handler h, int what, Object obj)3377 public void registerForAllDataDisconnected(Handler h, int what, Object obj) { 3378 mDcTracker.registerForAllDataDisconnected(h, what, obj); 3379 } 3380 unregisterForAllDataDisconnected(Handler h)3381 public void unregisterForAllDataDisconnected(Handler h) { 3382 mDcTracker.unregisterForAllDataDisconnected(h); 3383 } 3384 registerForDataEnabledChanged(Handler h, int what, Object obj)3385 public void registerForDataEnabledChanged(Handler h, int what, Object obj) { 3386 mDcTracker.registerForDataEnabledChanged(h, what, obj); 3387 } 3388 unregisterForDataEnabledChanged(Handler h)3389 public void unregisterForDataEnabledChanged(Handler h) { 3390 mDcTracker.unregisterForDataEnabledChanged(h); 3391 } 3392 getIccSmsInterfaceManager()3393 public IccSmsInterfaceManager getIccSmsInterfaceManager(){ 3394 return null; 3395 } 3396 isMatchGid(String gid)3397 protected boolean isMatchGid(String gid) { 3398 String gid1 = getGroupIdLevel1(); 3399 int gidLength = gid.length(); 3400 if (!TextUtils.isEmpty(gid1) && (gid1.length() >= gidLength) 3401 && gid1.substring(0, gidLength).equalsIgnoreCase(gid)) { 3402 return true; 3403 } 3404 return false; 3405 } 3406 checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, Context context)3407 public static void checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, Context context) 3408 throws CallStateException { 3409 if (imsPhone == null || !imsPhone.isWifiCallingEnabled()) { 3410 boolean wfcWiFiOnly = (ImsManager.isWfcEnabledByPlatform(context) && 3411 ImsManager.isWfcEnabledByUser(context) && 3412 (ImsManager.getWfcMode(context) == 3413 ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY)); 3414 if (wfcWiFiOnly) { 3415 throw new CallStateException( 3416 CallStateException.ERROR_DISCONNECTED, 3417 "WFC Wi-Fi Only Mode: IMS not registered"); 3418 } 3419 } 3420 } 3421 startRingbackTone()3422 public void startRingbackTone() { 3423 } 3424 stopRingbackTone()3425 public void stopRingbackTone() { 3426 } 3427 callEndCleanupHandOverCallIfAny()3428 public void callEndCleanupHandOverCallIfAny() { 3429 } 3430 cancelUSSD()3431 public void cancelUSSD() { 3432 } 3433 3434 /** 3435 * Set boolean broadcastEmergencyCallStateChanges 3436 */ setBroadcastEmergencyCallStateChanges(boolean broadcast)3437 public abstract void setBroadcastEmergencyCallStateChanges(boolean broadcast); 3438 sendEmergencyCallStateChange(boolean callActive)3439 public abstract void sendEmergencyCallStateChange(boolean callActive); 3440 3441 /** 3442 * This function returns the parent phone of the current phone. It is applicable 3443 * only for IMS phone (function is overridden by ImsPhone). For others the phone 3444 * object itself is returned. 3445 * @return 3446 */ getDefaultPhone()3447 public Phone getDefaultPhone() { 3448 return this; 3449 } 3450 getVtDataUsage()3451 public long getVtDataUsage() { 3452 if (mImsPhone == null) return 0; 3453 return mImsPhone.getVtDataUsage(); 3454 } 3455 3456 /** 3457 * Policy control of data connection. Usually used when we hit data limit. 3458 * @param enabled True if enabling the data, otherwise disabling. 3459 */ setPolicyDataEnabled(boolean enabled)3460 public void setPolicyDataEnabled(boolean enabled) { 3461 mDcTracker.setPolicyDataEnabled(enabled); 3462 } 3463 3464 /** 3465 * SIP URIs aliased to the current subscriber given by the IMS implementation. 3466 * Applicable only on IMS; used in absence of line1number. 3467 * @return array of SIP URIs aliased to the current subscriber 3468 */ getCurrentSubscriberUris()3469 public Uri[] getCurrentSubscriberUris() { 3470 return null; 3471 } 3472 getAppSmsManager()3473 public AppSmsManager getAppSmsManager() { 3474 return mAppSmsManager; 3475 } 3476 3477 /** 3478 * Set SIM card power state. Request is equivalent to inserting or removing the card. 3479 * @param powerUp True if powering up the SIM, otherwise powering down 3480 **/ setSimPowerState(boolean powerUp)3481 public void setSimPowerState(boolean powerUp) { 3482 mCi.setSimCardPower(powerUp, null); 3483 } 3484 dump(FileDescriptor fd, PrintWriter pw, String[] args)3485 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3486 pw.println("Phone: subId=" + getSubId()); 3487 pw.println(" mPhoneId=" + mPhoneId); 3488 pw.println(" mCi=" + mCi); 3489 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 3490 pw.println(" mDcTracker=" + mDcTracker); 3491 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 3492 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 3493 pw.println(" mCallRingDelay=" + mCallRingDelay); 3494 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 3495 pw.println(" mIccRecords=" + mIccRecords.get()); 3496 pw.println(" mUiccApplication=" + mUiccApplication.get()); 3497 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 3498 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 3499 pw.flush(); 3500 pw.println(" mLooper=" + mLooper); 3501 pw.println(" mContext=" + mContext); 3502 pw.println(" mNotifier=" + mNotifier); 3503 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 3504 pw.println(" mUnitTestMode=" + mUnitTestMode); 3505 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 3506 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 3507 pw.println(" getState()=" + getState()); 3508 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 3509 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 3510 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 3511 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 3512 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 3513 pw.flush(); 3514 pw.println(" isInEcm()=" + isInEcm()); 3515 pw.println(" getPhoneName()=" + getPhoneName()); 3516 pw.println(" getPhoneType()=" + getPhoneType()); 3517 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 3518 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 3519 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 3520 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 3521 pw.flush(); 3522 pw.println("++++++++++++++++++++++++++++++++"); 3523 3524 if (mImsPhone != null) { 3525 try { 3526 mImsPhone.dump(fd, pw, args); 3527 } catch (Exception e) { 3528 e.printStackTrace(); 3529 } 3530 3531 pw.flush(); 3532 pw.println("++++++++++++++++++++++++++++++++"); 3533 } 3534 3535 if (mDcTracker != null) { 3536 try { 3537 mDcTracker.dump(fd, pw, args); 3538 } catch (Exception e) { 3539 e.printStackTrace(); 3540 } 3541 3542 pw.flush(); 3543 pw.println("++++++++++++++++++++++++++++++++"); 3544 } 3545 3546 if (getServiceStateTracker() != null) { 3547 try { 3548 getServiceStateTracker().dump(fd, pw, args); 3549 } catch (Exception e) { 3550 e.printStackTrace(); 3551 } 3552 3553 pw.flush(); 3554 pw.println("++++++++++++++++++++++++++++++++"); 3555 } 3556 3557 if (mCarrierActionAgent != null) { 3558 try { 3559 mCarrierActionAgent.dump(fd, pw, args); 3560 } catch (Exception e) { 3561 e.printStackTrace(); 3562 } 3563 3564 pw.flush(); 3565 pw.println("++++++++++++++++++++++++++++++++"); 3566 } 3567 3568 if (mCarrierSignalAgent != null) { 3569 try { 3570 mCarrierSignalAgent.dump(fd, pw, args); 3571 } catch (Exception e) { 3572 e.printStackTrace(); 3573 } 3574 3575 pw.flush(); 3576 pw.println("++++++++++++++++++++++++++++++++"); 3577 } 3578 3579 if (getCallTracker() != null) { 3580 try { 3581 getCallTracker().dump(fd, pw, args); 3582 } catch (Exception e) { 3583 e.printStackTrace(); 3584 } 3585 3586 pw.flush(); 3587 pw.println("++++++++++++++++++++++++++++++++"); 3588 } 3589 3590 if (mSimActivationTracker != null) { 3591 try { 3592 mSimActivationTracker.dump(fd, pw, args); 3593 } catch (Exception e) { 3594 e.printStackTrace(); 3595 } 3596 3597 pw.flush(); 3598 pw.println("++++++++++++++++++++++++++++++++"); 3599 } 3600 3601 if (mCi != null && mCi instanceof RIL) { 3602 try { 3603 ((RIL)mCi).dump(fd, pw, args); 3604 } catch (Exception e) { 3605 e.printStackTrace(); 3606 } 3607 3608 pw.flush(); 3609 pw.println("++++++++++++++++++++++++++++++++"); 3610 } 3611 } 3612 } 3613