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