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