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