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 1332 // Commit and log the result. 1333 if (!editor.commit()) { 1334 Rlog.e(LOG_TAG, "Failed to commit CLIR preference"); 1335 } 1336 } 1337 1338 /** 1339 * For unit tests; don't send notifications to "Phone" 1340 * mailbox registrants if true. 1341 */ setUnitTestMode(boolean f)1342 private void setUnitTestMode(boolean f) { 1343 mUnitTestMode = f; 1344 } 1345 1346 /** 1347 * @return true If unit test mode is enabled 1348 */ getUnitTestMode()1349 public boolean getUnitTestMode() { 1350 return mUnitTestMode; 1351 } 1352 1353 /** 1354 * To be invoked when a voice call Connection disconnects. 1355 * 1356 * Subclasses of Phone probably want to replace this with a 1357 * version scoped to their packages 1358 */ notifyDisconnectP(Connection cn)1359 protected void notifyDisconnectP(Connection cn) { 1360 AsyncResult ar = new AsyncResult(null, cn, null); 1361 mDisconnectRegistrants.notifyRegistrants(ar); 1362 } 1363 1364 /** 1365 * Register for ServiceState changed. 1366 * Message.obj will contain an AsyncResult. 1367 * AsyncResult.result will be a ServiceState instance 1368 */ registerForServiceStateChanged( Handler h, int what, Object obj)1369 public void registerForServiceStateChanged( 1370 Handler h, int what, Object obj) { 1371 checkCorrectThread(h); 1372 1373 mServiceStateRegistrants.add(h, what, obj); 1374 } 1375 1376 /** 1377 * Unregisters for ServiceStateChange notification. 1378 * Extraneous calls are tolerated silently 1379 */ unregisterForServiceStateChanged(Handler h)1380 public void unregisterForServiceStateChanged(Handler h) { 1381 mServiceStateRegistrants.remove(h); 1382 } 1383 1384 /** 1385 * Notifies when out-band ringback tone is needed.<p> 1386 * 1387 * Messages received from this: 1388 * Message.obj will be an AsyncResult 1389 * AsyncResult.userObj = obj 1390 * AsyncResult.result = boolean, true to start play ringback tone 1391 * and false to stop. <p> 1392 */ registerForRingbackTone(Handler h, int what, Object obj)1393 public void registerForRingbackTone(Handler h, int what, Object obj) { 1394 mCi.registerForRingbackTone(h, what, obj); 1395 } 1396 1397 /** 1398 * Unregisters for ringback tone notification. 1399 */ unregisterForRingbackTone(Handler h)1400 public void unregisterForRingbackTone(Handler h) { 1401 mCi.unregisterForRingbackTone(h); 1402 } 1403 1404 /** 1405 * Notifies when out-band on-hold tone is needed.<p> 1406 * 1407 * Messages received from this: 1408 * Message.obj will be an AsyncResult 1409 * AsyncResult.userObj = obj 1410 * AsyncResult.result = boolean, true to start play on-hold tone 1411 * and false to stop. <p> 1412 */ registerForOnHoldTone(Handler h, int what, Object obj)1413 public void registerForOnHoldTone(Handler h, int what, Object obj) { 1414 } 1415 1416 /** 1417 * Unregisters for on-hold tone notification. 1418 */ unregisterForOnHoldTone(Handler h)1419 public void unregisterForOnHoldTone(Handler h) { 1420 } 1421 1422 /** 1423 * Registers the handler to reset the uplink mute state to get 1424 * uplink audio. 1425 */ registerForResendIncallMute(Handler h, int what, Object obj)1426 public void registerForResendIncallMute(Handler h, int what, Object obj) { 1427 mCi.registerForResendIncallMute(h, what, obj); 1428 } 1429 1430 /** 1431 * Unregisters for resend incall mute notifications. 1432 */ unregisterForResendIncallMute(Handler h)1433 public void unregisterForResendIncallMute(Handler h) { 1434 mCi.unregisterForResendIncallMute(h); 1435 } 1436 1437 /** 1438 * Enables or disables echo suppression. 1439 */ setEchoSuppressionEnabled()1440 public void setEchoSuppressionEnabled() { 1441 // no need for regular phone 1442 } 1443 1444 /** 1445 * Subclasses of Phone probably want to replace this with a 1446 * version scoped to their packages 1447 */ notifyServiceStateChangedP(ServiceState ss)1448 protected void notifyServiceStateChangedP(ServiceState ss) { 1449 AsyncResult ar = new AsyncResult(null, ss, null); 1450 mServiceStateRegistrants.notifyRegistrants(ar); 1451 1452 mNotifier.notifyServiceState(this); 1453 } 1454 1455 /** 1456 * If this is a simulated phone interface, returns a SimulatedRadioControl. 1457 * @return SimulatedRadioControl if this is a simulated interface; 1458 * otherwise, null. 1459 */ getSimulatedRadioControl()1460 public SimulatedRadioControl getSimulatedRadioControl() { 1461 return mSimulatedRadioControl; 1462 } 1463 1464 /** 1465 * Verifies the current thread is the same as the thread originally 1466 * used in the initialization of this instance. Throws RuntimeException 1467 * if not. 1468 * 1469 * @exception RuntimeException if the current thread is not 1470 * the thread that originally obtained this Phone instance. 1471 */ checkCorrectThread(Handler h)1472 private void checkCorrectThread(Handler h) { 1473 if (h.getLooper() != mLooper) { 1474 throw new RuntimeException( 1475 "com.android.internal.telephony.Phone must be used from within one thread"); 1476 } 1477 } 1478 1479 /** 1480 * Set the properties by matching the carrier string in 1481 * a string-array resource 1482 */ getLocaleFromCarrierProperties(Context ctx)1483 private static Locale getLocaleFromCarrierProperties(Context ctx) { 1484 String carrier = SystemProperties.get("ro.carrier"); 1485 1486 if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { 1487 return null; 1488 } 1489 1490 CharSequence[] carrierLocales = ctx.getResources().getTextArray(R.array.carrier_properties); 1491 1492 for (int i = 0; i < carrierLocales.length; i+=3) { 1493 String c = carrierLocales[i].toString(); 1494 if (carrier.equals(c)) { 1495 return Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-')); 1496 } 1497 } 1498 1499 return null; 1500 } 1501 1502 /** 1503 * Get current coarse-grained voice call state. 1504 * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object) 1505 * registerForPreciseCallStateChanged()} for change notification. <p> 1506 * If the phone has an active call and call waiting occurs, 1507 * then the phone state is RINGING not OFFHOOK 1508 * <strong>Note:</strong> 1509 * This registration point provides notification of finer-grained 1510 * changes.<p> 1511 */ getState()1512 public abstract PhoneConstants.State getState(); 1513 1514 /** 1515 * Retrieves the IccFileHandler of the Phone instance 1516 */ getIccFileHandler()1517 public IccFileHandler getIccFileHandler(){ 1518 UiccCardApplication uiccApplication = mUiccApplication.get(); 1519 IccFileHandler fh; 1520 1521 if (uiccApplication == null) { 1522 Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null"); 1523 fh = null; 1524 } else { 1525 fh = uiccApplication.getIccFileHandler(); 1526 } 1527 1528 Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh); 1529 return fh; 1530 } 1531 1532 /* 1533 * Retrieves the Handler of the Phone instance 1534 */ getHandler()1535 public Handler getHandler() { 1536 return this; 1537 } 1538 1539 /** 1540 * Update the phone object if the voice radio technology has changed 1541 * 1542 * @param voiceRadioTech The new voice radio technology 1543 */ updatePhoneObject(int voiceRadioTech)1544 public void updatePhoneObject(int voiceRadioTech) { 1545 } 1546 1547 /** 1548 * Retrieves the ServiceStateTracker of the phone instance. 1549 */ getServiceStateTracker()1550 public ServiceStateTracker getServiceStateTracker() { 1551 return null; 1552 } 1553 1554 /** 1555 * Get call tracker 1556 */ getCallTracker()1557 public CallTracker getCallTracker() { 1558 return null; 1559 } 1560 1561 /** 1562 * Update voice activation state 1563 */ setVoiceActivationState(int state)1564 public void setVoiceActivationState(int state) { 1565 mSimActivationTracker.setVoiceActivationState(state); 1566 } 1567 /** 1568 * Update data activation state 1569 */ setDataActivationState(int state)1570 public void setDataActivationState(int state) { 1571 mSimActivationTracker.setDataActivationState(state); 1572 } 1573 1574 /** 1575 * Returns voice activation state 1576 */ getVoiceActivationState()1577 public int getVoiceActivationState() { 1578 return mSimActivationTracker.getVoiceActivationState(); 1579 } 1580 /** 1581 * Returns data activation state 1582 */ getDataActivationState()1583 public int getDataActivationState() { 1584 return mSimActivationTracker.getDataActivationState(); 1585 } 1586 1587 /** 1588 * Update voice mail count related fields and notify listeners 1589 */ updateVoiceMail()1590 public void updateVoiceMail() { 1591 Rlog.e(LOG_TAG, "updateVoiceMail() should be overridden"); 1592 } 1593 getCurrentUiccAppType()1594 public AppType getCurrentUiccAppType() { 1595 UiccCardApplication currentApp = mUiccApplication.get(); 1596 if (currentApp != null) { 1597 return currentApp.getType(); 1598 } 1599 return AppType.APPTYPE_UNKNOWN; 1600 } 1601 1602 /** 1603 * Returns the ICC card interface for this phone, or null 1604 * if not applicable to underlying technology. 1605 */ getIccCard()1606 public IccCard getIccCard() { 1607 return null; 1608 //throw new Exception("getIccCard Shouldn't be called from Phone"); 1609 } 1610 1611 /** 1612 * Retrieves the serial number of the ICC, if applicable. Returns only the decimal digits before 1613 * the first hex digit in the ICC ID. 1614 */ getIccSerialNumber()1615 public String getIccSerialNumber() { 1616 IccRecords r = mIccRecords.get(); 1617 return (r != null) ? r.getIccId() : null; 1618 } 1619 1620 /** 1621 * Retrieves the full serial number of the ICC (including hex digits), if applicable. 1622 */ getFullIccSerialNumber()1623 public String getFullIccSerialNumber() { 1624 IccRecords r = mIccRecords.get(); 1625 return (r != null) ? r.getFullIccId() : null; 1626 } 1627 1628 /** 1629 * Returns SIM record load state. Use 1630 * <code>getSimCard().registerForReady()</code> for change notification. 1631 * 1632 * @return true if records from the SIM have been loaded and are 1633 * available (if applicable). If not applicable to the underlying 1634 * technology, returns true as well. 1635 */ getIccRecordsLoaded()1636 public boolean getIccRecordsLoaded() { 1637 IccRecords r = mIccRecords.get(); 1638 return (r != null) ? r.getRecordsLoaded() : false; 1639 } 1640 1641 /** 1642 * @param workSource calling WorkSource 1643 * @return all available cell information or null if none. 1644 */ getAllCellInfo(WorkSource workSource)1645 public List<CellInfo> getAllCellInfo(WorkSource workSource) { 1646 List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo(workSource); 1647 return privatizeCellInfoList(cellInfoList); 1648 } 1649 getCellLocation()1650 public CellLocation getCellLocation() { 1651 return getCellLocation(null); 1652 } 1653 1654 /** 1655 * Clear CDMA base station lat/long values if location setting is disabled. 1656 * @param cellInfoList the original cell info list from the RIL 1657 * @return the original list with CDMA lat/long cleared if necessary 1658 */ privatizeCellInfoList(List<CellInfo> cellInfoList)1659 private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) { 1660 if (cellInfoList == null) return null; 1661 int mode = Settings.Secure.getInt(getContext().getContentResolver(), 1662 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 1663 if (mode == Settings.Secure.LOCATION_MODE_OFF) { 1664 ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size()); 1665 // clear lat/lon values for location privacy 1666 for (CellInfo c : cellInfoList) { 1667 if (c instanceof CellInfoCdma) { 1668 CellInfoCdma cellInfoCdma = (CellInfoCdma) c; 1669 CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity(); 1670 CellIdentityCdma maskedCellIdentity = new CellIdentityCdma( 1671 cellIdentity.getNetworkId(), 1672 cellIdentity.getSystemId(), 1673 cellIdentity.getBasestationId(), 1674 Integer.MAX_VALUE, Integer.MAX_VALUE); 1675 CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma); 1676 privateCellInfoCdma.setCellIdentity(maskedCellIdentity); 1677 privateCellInfoList.add(privateCellInfoCdma); 1678 } else { 1679 privateCellInfoList.add(c); 1680 } 1681 } 1682 cellInfoList = privateCellInfoList; 1683 } 1684 return cellInfoList; 1685 } 1686 1687 /** 1688 * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged 1689 * PhoneStateListener.onCellInfoChanged} will be invoked. 1690 * 1691 * The default, 0, means invoke onCellInfoChanged when any of the reported 1692 * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue 1693 * A onCellInfoChanged. 1694 * 1695 * @param rateInMillis the rate 1696 * @param workSource calling WorkSource 1697 */ setCellInfoListRate(int rateInMillis, WorkSource workSource)1698 public void setCellInfoListRate(int rateInMillis, WorkSource workSource) { 1699 mCi.setCellInfoListRate(rateInMillis, null, workSource); 1700 } 1701 1702 /** 1703 * Get voice message waiting indicator status. No change notification 1704 * available on this interface. Use PhoneStateNotifier or similar instead. 1705 * 1706 * @return true if there is a voice message waiting 1707 */ getMessageWaitingIndicator()1708 public boolean getMessageWaitingIndicator() { 1709 return mVmCount != 0; 1710 } 1711 getCallForwardingIndicatorFromSharedPref()1712 private int getCallForwardingIndicatorFromSharedPref() { 1713 int status = IccRecords.CALL_FORWARDING_STATUS_DISABLED; 1714 int subId = getSubId(); 1715 if (SubscriptionManager.isValidSubscriptionId(subId)) { 1716 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 1717 status = sp.getInt(CF_STATUS + subId, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN); 1718 Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " + 1719 status); 1720 // Check for old preference if status is UNKNOWN for current subId. This part of the 1721 // code is needed only when upgrading from M to N. 1722 if (status == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) { 1723 String subscriberId = sp.getString(CF_ID, null); 1724 if (subscriberId != null) { 1725 String currentSubscriberId = getSubscriberId(); 1726 1727 if (subscriberId.equals(currentSubscriberId)) { 1728 // get call forwarding status from preferences 1729 status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED); 1730 setCallForwardingIndicatorInSharedPref( 1731 status == IccRecords.CALL_FORWARDING_STATUS_ENABLED ? true : false); 1732 Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: " + status); 1733 } else { 1734 Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: returning " + 1735 "DISABLED as status for matching subscriberId not found"); 1736 } 1737 1738 // get rid of old preferences. 1739 SharedPreferences.Editor editor = sp.edit(); 1740 editor.remove(CF_ID); 1741 editor.remove(CF_STATUS); 1742 editor.apply(); 1743 } 1744 } 1745 } else { 1746 Rlog.e(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId); 1747 } 1748 return status; 1749 } 1750 setCallForwardingIndicatorInSharedPref(boolean enable)1751 private void setCallForwardingIndicatorInSharedPref(boolean enable) { 1752 int status = enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED : 1753 IccRecords.CALL_FORWARDING_STATUS_DISABLED; 1754 int subId = getSubId(); 1755 Rlog.d(LOG_TAG, "setCallForwardingIndicatorInSharedPref: Storing status = " + status + 1756 " in pref " + CF_STATUS + subId); 1757 1758 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 1759 SharedPreferences.Editor editor = sp.edit(); 1760 editor.putInt(CF_STATUS + subId, status); 1761 editor.apply(); 1762 } 1763 setVoiceCallForwardingFlag(int line, boolean enable, String number)1764 public void setVoiceCallForwardingFlag(int line, boolean enable, String number) { 1765 setCallForwardingIndicatorInSharedPref(enable); 1766 IccRecords r = mIccRecords.get(); 1767 if (r != null) { 1768 r.setVoiceCallForwardingFlag(line, enable, number); 1769 } 1770 } 1771 setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, String number)1772 protected void setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, 1773 String number) { 1774 setCallForwardingIndicatorInSharedPref(enable); 1775 r.setVoiceCallForwardingFlag(line, enable, number); 1776 } 1777 1778 /** 1779 * Get voice call forwarding indicator status. No change notification 1780 * available on this interface. Use PhoneStateNotifier or similar instead. 1781 * 1782 * @return true if there is a voice call forwarding 1783 */ getCallForwardingIndicator()1784 public boolean getCallForwardingIndicator() { 1785 if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1786 Rlog.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA"); 1787 return false; 1788 } 1789 IccRecords r = mIccRecords.get(); 1790 int callForwardingIndicator = IccRecords.CALL_FORWARDING_STATUS_UNKNOWN; 1791 if (r != null) { 1792 callForwardingIndicator = r.getVoiceCallForwardingFlag(); 1793 } 1794 if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) { 1795 callForwardingIndicator = getCallForwardingIndicatorFromSharedPref(); 1796 } 1797 return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED); 1798 } 1799 getCarrierSignalAgent()1800 public CarrierSignalAgent getCarrierSignalAgent() { 1801 return mCarrierSignalAgent; 1802 } 1803 getCarrierActionAgent()1804 public CarrierActionAgent getCarrierActionAgent() { 1805 return mCarrierActionAgent; 1806 } 1807 1808 /** 1809 * Query the CDMA roaming preference setting 1810 * 1811 * @param response is callback message to report one of CDMA_RM_* 1812 */ queryCdmaRoamingPreference(Message response)1813 public void queryCdmaRoamingPreference(Message response) { 1814 mCi.queryCdmaRoamingPreference(response); 1815 } 1816 1817 /** 1818 * Get current signal strength. No change notification available on this 1819 * interface. Use <code>PhoneStateNotifier</code> or an equivalent. 1820 * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu). 1821 * The following special values are defined:</p> 1822 * <ul><li>0 means "-113 dBm or less".</li> 1823 * <li>31 means "-51 dBm or greater".</li></ul> 1824 * 1825 * @return Current signal strength as SignalStrength 1826 */ getSignalStrength()1827 public SignalStrength getSignalStrength() { 1828 ServiceStateTracker sst = getServiceStateTracker(); 1829 if (sst == null) { 1830 return new SignalStrength(); 1831 } else { 1832 return sst.getSignalStrength(); 1833 } 1834 } 1835 1836 /** 1837 * @return true, if the device is in a state where both voice and data 1838 * are supported simultaneously. This can change based on location or network condition. 1839 */ isConcurrentVoiceAndDataAllowed()1840 public boolean isConcurrentVoiceAndDataAllowed() { 1841 ServiceStateTracker sst = getServiceStateTracker(); 1842 return sst == null ? false : sst.isConcurrentVoiceAndDataAllowed(); 1843 } 1844 1845 /** 1846 * Requests to set the CDMA roaming preference 1847 * @param cdmaRoamingType one of CDMA_RM_* 1848 * @param response is callback message 1849 */ setCdmaRoamingPreference(int cdmaRoamingType, Message response)1850 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 1851 mCi.setCdmaRoamingPreference(cdmaRoamingType, response); 1852 } 1853 1854 /** 1855 * Requests to set the CDMA subscription mode 1856 * @param cdmaSubscriptionType one of CDMA_SUBSCRIPTION_* 1857 * @param response is callback message 1858 */ setCdmaSubscription(int cdmaSubscriptionType, Message response)1859 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 1860 mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 1861 } 1862 1863 /** 1864 * Requests to set the preferred network type for searching and registering 1865 * (CS/PS domain, RAT, and operation mode) 1866 * @param networkType one of NT_*_TYPE 1867 * @param response is callback message 1868 */ setPreferredNetworkType(int networkType, Message response)1869 public void setPreferredNetworkType(int networkType, Message response) { 1870 // Only set preferred network types to that which the modem supports 1871 int modemRaf = getRadioAccessFamily(); 1872 int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType); 1873 1874 if (modemRaf == RadioAccessFamily.RAF_UNKNOWN 1875 || rafFromType == RadioAccessFamily.RAF_UNKNOWN) { 1876 Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: " 1877 + modemRaf + " " + rafFromType); 1878 if (response != null) { 1879 CommandException ex; 1880 1881 ex = new CommandException(CommandException.Error.GENERIC_FAILURE); 1882 AsyncResult.forMessage(response, null, ex); 1883 response.sendToTarget(); 1884 } 1885 return; 1886 } 1887 1888 int filteredRaf = (rafFromType & modemRaf); 1889 int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf); 1890 1891 Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType 1892 + " modemRaf = " + modemRaf 1893 + " rafFromType = " + rafFromType 1894 + " filteredType = " + filteredType); 1895 1896 mCi.setPreferredNetworkType(filteredType, response); 1897 } 1898 1899 /** 1900 * Query the preferred network type setting 1901 * 1902 * @param response is callback message to report one of NT_*_TYPE 1903 */ getPreferredNetworkType(Message response)1904 public void getPreferredNetworkType(Message response) { 1905 mCi.getPreferredNetworkType(response); 1906 } 1907 1908 /** 1909 * Gets the default SMSC address. 1910 * 1911 * @param result Callback message contains the SMSC address. 1912 */ getSmscAddress(Message result)1913 public void getSmscAddress(Message result) { 1914 mCi.getSmscAddress(result); 1915 } 1916 1917 /** 1918 * Sets the default SMSC address. 1919 * 1920 * @param address new SMSC address 1921 * @param result Callback message is empty on completion 1922 */ setSmscAddress(String address, Message result)1923 public void setSmscAddress(String address, Message result) { 1924 mCi.setSmscAddress(address, result); 1925 } 1926 1927 /** 1928 * setTTYMode 1929 * sets a TTY mode option. 1930 * @param ttyMode is a one of the following: 1931 * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} 1932 * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} 1933 * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} 1934 * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} 1935 * @param onComplete a callback message when the action is completed 1936 */ setTTYMode(int ttyMode, Message onComplete)1937 public void setTTYMode(int ttyMode, Message onComplete) { 1938 mCi.setTTYMode(ttyMode, onComplete); 1939 } 1940 1941 /** 1942 * setUiTTYMode 1943 * sets a TTY mode option. 1944 * @param ttyMode is a one of the following: 1945 * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} 1946 * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} 1947 * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} 1948 * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} 1949 * @param onComplete a callback message when the action is completed 1950 */ setUiTTYMode(int uiTtyMode, Message onComplete)1951 public void setUiTTYMode(int uiTtyMode, Message onComplete) { 1952 Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call"); 1953 } 1954 1955 /** 1956 * queryTTYMode 1957 * query the status of the TTY mode 1958 * 1959 * @param onComplete a callback message when the action is completed. 1960 */ queryTTYMode(Message onComplete)1961 public void queryTTYMode(Message onComplete) { 1962 mCi.queryTTYMode(onComplete); 1963 } 1964 1965 /** 1966 * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is 1967 * disabled, normal VP is enabled. 1968 * 1969 * @param enable whether true or false to enable or disable. 1970 * @param onComplete a callback message when the action is completed. 1971 */ enableEnhancedVoicePrivacy(boolean enable, Message onComplete)1972 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 1973 } 1974 1975 /** 1976 * Get the currently set Voice Privacy (VP) mode. 1977 * 1978 * @param onComplete a callback message when the action is completed. 1979 */ getEnhancedVoicePrivacy(Message onComplete)1980 public void getEnhancedVoicePrivacy(Message onComplete) { 1981 } 1982 1983 /** 1984 * Assign a specified band for RF configuration. 1985 * 1986 * @param bandMode one of BM_*_BAND 1987 * @param response is callback message 1988 */ setBandMode(int bandMode, Message response)1989 public void setBandMode(int bandMode, Message response) { 1990 mCi.setBandMode(bandMode, response); 1991 } 1992 1993 /** 1994 * Query the list of band mode supported by RF. 1995 * 1996 * @param response is callback message 1997 * ((AsyncResult)response.obj).result is an int[] where int[0] is 1998 * the size of the array and the rest of each element representing 1999 * one available BM_*_BAND 2000 */ queryAvailableBandMode(Message response)2001 public void queryAvailableBandMode(Message response) { 2002 mCi.queryAvailableBandMode(response); 2003 } 2004 2005 /** 2006 * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation. 2007 * 2008 * @param data The data for the request. 2009 * @param response <strong>On success</strong>, 2010 * (byte[])(((AsyncResult)response.obj).result) 2011 * <strong>On failure</strong>, 2012 * (((AsyncResult)response.obj).result) == null and 2013 * (((AsyncResult)response.obj).exception) being an instance of 2014 * com.android.internal.telephony.gsm.CommandException 2015 * 2016 * @see #invokeOemRilRequestRaw(byte[], android.os.Message) 2017 * @deprecated OEM needs a vendor-extension hal and their apps should use that instead 2018 */ 2019 @Deprecated invokeOemRilRequestRaw(byte[] data, Message response)2020 public void invokeOemRilRequestRaw(byte[] data, Message response) { 2021 mCi.invokeOemRilRequestRaw(data, response); 2022 } 2023 2024 /** 2025 * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation. 2026 * 2027 * @param strings The strings to make available as the request data. 2028 * @param response <strong>On success</strong>, "response" bytes is 2029 * made available as: 2030 * (String[])(((AsyncResult)response.obj).result). 2031 * <strong>On failure</strong>, 2032 * (((AsyncResult)response.obj).result) == null and 2033 * (((AsyncResult)response.obj).exception) being an instance of 2034 * com.android.internal.telephony.gsm.CommandException 2035 * 2036 * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message) 2037 * @deprecated OEM needs a vendor-extension hal and their apps should use that instead 2038 */ 2039 @Deprecated invokeOemRilRequestStrings(String[] strings, Message response)2040 public void invokeOemRilRequestStrings(String[] strings, Message response) { 2041 mCi.invokeOemRilRequestStrings(strings, response); 2042 } 2043 2044 /** 2045 * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}. 2046 * Used for device configuration by some CDMA operators. 2047 * 2048 * @param itemID the ID of the item to read 2049 * @param response callback message with the String response in the obj field 2050 */ nvReadItem(int itemID, Message response)2051 public void nvReadItem(int itemID, Message response) { 2052 mCi.nvReadItem(itemID, response); 2053 } 2054 2055 /** 2056 * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}. 2057 * Used for device configuration by some CDMA operators. 2058 * 2059 * @param itemID the ID of the item to read 2060 * @param itemValue the value to write, as a String 2061 * @param response Callback message. 2062 */ nvWriteItem(int itemID, String itemValue, Message response)2063 public void nvWriteItem(int itemID, String itemValue, Message response) { 2064 mCi.nvWriteItem(itemID, itemValue, response); 2065 } 2066 2067 /** 2068 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 2069 * Used for device configuration by some CDMA operators. 2070 * 2071 * @param preferredRoamingList byte array containing the new PRL 2072 * @param response Callback message. 2073 */ nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)2074 public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) { 2075 mCi.nvWriteCdmaPrl(preferredRoamingList, response); 2076 } 2077 2078 /** 2079 * Perform the specified type of NV config reset. The radio will be taken offline 2080 * and the device must be rebooted after erasing the NV. Used for device 2081 * configuration by some CDMA operators. 2082 * 2083 * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset 2084 * @param response Callback message. 2085 */ nvResetConfig(int resetType, Message response)2086 public void nvResetConfig(int resetType, Message response) { 2087 mCi.nvResetConfig(resetType, response); 2088 } 2089 notifyDataActivity()2090 public void notifyDataActivity() { 2091 mNotifier.notifyDataActivity(this); 2092 } 2093 notifyMessageWaitingIndicator()2094 private void notifyMessageWaitingIndicator() { 2095 // Do not notify voice mail waiting if device doesn't support voice 2096 if (!mIsVoiceCapable) 2097 return; 2098 2099 // This function is added to send the notification to DefaultPhoneNotifier. 2100 mNotifier.notifyMessageWaitingChanged(this); 2101 } 2102 notifyDataConnection(String reason, String apnType, PhoneConstants.DataState state)2103 public void notifyDataConnection(String reason, String apnType, 2104 PhoneConstants.DataState state) { 2105 mNotifier.notifyDataConnection(this, reason, apnType, state); 2106 } 2107 notifyDataConnection(String reason, String apnType)2108 public void notifyDataConnection(String reason, String apnType) { 2109 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 2110 } 2111 notifyDataConnection(String reason)2112 public void notifyDataConnection(String reason) { 2113 String types[] = getActiveApnTypes(); 2114 for (String apnType : types) { 2115 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 2116 } 2117 } 2118 notifyOtaspChanged(int otaspMode)2119 public void notifyOtaspChanged(int otaspMode) { 2120 mNotifier.notifyOtaspChanged(this, otaspMode); 2121 } 2122 notifyVoiceActivationStateChanged(int state)2123 public void notifyVoiceActivationStateChanged(int state) { 2124 mNotifier.notifyVoiceActivationStateChanged(this, state); 2125 } 2126 notifyDataActivationStateChanged(int state)2127 public void notifyDataActivationStateChanged(int state) { 2128 mNotifier.notifyDataActivationStateChanged(this, state); 2129 } 2130 notifySignalStrength()2131 public void notifySignalStrength() { 2132 mNotifier.notifySignalStrength(this); 2133 } 2134 notifyCellInfo(List<CellInfo> cellInfo)2135 public void notifyCellInfo(List<CellInfo> cellInfo) { 2136 mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo)); 2137 } 2138 notifyVoLteServiceStateChanged(VoLteServiceState lteState)2139 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 2140 mNotifier.notifyVoLteServiceStateChanged(this, lteState); 2141 } 2142 2143 /** 2144 * @return true if a mobile originating emergency call is active 2145 */ isInEmergencyCall()2146 public boolean isInEmergencyCall() { 2147 return false; 2148 } 2149 2150 // This property is used to handle phone process crashes, and is the same for CDMA and IMS 2151 // phones getInEcmMode()2152 protected static boolean getInEcmMode() { 2153 return SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false); 2154 } 2155 2156 /** 2157 * @return {@code true} if we are in emergency call back mode. This is a period where the phone 2158 * should be using as little power as possible and be ready to receive an incoming call from the 2159 * emergency operator. 2160 * 2161 * This method is overridden for GSM phones to return false always 2162 */ isInEcm()2163 public boolean isInEcm() { 2164 return mIsPhoneInEcmState; 2165 } 2166 setIsInEcm(boolean isInEcm)2167 public void setIsInEcm(boolean isInEcm) { 2168 setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, String.valueOf(isInEcm)); 2169 mIsPhoneInEcmState = isInEcm; 2170 } 2171 getVideoState(Call call)2172 private static int getVideoState(Call call) { 2173 int videoState = VideoProfile.STATE_AUDIO_ONLY; 2174 Connection conn = call.getEarliestConnection(); 2175 if (conn != null) { 2176 videoState = conn.getVideoState(); 2177 } 2178 return videoState; 2179 } 2180 2181 /** 2182 * Determines if the specified call currently is or was at some point a video call, or if it is 2183 * a conference call. 2184 * @param call The call. 2185 * @return {@code true} if the call is or was a video call or is a conference call, 2186 * {@code false} otherwise. 2187 */ isVideoCallOrConference(Call call)2188 private boolean isVideoCallOrConference(Call call) { 2189 if (call.isMultiparty()) { 2190 return true; 2191 } 2192 2193 boolean isDowngradedVideoCall = false; 2194 if (call instanceof ImsPhoneCall) { 2195 ImsPhoneCall imsPhoneCall = (ImsPhoneCall) call; 2196 ImsCall imsCall = imsPhoneCall.getImsCall(); 2197 return imsCall != null && (imsCall.isVideoCall() || 2198 imsCall.wasVideoCall()); 2199 } 2200 return isDowngradedVideoCall; 2201 } 2202 2203 /** 2204 * @return {@code true} if an IMS video call or IMS conference is present, false otherwise. 2205 */ isImsVideoCallOrConferencePresent()2206 public boolean isImsVideoCallOrConferencePresent() { 2207 boolean isPresent = false; 2208 if (mImsPhone != null) { 2209 isPresent = isVideoCallOrConference(mImsPhone.getForegroundCall()) || 2210 isVideoCallOrConference(mImsPhone.getBackgroundCall()) || 2211 isVideoCallOrConference(mImsPhone.getRingingCall()); 2212 } 2213 Rlog.d(LOG_TAG, "isImsVideoCallOrConferencePresent: " + isPresent); 2214 return isPresent; 2215 } 2216 2217 /** 2218 * Return a numerical identifier for the phone radio interface. 2219 * @return PHONE_TYPE_XXX as defined above. 2220 */ getPhoneType()2221 public abstract int getPhoneType(); 2222 2223 /** 2224 * Returns unread voicemail count. This count is shown when the voicemail 2225 * notification is expanded.<p> 2226 */ getVoiceMessageCount()2227 public int getVoiceMessageCount(){ 2228 return mVmCount; 2229 } 2230 2231 /** sets the voice mail count of the phone and notifies listeners. */ setVoiceMessageCount(int countWaiting)2232 public void setVoiceMessageCount(int countWaiting) { 2233 mVmCount = countWaiting; 2234 int subId = getSubId(); 2235 if (SubscriptionManager.isValidSubscriptionId(subId)) { 2236 2237 Rlog.d(LOG_TAG, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting + 2238 " for mVmCountKey = " + VM_COUNT + subId + " in preferences."); 2239 2240 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 2241 SharedPreferences.Editor editor = sp.edit(); 2242 editor.putInt(VM_COUNT + subId, countWaiting); 2243 editor.apply(); 2244 } else { 2245 Rlog.e(LOG_TAG, "setVoiceMessageCount in sharedPreference: invalid subId " + subId); 2246 } 2247 // notify listeners of voice mail 2248 notifyMessageWaitingIndicator(); 2249 } 2250 2251 /** gets the voice mail count from preferences */ getStoredVoiceMessageCount()2252 protected int getStoredVoiceMessageCount() { 2253 int countVoiceMessages = 0; 2254 int subId = getSubId(); 2255 if (SubscriptionManager.isValidSubscriptionId(subId)) { 2256 int invalidCount = -2; //-1 is not really invalid. It is used for unknown number of vm 2257 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 2258 int countFromSP = sp.getInt(VM_COUNT + subId, invalidCount); 2259 if (countFromSP != invalidCount) { 2260 countVoiceMessages = countFromSP; 2261 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference for subId " + subId + 2262 "= " + countVoiceMessages); 2263 } else { 2264 // Check for old preference if count not found for current subId. This part of the 2265 // code is needed only when upgrading from M to N. 2266 String subscriberId = sp.getString(VM_ID, null); 2267 if (subscriberId != null) { 2268 String currentSubscriberId = getSubscriberId(); 2269 2270 if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) { 2271 // get voice mail count from preferences 2272 countVoiceMessages = sp.getInt(VM_COUNT, 0); 2273 setVoiceMessageCount(countVoiceMessages); 2274 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference = " + 2275 countVoiceMessages); 2276 } else { 2277 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: returning 0 as count for " + 2278 "matching subscriberId not found"); 2279 2280 } 2281 // get rid of old preferences. 2282 SharedPreferences.Editor editor = sp.edit(); 2283 editor.remove(VM_ID); 2284 editor.remove(VM_COUNT); 2285 editor.apply(); 2286 } 2287 } 2288 } else { 2289 Rlog.e(LOG_TAG, "getStoredVoiceMessageCount: invalid subId " + subId); 2290 } 2291 return countVoiceMessages; 2292 } 2293 2294 /** 2295 * send secret dialer codes to launch arbitrary activities. 2296 * an Intent is started with the android_secret_code://<code> URI. 2297 * 2298 * @param code stripped version of secret code without *#*# prefix and #*#* suffix 2299 */ sendDialerSpecialCode(String code)2300 public void sendDialerSpecialCode(String code) { 2301 if (!TextUtils.isEmpty(code)) { 2302 Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION, 2303 Uri.parse("android_secret_code://" + code)); 2304 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 2305 mContext.sendBroadcast(intent); 2306 } 2307 } 2308 2309 /** 2310 * Returns the CDMA ERI icon index to display 2311 */ getCdmaEriIconIndex()2312 public int getCdmaEriIconIndex() { 2313 return -1; 2314 } 2315 2316 /** 2317 * Returns the CDMA ERI icon mode, 2318 * 0 - ON 2319 * 1 - FLASHING 2320 */ getCdmaEriIconMode()2321 public int getCdmaEriIconMode() { 2322 return -1; 2323 } 2324 2325 /** 2326 * Returns the CDMA ERI text, 2327 */ getCdmaEriText()2328 public String getCdmaEriText() { 2329 return "GSM nw, no ERI"; 2330 } 2331 2332 /** 2333 * Retrieves the MIN for CDMA phones. 2334 */ getCdmaMin()2335 public String getCdmaMin() { 2336 return null; 2337 } 2338 2339 /** 2340 * Check if subscription data has been assigned to mMin 2341 * 2342 * return true if MIN info is ready; false otherwise. 2343 */ isMinInfoReady()2344 public boolean isMinInfoReady() { 2345 return false; 2346 } 2347 2348 /** 2349 * Retrieves PRL Version for CDMA phones 2350 */ getCdmaPrlVersion()2351 public String getCdmaPrlVersion(){ 2352 return null; 2353 } 2354 2355 /** 2356 * send burst DTMF tone, it can send the string as single character or multiple character 2357 * ignore if there is no active call or not valid digits string. 2358 * Valid digit means only includes characters ISO-LATIN characters 0-9, *, # 2359 * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character, 2360 * this api can send single character and multiple character, also, this api has response 2361 * back to caller. 2362 * 2363 * @param dtmfString is string representing the dialing digit(s) in the active call 2364 * @param on the DTMF ON length in milliseconds, or 0 for default 2365 * @param off the DTMF OFF length in milliseconds, or 0 for default 2366 * @param onComplete is the callback message when the action is processed by BP 2367 * 2368 */ sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)2369 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 2370 } 2371 2372 /** 2373 * Sets an event to be fired when the telephony system processes 2374 * a post-dial character on an outgoing call.<p> 2375 * 2376 * Messages of type <code>what</code> will be sent to <code>h</code>. 2377 * The <code>obj</code> field of these Message's will be instances of 2378 * <code>AsyncResult</code>. <code>Message.obj.result</code> will be 2379 * a Connection object.<p> 2380 * 2381 * Message.arg1 will be the post dial character being processed, 2382 * or 0 ('\0') if end of string.<p> 2383 * 2384 * If Connection.getPostDialState() == WAIT, 2385 * the application must call 2386 * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar() 2387 * Connection.proceedAfterWaitChar()} or 2388 * {@link com.android.internal.telephony.Connection#cancelPostDial() 2389 * Connection.cancelPostDial()} 2390 * for the telephony system to continue playing the post-dial 2391 * DTMF sequence.<p> 2392 * 2393 * If Connection.getPostDialState() == WILD, 2394 * the application must call 2395 * {@link com.android.internal.telephony.Connection#proceedAfterWildChar 2396 * Connection.proceedAfterWildChar()} 2397 * or 2398 * {@link com.android.internal.telephony.Connection#cancelPostDial() 2399 * Connection.cancelPostDial()} 2400 * for the telephony system to continue playing the 2401 * post-dial DTMF sequence.<p> 2402 * 2403 * Only one post dial character handler may be set. <p> 2404 * Calling this method with "h" equal to null unsets this handler.<p> 2405 */ setOnPostDialCharacter(Handler h, int what, Object obj)2406 public void setOnPostDialCharacter(Handler h, int what, Object obj) { 2407 mPostDialHandler = new Registrant(h, what, obj); 2408 } 2409 getPostDialHandler()2410 public Registrant getPostDialHandler() { 2411 return mPostDialHandler; 2412 } 2413 2414 /** 2415 * request to exit emergency call back mode 2416 * the caller should use setOnECMModeExitResponse 2417 * to receive the emergency callback mode exit response 2418 */ exitEmergencyCallbackMode()2419 public void exitEmergencyCallbackMode() { 2420 } 2421 2422 /** 2423 * Register for notifications when CDMA OTA Provision status change 2424 * 2425 * @param h Handler that receives the notification message. 2426 * @param what User-defined message code. 2427 * @param obj User object. 2428 */ registerForCdmaOtaStatusChange(Handler h, int what, Object obj)2429 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 2430 } 2431 2432 /** 2433 * Unregister for notifications when CDMA OTA Provision status change 2434 * @param h Handler to be removed from the registrant list. 2435 */ unregisterForCdmaOtaStatusChange(Handler h)2436 public void unregisterForCdmaOtaStatusChange(Handler h) { 2437 } 2438 2439 /** 2440 * Registration point for subscription info ready 2441 * @param h handler to notify 2442 * @param what what code of message when delivered 2443 * @param obj placed in Message.obj 2444 */ registerForSubscriptionInfoReady(Handler h, int what, Object obj)2445 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 2446 } 2447 2448 /** 2449 * Unregister for notifications for subscription info 2450 * @param h Handler to be removed from the registrant list. 2451 */ unregisterForSubscriptionInfoReady(Handler h)2452 public void unregisterForSubscriptionInfoReady(Handler h) { 2453 } 2454 2455 /** 2456 * Returns true if OTA Service Provisioning needs to be performed. 2457 */ needsOtaServiceProvisioning()2458 public boolean needsOtaServiceProvisioning() { 2459 return false; 2460 } 2461 2462 /** 2463 * this decides if the dial number is OTA(Over the air provision) number or not 2464 * @param dialStr is string representing the dialing digit(s) 2465 * @return true means the dialStr is OTA number, and false means the dialStr is not OTA number 2466 */ isOtaSpNumber(String dialStr)2467 public boolean isOtaSpNumber(String dialStr) { 2468 return false; 2469 } 2470 2471 /** 2472 * Register for notifications when CDMA call waiting comes 2473 * 2474 * @param h Handler that receives the notification message. 2475 * @param what User-defined message code. 2476 * @param obj User object. 2477 */ registerForCallWaiting(Handler h, int what, Object obj)2478 public void registerForCallWaiting(Handler h, int what, Object obj){ 2479 } 2480 2481 /** 2482 * Unegister for notifications when CDMA Call waiting comes 2483 * @param h Handler to be removed from the registrant list. 2484 */ unregisterForCallWaiting(Handler h)2485 public void unregisterForCallWaiting(Handler h){ 2486 } 2487 2488 /** 2489 * Registration point for Ecm timer reset 2490 * @param h handler to notify 2491 * @param what user-defined message code 2492 * @param obj placed in Message.obj 2493 */ registerForEcmTimerReset(Handler h, int what, Object obj)2494 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 2495 } 2496 2497 /** 2498 * Unregister for notification for Ecm timer reset 2499 * @param h Handler to be removed from the registrant list. 2500 */ unregisterForEcmTimerReset(Handler h)2501 public void unregisterForEcmTimerReset(Handler h) { 2502 } 2503 2504 /** 2505 * Register for signal information notifications from the network. 2506 * Message.obj will contain an AsyncResult. 2507 * AsyncResult.result will be a SuppServiceNotification instance. 2508 * 2509 * @param h Handler that receives the notification message. 2510 * @param what User-defined message code. 2511 * @param obj User object. 2512 */ registerForSignalInfo(Handler h, int what, Object obj)2513 public void registerForSignalInfo(Handler h, int what, Object obj) { 2514 mCi.registerForSignalInfo(h, what, obj); 2515 } 2516 2517 /** 2518 * Unregisters for signal information notifications. 2519 * Extraneous calls are tolerated silently 2520 * 2521 * @param h Handler to be removed from the registrant list. 2522 */ unregisterForSignalInfo(Handler h)2523 public void unregisterForSignalInfo(Handler h) { 2524 mCi.unregisterForSignalInfo(h); 2525 } 2526 2527 /** 2528 * Register for display information notifications from the network. 2529 * Message.obj will contain an AsyncResult. 2530 * AsyncResult.result will be a SuppServiceNotification instance. 2531 * 2532 * @param h Handler that receives the notification message. 2533 * @param what User-defined message code. 2534 * @param obj User object. 2535 */ registerForDisplayInfo(Handler h, int what, Object obj)2536 public void registerForDisplayInfo(Handler h, int what, Object obj) { 2537 mCi.registerForDisplayInfo(h, what, obj); 2538 } 2539 2540 /** 2541 * Unregisters for display information notifications. 2542 * Extraneous calls are tolerated silently 2543 * 2544 * @param h Handler to be removed from the registrant list. 2545 */ unregisterForDisplayInfo(Handler h)2546 public void unregisterForDisplayInfo(Handler h) { 2547 mCi.unregisterForDisplayInfo(h); 2548 } 2549 2550 /** 2551 * Register for CDMA number information record notification from the network. 2552 * Message.obj will contain an AsyncResult. 2553 * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec 2554 * instance. 2555 * 2556 * @param h Handler that receives the notification message. 2557 * @param what User-defined message code. 2558 * @param obj User object. 2559 */ registerForNumberInfo(Handler h, int what, Object obj)2560 public void registerForNumberInfo(Handler h, int what, Object obj) { 2561 mCi.registerForNumberInfo(h, what, obj); 2562 } 2563 2564 /** 2565 * Unregisters for number information record notifications. 2566 * Extraneous calls are tolerated silently 2567 * 2568 * @param h Handler to be removed from the registrant list. 2569 */ unregisterForNumberInfo(Handler h)2570 public void unregisterForNumberInfo(Handler h) { 2571 mCi.unregisterForNumberInfo(h); 2572 } 2573 2574 /** 2575 * Register for CDMA redirected number information record notification 2576 * from the network. 2577 * Message.obj will contain an AsyncResult. 2578 * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec 2579 * instance. 2580 * 2581 * @param h Handler that receives the notification message. 2582 * @param what User-defined message code. 2583 * @param obj User object. 2584 */ registerForRedirectedNumberInfo(Handler h, int what, Object obj)2585 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 2586 mCi.registerForRedirectedNumberInfo(h, what, obj); 2587 } 2588 2589 /** 2590 * Unregisters for redirected number information record notification. 2591 * Extraneous calls are tolerated silently 2592 * 2593 * @param h Handler to be removed from the registrant list. 2594 */ unregisterForRedirectedNumberInfo(Handler h)2595 public void unregisterForRedirectedNumberInfo(Handler h) { 2596 mCi.unregisterForRedirectedNumberInfo(h); 2597 } 2598 2599 /** 2600 * Register for CDMA line control information record notification 2601 * from the network. 2602 * Message.obj will contain an AsyncResult. 2603 * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec 2604 * instance. 2605 * 2606 * @param h Handler that receives the notification message. 2607 * @param what User-defined message code. 2608 * @param obj User object. 2609 */ registerForLineControlInfo(Handler h, int what, Object obj)2610 public void registerForLineControlInfo(Handler h, int what, Object obj) { 2611 mCi.registerForLineControlInfo(h, what, obj); 2612 } 2613 2614 /** 2615 * Unregisters for line control information notifications. 2616 * Extraneous calls are tolerated silently 2617 * 2618 * @param h Handler to be removed from the registrant list. 2619 */ unregisterForLineControlInfo(Handler h)2620 public void unregisterForLineControlInfo(Handler h) { 2621 mCi.unregisterForLineControlInfo(h); 2622 } 2623 2624 /** 2625 * Register for CDMA T53 CLIR information record notifications 2626 * from the network. 2627 * Message.obj will contain an AsyncResult. 2628 * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec 2629 * instance. 2630 * 2631 * @param h Handler that receives the notification message. 2632 * @param what User-defined message code. 2633 * @param obj User object. 2634 */ registerFoT53ClirlInfo(Handler h, int what, Object obj)2635 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 2636 mCi.registerFoT53ClirlInfo(h, what, obj); 2637 } 2638 2639 /** 2640 * Unregisters for T53 CLIR information record notification 2641 * Extraneous calls are tolerated silently 2642 * 2643 * @param h Handler to be removed from the registrant list. 2644 */ unregisterForT53ClirInfo(Handler h)2645 public void unregisterForT53ClirInfo(Handler h) { 2646 mCi.unregisterForT53ClirInfo(h); 2647 } 2648 2649 /** 2650 * Register for CDMA T53 audio control information record notifications 2651 * from the network. 2652 * Message.obj will contain an AsyncResult. 2653 * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec 2654 * instance. 2655 * 2656 * @param h Handler that receives the notification message. 2657 * @param what User-defined message code. 2658 * @param obj User object. 2659 */ registerForT53AudioControlInfo(Handler h, int what, Object obj)2660 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 2661 mCi.registerForT53AudioControlInfo(h, what, obj); 2662 } 2663 2664 /** 2665 * Unregisters for T53 audio control information record notifications. 2666 * Extraneous calls are tolerated silently 2667 * 2668 * @param h Handler to be removed from the registrant list. 2669 */ unregisterForT53AudioControlInfo(Handler h)2670 public void unregisterForT53AudioControlInfo(Handler h) { 2671 mCi.unregisterForT53AudioControlInfo(h); 2672 } 2673 2674 /** 2675 * registers for exit emergency call back mode request response 2676 * 2677 * @param h Handler that receives the notification message. 2678 * @param what User-defined message code. 2679 * @param obj User object. 2680 */ setOnEcbModeExitResponse(Handler h, int what, Object obj)2681 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 2682 } 2683 2684 /** 2685 * Unregisters for exit emergency call back mode request response 2686 * 2687 * @param h Handler to be removed from the registrant list. 2688 */ unsetOnEcbModeExitResponse(Handler h)2689 public void unsetOnEcbModeExitResponse(Handler h){ 2690 } 2691 2692 /** 2693 * Register for radio off or not available 2694 * 2695 * @param h Handler that receives the notification message. 2696 * @param what User-defined message code. 2697 * @param obj User object. 2698 */ registerForRadioOffOrNotAvailable(Handler h, int what, Object obj)2699 public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) { 2700 mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj); 2701 } 2702 2703 /** 2704 * Unregisters for radio off or not available 2705 * 2706 * @param h Handler to be removed from the registrant list. 2707 */ unregisterForRadioOffOrNotAvailable(Handler h)2708 public void unregisterForRadioOffOrNotAvailable(Handler h) { 2709 mRadioOffOrNotAvailableRegistrants.remove(h); 2710 } 2711 2712 /** 2713 * Returns an array of string identifiers for the APN types serviced by the 2714 * currently active. 2715 * @return The string array will always return at least one entry, Phone.APN_TYPE_DEFAULT. 2716 * TODO: Revisit if we always should return at least one entry. 2717 */ getActiveApnTypes()2718 public String[] getActiveApnTypes() { 2719 if (mDcTracker == null) { 2720 return null; 2721 } 2722 2723 return mDcTracker.getActiveApnTypes(); 2724 } 2725 2726 /** 2727 * Check if TETHER_DUN_APN setting or config_tether_apndata includes APN that matches 2728 * current operator. 2729 * @return true if there is a matching DUN APN. 2730 */ hasMatchedTetherApnSetting()2731 public boolean hasMatchedTetherApnSetting() { 2732 return mDcTracker.hasMatchedTetherApnSetting(); 2733 } 2734 2735 /** 2736 * Returns string for the active APN host. 2737 * @return type as a string or null if none. 2738 */ getActiveApnHost(String apnType)2739 public String getActiveApnHost(String apnType) { 2740 return mDcTracker.getActiveApnString(apnType); 2741 } 2742 2743 /** 2744 * Return the LinkProperties for the named apn or null if not available 2745 */ getLinkProperties(String apnType)2746 public LinkProperties getLinkProperties(String apnType) { 2747 return mDcTracker.getLinkProperties(apnType); 2748 } 2749 2750 /** 2751 * Return the NetworkCapabilities 2752 */ getNetworkCapabilities(String apnType)2753 public NetworkCapabilities getNetworkCapabilities(String apnType) { 2754 return mDcTracker.getNetworkCapabilities(apnType); 2755 } 2756 2757 /** 2758 * Report on whether data connectivity is allowed. 2759 */ isDataConnectivityPossible()2760 public boolean isDataConnectivityPossible() { 2761 return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT); 2762 } 2763 2764 /** 2765 * Report on whether data connectivity is allowed for an APN. 2766 */ isDataConnectivityPossible(String apnType)2767 public boolean isDataConnectivityPossible(String apnType) { 2768 return ((mDcTracker != null) && 2769 (mDcTracker.isDataPossible(apnType))); 2770 } 2771 2772 2773 /** 2774 * Action set from carrier signalling broadcast receivers to enable/disable metered apns. 2775 */ carrierActionSetMeteredApnsEnabled(boolean enabled)2776 public void carrierActionSetMeteredApnsEnabled(boolean enabled) { 2777 mCarrierActionAgent.carrierActionSetMeteredApnsEnabled(enabled); 2778 } 2779 2780 /** 2781 * Action set from carrier signalling broadcast receivers to enable/disable radio 2782 */ carrierActionSetRadioEnabled(boolean enabled)2783 public void carrierActionSetRadioEnabled(boolean enabled) { 2784 mCarrierActionAgent.carrierActionSetRadioEnabled(enabled); 2785 } 2786 2787 /** 2788 * Notify registrants of a new ringing Connection. 2789 * Subclasses of Phone probably want to replace this with a 2790 * version scoped to their packages 2791 */ notifyNewRingingConnectionP(Connection cn)2792 public void notifyNewRingingConnectionP(Connection cn) { 2793 if (!mIsVoiceCapable) 2794 return; 2795 AsyncResult ar = new AsyncResult(null, cn, null); 2796 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 2797 } 2798 2799 /** 2800 * Notify registrants of a new unknown connection. 2801 */ notifyUnknownConnectionP(Connection cn)2802 public void notifyUnknownConnectionP(Connection cn) { 2803 mUnknownConnectionRegistrants.notifyResult(cn); 2804 } 2805 2806 /** 2807 * Notify registrants if phone is video capable. 2808 */ notifyForVideoCapabilityChanged(boolean isVideoCallCapable)2809 public void notifyForVideoCapabilityChanged(boolean isVideoCallCapable) { 2810 // Cache the current video capability so that we don't lose the information. 2811 mIsVideoCapable = isVideoCallCapable; 2812 2813 AsyncResult ar = new AsyncResult(null, isVideoCallCapable, null); 2814 mVideoCapabilityChangedRegistrants.notifyRegistrants(ar); 2815 } 2816 2817 /** 2818 * Notify registrants of a RING event. 2819 */ notifyIncomingRing()2820 private void notifyIncomingRing() { 2821 if (!mIsVoiceCapable) 2822 return; 2823 AsyncResult ar = new AsyncResult(null, this, null); 2824 mIncomingRingRegistrants.notifyRegistrants(ar); 2825 } 2826 2827 /** 2828 * Send the incoming call Ring notification if conditions are right. 2829 */ sendIncomingCallRingNotification(int token)2830 private void sendIncomingCallRingNotification(int token) { 2831 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 2832 (token == mCallRingContinueToken)) { 2833 Rlog.d(LOG_TAG, "Sending notifyIncomingRing"); 2834 notifyIncomingRing(); 2835 sendMessageDelayed( 2836 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 2837 } else { 2838 Rlog.d(LOG_TAG, "Ignoring ring notification request," 2839 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 2840 + " token=" + token 2841 + " mCallRingContinueToken=" + mCallRingContinueToken 2842 + " mIsVoiceCapable=" + mIsVoiceCapable); 2843 } 2844 } 2845 2846 /** 2847 * TODO: Adding a function for each property is not good. 2848 * A fucntion of type getPhoneProp(propType) where propType is an 2849 * enum of GSM+CDMA+LTE props would be a better approach. 2850 * 2851 * Get "Restriction of menu options for manual PLMN selection" bit 2852 * status from EF_CSP data, this belongs to "Value Added Services Group". 2853 * @return true if this bit is set or EF_CSP data is unavailable, 2854 * false otherwise 2855 */ isCspPlmnEnabled()2856 public boolean isCspPlmnEnabled() { 2857 return false; 2858 } 2859 2860 /** 2861 * Return an interface to retrieve the ISIM records for IMS, if available. 2862 * @return the interface to retrieve the ISIM records, or null if not supported 2863 */ getIsimRecords()2864 public IsimRecords getIsimRecords() { 2865 Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 2866 return null; 2867 } 2868 2869 /** 2870 * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to 2871 * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns 2872 * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones. 2873 */ getMsisdn()2874 public String getMsisdn() { 2875 return null; 2876 } 2877 2878 /** 2879 * Get the current for the default apn DataState. No change notification 2880 * exists at this interface -- use 2881 * {@link android.telephony.PhoneStateListener} instead. 2882 */ getDataConnectionState()2883 public PhoneConstants.DataState getDataConnectionState() { 2884 return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT); 2885 } 2886 notifyCallForwardingIndicator()2887 public void notifyCallForwardingIndicator() { 2888 } 2889 notifyDataConnectionFailed(String reason, String apnType)2890 public void notifyDataConnectionFailed(String reason, String apnType) { 2891 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 2892 } 2893 notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause)2894 public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, 2895 String failCause) { 2896 mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause); 2897 } 2898 2899 /** 2900 * Return if the current radio is LTE on CDMA. This 2901 * is a tri-state return value as for a period of time 2902 * the mode may be unknown. 2903 * 2904 * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE} 2905 * or {@link PhoneConstants#LTE_ON_CDMA_TRUE} 2906 */ getLteOnCdmaMode()2907 public int getLteOnCdmaMode() { 2908 return mCi.getLteOnCdmaMode(); 2909 } 2910 2911 /** 2912 * Sets the SIM voice message waiting indicator records. 2913 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 2914 * @param countWaiting The number of messages waiting, if known. Use 2915 * -1 to indicate that an unknown number of 2916 * messages are waiting 2917 */ setVoiceMessageWaiting(int line, int countWaiting)2918 public void setVoiceMessageWaiting(int line, int countWaiting) { 2919 // This function should be overridden by class GsmCdmaPhone. 2920 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone."); 2921 } 2922 2923 /** 2924 * Gets the USIM service table from the UICC, if present and available. 2925 * @return an interface to the UsimServiceTable record, or null if not available 2926 */ getUsimServiceTable()2927 public UsimServiceTable getUsimServiceTable() { 2928 IccRecords r = mIccRecords.get(); 2929 return (r != null) ? r.getUsimServiceTable() : null; 2930 } 2931 2932 /** 2933 * Gets the Uicc card corresponding to this phone. 2934 * @return the UiccCard object corresponding to the phone ID. 2935 */ getUiccCard()2936 public UiccCard getUiccCard() { 2937 return mUiccController.getUiccCard(mPhoneId); 2938 } 2939 2940 /** 2941 * Get P-CSCF address from PCO after data connection is established or modified. 2942 * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN 2943 */ getPcscfAddress(String apnType)2944 public String[] getPcscfAddress(String apnType) { 2945 return mDcTracker.getPcscfAddress(apnType); 2946 } 2947 2948 /** 2949 * Set IMS registration state 2950 */ setImsRegistrationState(boolean registered)2951 public void setImsRegistrationState(boolean registered) { 2952 } 2953 2954 /** 2955 * Return an instance of a IMS phone 2956 */ getImsPhone()2957 public Phone getImsPhone() { 2958 return mImsPhone; 2959 } 2960 2961 /** 2962 * Return if UT capability of ImsPhone is enabled or not 2963 */ isUtEnabled()2964 public boolean isUtEnabled() { 2965 if (mImsPhone != null) { 2966 return mImsPhone.isUtEnabled(); 2967 } 2968 return false; 2969 } 2970 dispose()2971 public void dispose() { 2972 } 2973 updateImsPhone()2974 private void updateImsPhone() { 2975 Rlog.d(LOG_TAG, "updateImsPhone" 2976 + " mImsServiceReady=" + mImsServiceReady); 2977 2978 if (mImsServiceReady && (mImsPhone == null)) { 2979 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this); 2980 CallManager.getInstance().registerPhone(mImsPhone); 2981 mImsPhone.registerForSilentRedial( 2982 this, EVENT_INITIATE_SILENT_REDIAL, null); 2983 } else if (!mImsServiceReady && (mImsPhone != null)) { 2984 CallManager.getInstance().unregisterPhone(mImsPhone); 2985 mImsPhone.unregisterForSilentRedial(this); 2986 2987 mImsPhone.dispose(); 2988 // Potential GC issue if someone keeps a reference to ImsPhone. 2989 // However: this change will make sure that such a reference does 2990 // not access functions through NULL pointer. 2991 //mImsPhone.removeReferences(); 2992 mImsPhone = null; 2993 } 2994 } 2995 2996 /** 2997 * Dials a number. 2998 * 2999 * @param dialString The number to dial. 3000 * @param uusInfo The UUSInfo. 3001 * @param videoState The video state for the call. 3002 * @param intentExtras Extras from the original CALL intent. 3003 * @return The Connection. 3004 * @throws CallStateException 3005 */ dialInternal( String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras)3006 protected Connection dialInternal( 3007 String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras) 3008 throws CallStateException { 3009 // dialInternal shall be overriden by GsmCdmaPhone 3010 return null; 3011 } 3012 3013 /* 3014 * Returns the subscription id. 3015 */ getSubId()3016 public int getSubId() { 3017 return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId); 3018 } 3019 3020 /** 3021 * Returns the phone id. 3022 */ getPhoneId()3023 public int getPhoneId() { 3024 return mPhoneId; 3025 } 3026 3027 /** 3028 * Return the service state of mImsPhone if it is STATE_IN_SERVICE 3029 * otherwise return the current voice service state 3030 */ getVoicePhoneServiceState()3031 public int getVoicePhoneServiceState() { 3032 Phone imsPhone = mImsPhone; 3033 if (imsPhone != null 3034 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) { 3035 return ServiceState.STATE_IN_SERVICE; 3036 } 3037 return getServiceState().getState(); 3038 } 3039 3040 /** 3041 * Override the service provider name and the operator name for the current ICCID. 3042 */ setOperatorBrandOverride(String brand)3043 public boolean setOperatorBrandOverride(String brand) { 3044 return false; 3045 } 3046 3047 /** 3048 * Override the roaming indicator for the current ICCID. 3049 */ setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)3050 public boolean setRoamingOverride(List<String> gsmRoamingList, 3051 List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 3052 List<String> cdmaNonRoamingList) { 3053 String iccId = getIccSerialNumber(); 3054 if (TextUtils.isEmpty(iccId)) { 3055 return false; 3056 } 3057 3058 setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3059 setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3060 setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3061 setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 3062 3063 // Refresh. 3064 ServiceStateTracker tracker = getServiceStateTracker(); 3065 if (tracker != null) { 3066 tracker.pollState(); 3067 } 3068 return true; 3069 } 3070 setRoamingOverrideHelper(List<String> list, String prefix, String iccId)3071 private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) { 3072 SharedPreferences.Editor spEditor = 3073 PreferenceManager.getDefaultSharedPreferences(mContext).edit(); 3074 String key = prefix + iccId; 3075 if (list == null || list.isEmpty()) { 3076 spEditor.remove(key).commit(); 3077 } else { 3078 spEditor.putStringSet(key, new HashSet<String>(list)).commit(); 3079 } 3080 } 3081 isMccMncMarkedAsRoaming(String mccMnc)3082 public boolean isMccMncMarkedAsRoaming(String mccMnc) { 3083 return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 3084 } 3085 isMccMncMarkedAsNonRoaming(String mccMnc)3086 public boolean isMccMncMarkedAsNonRoaming(String mccMnc) { 3087 return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 3088 } 3089 isSidMarkedAsRoaming(int SID)3090 public boolean isSidMarkedAsRoaming(int SID) { 3091 return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX, 3092 Integer.toString(SID)); 3093 } 3094 isSidMarkedAsNonRoaming(int SID)3095 public boolean isSidMarkedAsNonRoaming(int SID) { 3096 return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, 3097 Integer.toString(SID)); 3098 } 3099 3100 /** 3101 * Query the IMS Registration Status. 3102 * 3103 * @return true if IMS is Registered 3104 */ isImsRegistered()3105 public boolean isImsRegistered() { 3106 Phone imsPhone = mImsPhone; 3107 boolean isImsRegistered = false; 3108 if (imsPhone != null) { 3109 isImsRegistered = imsPhone.isImsRegistered(); 3110 } else { 3111 ServiceStateTracker sst = getServiceStateTracker(); 3112 if (sst != null) { 3113 isImsRegistered = sst.isImsRegistered(); 3114 } 3115 } 3116 Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered); 3117 return isImsRegistered; 3118 } 3119 3120 /** 3121 * Get Wifi Calling Feature Availability 3122 */ isWifiCallingEnabled()3123 public boolean isWifiCallingEnabled() { 3124 Phone imsPhone = mImsPhone; 3125 boolean isWifiCallingEnabled = false; 3126 if (imsPhone != null) { 3127 isWifiCallingEnabled = imsPhone.isWifiCallingEnabled(); 3128 } 3129 Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled); 3130 return isWifiCallingEnabled; 3131 } 3132 3133 /** 3134 * Get Volte Feature Availability 3135 */ isVolteEnabled()3136 public boolean isVolteEnabled() { 3137 Phone imsPhone = mImsPhone; 3138 boolean isVolteEnabled = false; 3139 if (imsPhone != null) { 3140 isVolteEnabled = imsPhone.isVolteEnabled(); 3141 } 3142 Rlog.d(LOG_TAG, "isImsRegistered =" + isVolteEnabled); 3143 return isVolteEnabled; 3144 } 3145 getRoamingOverrideHelper(String prefix, String key)3146 private boolean getRoamingOverrideHelper(String prefix, String key) { 3147 String iccId = getIccSerialNumber(); 3148 if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) { 3149 return false; 3150 } 3151 3152 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 3153 Set<String> value = sp.getStringSet(prefix + iccId, null); 3154 if (value == null) { 3155 return false; 3156 } 3157 return value.contains(key); 3158 } 3159 3160 /** 3161 * Is Radio Present on the device and is it accessible 3162 */ isRadioAvailable()3163 public boolean isRadioAvailable() { 3164 return mCi.getRadioState().isAvailable(); 3165 } 3166 3167 /** 3168 * Is Radio turned on 3169 */ isRadioOn()3170 public boolean isRadioOn() { 3171 return mCi.getRadioState().isOn(); 3172 } 3173 3174 /** 3175 * shutdown Radio gracefully 3176 */ shutdownRadio()3177 public void shutdownRadio() { 3178 getServiceStateTracker().requestShutdown(); 3179 } 3180 3181 /** 3182 * Return true if the device is shutting down. 3183 */ isShuttingDown()3184 public boolean isShuttingDown() { 3185 return getServiceStateTracker().isDeviceShuttingDown(); 3186 } 3187 3188 /** 3189 * Set phone radio capability 3190 * 3191 * @param rc the phone radio capability defined in 3192 * RadioCapability. It's a input object used to transfer parameter to logic modem 3193 * @param response Callback message. 3194 */ setRadioCapability(RadioCapability rc, Message response)3195 public void setRadioCapability(RadioCapability rc, Message response) { 3196 mCi.setRadioCapability(rc, response); 3197 } 3198 3199 /** 3200 * Get phone radio access family 3201 * 3202 * @return a bit mask to identify the radio access family. 3203 */ getRadioAccessFamily()3204 public int getRadioAccessFamily() { 3205 final RadioCapability rc = getRadioCapability(); 3206 return (rc == null ? RadioAccessFamily.RAF_UNKNOWN : rc.getRadioAccessFamily()); 3207 } 3208 3209 /** 3210 * Get the associated data modems Id. 3211 * 3212 * @return a String containing the id of the data modem 3213 */ getModemUuId()3214 public String getModemUuId() { 3215 final RadioCapability rc = getRadioCapability(); 3216 return (rc == null ? "" : rc.getLogicalModemUuid()); 3217 } 3218 3219 /** 3220 * Get phone radio capability 3221 * 3222 * @return the capability of the radio defined in RadioCapability 3223 */ getRadioCapability()3224 public RadioCapability getRadioCapability() { 3225 return mRadioCapability.get(); 3226 } 3227 3228 /** 3229 * The RadioCapability has changed. This comes up from the RIL and is called when radios first 3230 * become available or after a capability switch. The flow is we use setRadioCapability to 3231 * request a change with the RIL and get an UNSOL response with the new data which gets set 3232 * here. 3233 * 3234 * @param rc the phone radio capability currently in effect for this phone. 3235 */ radioCapabilityUpdated(RadioCapability rc)3236 public void radioCapabilityUpdated(RadioCapability rc) { 3237 // Called when radios first become available or after a capability switch 3238 // Update the cached value 3239 mRadioCapability.set(rc); 3240 3241 if (SubscriptionManager.isValidSubscriptionId(getSubId())) { 3242 sendSubscriptionSettings(true); 3243 } 3244 } 3245 sendSubscriptionSettings(boolean restoreNetworkSelection)3246 public void sendSubscriptionSettings(boolean restoreNetworkSelection) { 3247 // Send settings down 3248 int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId()); 3249 setPreferredNetworkType(type, null); 3250 3251 if (restoreNetworkSelection) { 3252 restoreSavedNetworkSelection(null); 3253 } 3254 } 3255 setPreferredNetworkTypeIfSimLoaded()3256 protected void setPreferredNetworkTypeIfSimLoaded() { 3257 int subId = getSubId(); 3258 if (SubscriptionManager.isValidSubscriptionId(subId)) { 3259 int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId()); 3260 setPreferredNetworkType(type, null); 3261 } 3262 } 3263 3264 /** 3265 * Registers the handler when phone radio capability is changed. 3266 * 3267 * @param h Handler for notification message. 3268 * @param what User-defined message code. 3269 * @param obj User object. 3270 */ registerForRadioCapabilityChanged(Handler h, int what, Object obj)3271 public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) { 3272 mCi.registerForRadioCapabilityChanged(h, what, obj); 3273 } 3274 3275 /** 3276 * Unregister for notifications when phone radio type and access technology is changed. 3277 * 3278 * @param h Handler to be removed from the registrant list. 3279 */ unregisterForRadioCapabilityChanged(Handler h)3280 public void unregisterForRadioCapabilityChanged(Handler h) { 3281 mCi.unregisterForRadioCapabilityChanged(this); 3282 } 3283 3284 /** 3285 * Determines if IMS is enabled for call. 3286 * 3287 * @return {@code true} if IMS calling is enabled. 3288 */ isImsUseEnabled()3289 public boolean isImsUseEnabled() { 3290 boolean imsUseEnabled = 3291 ((ImsManager.isVolteEnabledByPlatform(mContext) && 3292 ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext)) || 3293 (ImsManager.isWfcEnabledByPlatform(mContext) && 3294 ImsManager.isWfcEnabledByUser(mContext)) && 3295 ImsManager.isNonTtyOrTtyOnVolteEnabled(mContext)); 3296 return imsUseEnabled; 3297 } 3298 3299 /** 3300 * Determines if video calling is enabled for the phone. 3301 * 3302 * @return {@code true} if video calling is enabled, {@code false} otherwise. 3303 */ isVideoEnabled()3304 public boolean isVideoEnabled() { 3305 Phone imsPhone = mImsPhone; 3306 if ((imsPhone != null) 3307 && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)) { 3308 return imsPhone.isVideoEnabled(); 3309 } 3310 return false; 3311 } 3312 3313 /** 3314 * Returns the status of Link Capacity Estimation (LCE) service. 3315 */ getLceStatus()3316 public int getLceStatus() { 3317 return mLceStatus; 3318 } 3319 3320 /** 3321 * Returns the modem activity information 3322 */ getModemActivityInfo(Message response)3323 public void getModemActivityInfo(Message response) { 3324 mCi.getModemActivityInfo(response); 3325 } 3326 3327 /** 3328 * Starts LCE service after radio becomes available. 3329 * LCE service state may get destroyed on the modem when radio becomes unavailable. 3330 */ startLceAfterRadioIsAvailable()3331 public void startLceAfterRadioIsAvailable() { 3332 mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE, 3333 obtainMessage(EVENT_CONFIG_LCE)); 3334 } 3335 3336 /** 3337 * Set allowed carriers 3338 */ setAllowedCarriers(List<CarrierIdentifier> carriers, Message response)3339 public void setAllowedCarriers(List<CarrierIdentifier> carriers, Message response) { 3340 mCi.setAllowedCarriers(carriers, response); 3341 } 3342 3343 /** 3344 * Get allowed carriers 3345 */ getAllowedCarriers(Message response)3346 public void getAllowedCarriers(Message response) { 3347 mCi.getAllowedCarriers(response); 3348 } 3349 3350 /** 3351 * Returns the locale based on the carrier properties (such as {@code ro.carrier}) and 3352 * SIM preferences. 3353 */ getLocaleFromSimAndCarrierPrefs()3354 public Locale getLocaleFromSimAndCarrierPrefs() { 3355 final IccRecords records = mIccRecords.get(); 3356 if (records != null && records.getSimLanguage() != null) { 3357 return new Locale(records.getSimLanguage()); 3358 } 3359 3360 return getLocaleFromCarrierProperties(mContext); 3361 } 3362 updateDataConnectionTracker()3363 public void updateDataConnectionTracker() { 3364 mDcTracker.update(); 3365 } 3366 setInternalDataEnabled(boolean enable, Message onCompleteMsg)3367 public void setInternalDataEnabled(boolean enable, Message onCompleteMsg) { 3368 mDcTracker.setInternalDataEnabled(enable, onCompleteMsg); 3369 } 3370 updateCurrentCarrierInProvider()3371 public boolean updateCurrentCarrierInProvider() { 3372 return false; 3373 } 3374 registerForAllDataDisconnected(Handler h, int what, Object obj)3375 public void registerForAllDataDisconnected(Handler h, int what, Object obj) { 3376 mDcTracker.registerForAllDataDisconnected(h, what, obj); 3377 } 3378 unregisterForAllDataDisconnected(Handler h)3379 public void unregisterForAllDataDisconnected(Handler h) { 3380 mDcTracker.unregisterForAllDataDisconnected(h); 3381 } 3382 registerForDataEnabledChanged(Handler h, int what, Object obj)3383 public void registerForDataEnabledChanged(Handler h, int what, Object obj) { 3384 mDcTracker.registerForDataEnabledChanged(h, what, obj); 3385 } 3386 unregisterForDataEnabledChanged(Handler h)3387 public void unregisterForDataEnabledChanged(Handler h) { 3388 mDcTracker.unregisterForDataEnabledChanged(h); 3389 } 3390 getIccSmsInterfaceManager()3391 public IccSmsInterfaceManager getIccSmsInterfaceManager(){ 3392 return null; 3393 } 3394 isMatchGid(String gid)3395 protected boolean isMatchGid(String gid) { 3396 String gid1 = getGroupIdLevel1(); 3397 int gidLength = gid.length(); 3398 if (!TextUtils.isEmpty(gid1) && (gid1.length() >= gidLength) 3399 && gid1.substring(0, gidLength).equalsIgnoreCase(gid)) { 3400 return true; 3401 } 3402 return false; 3403 } 3404 checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, Context context)3405 public static void checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, Context context) 3406 throws CallStateException { 3407 if (imsPhone == null || !imsPhone.isWifiCallingEnabled()) { 3408 boolean wfcWiFiOnly = (ImsManager.isWfcEnabledByPlatform(context) && 3409 ImsManager.isWfcEnabledByUser(context) && 3410 (ImsManager.getWfcMode(context) == 3411 ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY)); 3412 if (wfcWiFiOnly) { 3413 throw new CallStateException( 3414 CallStateException.ERROR_DISCONNECTED, 3415 "WFC Wi-Fi Only Mode: IMS not registered"); 3416 } 3417 } 3418 } 3419 startRingbackTone()3420 public void startRingbackTone() { 3421 } 3422 stopRingbackTone()3423 public void stopRingbackTone() { 3424 } 3425 callEndCleanupHandOverCallIfAny()3426 public void callEndCleanupHandOverCallIfAny() { 3427 } 3428 cancelUSSD()3429 public void cancelUSSD() { 3430 } 3431 3432 /** 3433 * Set boolean broadcastEmergencyCallStateChanges 3434 */ setBroadcastEmergencyCallStateChanges(boolean broadcast)3435 public abstract void setBroadcastEmergencyCallStateChanges(boolean broadcast); 3436 sendEmergencyCallStateChange(boolean callActive)3437 public abstract void sendEmergencyCallStateChange(boolean callActive); 3438 3439 /** 3440 * This function returns the parent phone of the current phone. It is applicable 3441 * only for IMS phone (function is overridden by ImsPhone). For others the phone 3442 * object itself is returned. 3443 * @return 3444 */ getDefaultPhone()3445 public Phone getDefaultPhone() { 3446 return this; 3447 } 3448 getVtDataUsage()3449 public long getVtDataUsage() { 3450 if (mImsPhone == null) return 0; 3451 return mImsPhone.getVtDataUsage(); 3452 } 3453 3454 /** 3455 * Policy control of data connection. Usually used when we hit data limit. 3456 * @param enabled True if enabling the data, otherwise disabling. 3457 */ setPolicyDataEnabled(boolean enabled)3458 public void setPolicyDataEnabled(boolean enabled) { 3459 mDcTracker.setPolicyDataEnabled(enabled); 3460 } 3461 3462 /** 3463 * SIP URIs aliased to the current subscriber given by the IMS implementation. 3464 * Applicable only on IMS; used in absence of line1number. 3465 * @return array of SIP URIs aliased to the current subscriber 3466 */ getCurrentSubscriberUris()3467 public Uri[] getCurrentSubscriberUris() { 3468 return null; 3469 } 3470 getAppSmsManager()3471 public AppSmsManager getAppSmsManager() { 3472 return mAppSmsManager; 3473 } 3474 3475 /** 3476 * Set SIM card power state. Request is equivalent to inserting or removing the card. 3477 * @param powerUp True if powering up the SIM, otherwise powering down 3478 **/ setSimPowerState(boolean powerUp)3479 public void setSimPowerState(boolean powerUp) { 3480 mCi.setSimCardPower(powerUp, null); 3481 } 3482 dump(FileDescriptor fd, PrintWriter pw, String[] args)3483 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3484 pw.println("Phone: subId=" + getSubId()); 3485 pw.println(" mPhoneId=" + mPhoneId); 3486 pw.println(" mCi=" + mCi); 3487 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 3488 pw.println(" mDcTracker=" + mDcTracker); 3489 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 3490 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 3491 pw.println(" mCallRingDelay=" + mCallRingDelay); 3492 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 3493 pw.println(" mIccRecords=" + mIccRecords.get()); 3494 pw.println(" mUiccApplication=" + mUiccApplication.get()); 3495 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 3496 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 3497 pw.flush(); 3498 pw.println(" mLooper=" + mLooper); 3499 pw.println(" mContext=" + mContext); 3500 pw.println(" mNotifier=" + mNotifier); 3501 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 3502 pw.println(" mUnitTestMode=" + mUnitTestMode); 3503 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 3504 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 3505 pw.println(" getState()=" + getState()); 3506 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 3507 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 3508 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 3509 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 3510 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 3511 pw.flush(); 3512 pw.println(" isInEcm()=" + isInEcm()); 3513 pw.println(" getPhoneName()=" + getPhoneName()); 3514 pw.println(" getPhoneType()=" + getPhoneType()); 3515 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 3516 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 3517 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 3518 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 3519 pw.flush(); 3520 pw.println("++++++++++++++++++++++++++++++++"); 3521 3522 if (mImsPhone != null) { 3523 try { 3524 mImsPhone.dump(fd, pw, args); 3525 } catch (Exception e) { 3526 e.printStackTrace(); 3527 } 3528 3529 pw.flush(); 3530 pw.println("++++++++++++++++++++++++++++++++"); 3531 } 3532 3533 if (mDcTracker != null) { 3534 try { 3535 mDcTracker.dump(fd, pw, args); 3536 } catch (Exception e) { 3537 e.printStackTrace(); 3538 } 3539 3540 pw.flush(); 3541 pw.println("++++++++++++++++++++++++++++++++"); 3542 } 3543 3544 if (getServiceStateTracker() != null) { 3545 try { 3546 getServiceStateTracker().dump(fd, pw, args); 3547 } catch (Exception e) { 3548 e.printStackTrace(); 3549 } 3550 3551 pw.flush(); 3552 pw.println("++++++++++++++++++++++++++++++++"); 3553 } 3554 3555 if (mCarrierActionAgent != null) { 3556 try { 3557 mCarrierActionAgent.dump(fd, pw, args); 3558 } catch (Exception e) { 3559 e.printStackTrace(); 3560 } 3561 3562 pw.flush(); 3563 pw.println("++++++++++++++++++++++++++++++++"); 3564 } 3565 3566 if (mCarrierSignalAgent != null) { 3567 try { 3568 mCarrierSignalAgent.dump(fd, pw, args); 3569 } catch (Exception e) { 3570 e.printStackTrace(); 3571 } 3572 3573 pw.flush(); 3574 pw.println("++++++++++++++++++++++++++++++++"); 3575 } 3576 3577 if (getCallTracker() != null) { 3578 try { 3579 getCallTracker().dump(fd, pw, args); 3580 } catch (Exception e) { 3581 e.printStackTrace(); 3582 } 3583 3584 pw.flush(); 3585 pw.println("++++++++++++++++++++++++++++++++"); 3586 } 3587 3588 if (mSimActivationTracker != null) { 3589 try { 3590 mSimActivationTracker.dump(fd, pw, args); 3591 } catch (Exception e) { 3592 e.printStackTrace(); 3593 } 3594 3595 pw.flush(); 3596 pw.println("++++++++++++++++++++++++++++++++"); 3597 } 3598 3599 if (mCi != null && mCi instanceof RIL) { 3600 try { 3601 ((RIL)mCi).dump(fd, pw, args); 3602 } catch (Exception e) { 3603 e.printStackTrace(); 3604 } 3605 3606 pw.flush(); 3607 pw.println("++++++++++++++++++++++++++++++++"); 3608 } 3609 } 3610 } 3611