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