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