1 /* 2 * Copyright (C) 2007 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.wifi.WifiManager; 27 import android.os.AsyncResult; 28 import android.os.Build; 29 import android.os.Bundle; 30 import android.os.Handler; 31 import android.os.Looper; 32 import android.os.Message; 33 import android.os.Registrant; 34 import android.os.RegistrantList; 35 import android.os.SystemProperties; 36 import android.preference.PreferenceManager; 37 import android.provider.Settings; 38 import android.telecom.VideoProfile; 39 import android.telephony.CellIdentityCdma; 40 import android.telephony.CellInfo; 41 import android.telephony.CellInfoCdma; 42 import android.telephony.DataConnectionRealTimeInfo; 43 import android.telephony.RadioAccessFamily; 44 import android.telephony.Rlog; 45 import android.telephony.ServiceState; 46 import android.telephony.SignalStrength; 47 import android.telephony.SubscriptionManager; 48 import android.telephony.VoLteServiceState; 49 import android.telephony.ModemActivityInfo; 50 import android.text.TextUtils; 51 52 import com.android.ims.ImsManager; 53 import com.android.internal.R; 54 import com.android.internal.telephony.dataconnection.DcTrackerBase; 55 import com.android.internal.telephony.imsphone.ImsPhone; 56 import com.android.internal.telephony.imsphone.ImsPhoneConnection; 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 PhoneBase extends Handler implements Phone { 89 private static final String LOG_TAG = "PhoneBase"; 90 91 private boolean mImsIntentReceiverRegistered = false; 92 private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() { 93 @Override 94 public void onReceive(Context context, Intent intent) { 95 Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction()); 96 if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) { 97 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID, 98 SubscriptionManager.INVALID_PHONE_INDEX); 99 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId); 100 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX || 101 extraPhoneId != getPhoneId()) { 102 return; 103 } 104 } 105 106 synchronized (PhoneProxy.lockForRadioTechnologyChange) { 107 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) { 108 mImsServiceReady = true; 109 updateImsPhone(); 110 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) { 111 mImsServiceReady = false; 112 updateImsPhone(); 113 } 114 } 115 } 116 }; 117 118 // Key used to read and write the saved network selection numeric value 119 public static final String NETWORK_SELECTION_KEY = "network_selection_key"; 120 // Key used to read and write the saved network selection operator name 121 public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key"; 122 // Key used to read and write the saved network selection operator short name 123 public static final String NETWORK_SELECTION_SHORT_KEY = "network_selection_short_key"; 124 125 126 // Key used to read/write "disable data connection on boot" pref (used for testing) 127 public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key"; 128 129 /* Event Constants */ 130 protected static final int EVENT_RADIO_AVAILABLE = 1; 131 /** Supplementary Service Notification received. */ 132 protected static final int EVENT_SSN = 2; 133 protected static final int EVENT_SIM_RECORDS_LOADED = 3; 134 protected static final int EVENT_MMI_DONE = 4; 135 protected static final int EVENT_RADIO_ON = 5; 136 protected static final int EVENT_GET_BASEBAND_VERSION_DONE = 6; 137 protected static final int EVENT_USSD = 7; 138 protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8; 139 protected static final int EVENT_GET_IMEI_DONE = 9; 140 protected static final int EVENT_GET_IMEISV_DONE = 10; 141 protected static final int EVENT_GET_SIM_STATUS_DONE = 11; 142 protected static final int EVENT_SET_CALL_FORWARD_DONE = 12; 143 protected static final int EVENT_GET_CALL_FORWARD_DONE = 13; 144 protected static final int EVENT_CALL_RING = 14; 145 protected static final int EVENT_CALL_RING_CONTINUE = 15; 146 147 // Used to intercept the carrier selection calls so that 148 // we can save the values. 149 protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 16; 150 protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17; 151 protected static final int EVENT_SET_CLIR_COMPLETE = 18; 152 protected static final int EVENT_REGISTERED_TO_NETWORK = 19; 153 protected static final int EVENT_SET_VM_NUMBER_DONE = 20; 154 // Events for CDMA support 155 protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 21; 156 protected static final int EVENT_RUIM_RECORDS_LOADED = 22; 157 protected static final int EVENT_NV_READY = 23; 158 protected static final int EVENT_SET_ENHANCED_VP = 24; 159 protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25; 160 protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26; 161 protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27; 162 // other 163 protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28; 164 protected static final int EVENT_ICC_RECORD_EVENTS = 29; 165 protected static final int EVENT_ICC_CHANGED = 30; 166 // Single Radio Voice Call Continuity 167 protected static final int EVENT_SRVCC_STATE_CHANGED = 31; 168 protected static final int EVENT_INITIATE_SILENT_REDIAL = 32; 169 protected static final int EVENT_RADIO_NOT_AVAILABLE = 33; 170 protected static final int EVENT_UNSOL_OEM_HOOK_RAW = 34; 171 protected static final int EVENT_GET_RADIO_CAPABILITY = 35; 172 protected static final int EVENT_SS = 36; 173 protected static final int EVENT_CONFIG_LCE = 37; 174 private static final int EVENT_CHECK_FOR_NETWORK_AUTOMATIC = 38; 175 protected static final int EVENT_LAST = 176 EVENT_CHECK_FOR_NETWORK_AUTOMATIC; 177 178 // For shared prefs. 179 private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_"; 180 private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_"; 181 private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_"; 182 private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_"; 183 184 // Key used to read/write current CLIR setting 185 public static final String CLIR_KEY = "clir_key"; 186 187 // Key used for storing voice mail count 188 public static final String VM_COUNT = "vm_count_key"; 189 // Key used to read/write the ID for storing the voice mail 190 public static final String VM_ID = "vm_id_key"; 191 192 // Key used to read/write "disable DNS server check" pref (used for testing) 193 public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key"; 194 195 /** 196 * Small container class used to hold information relevant to 197 * the carrier selection process. operatorNumeric can be "" 198 * if we are looking for automatic selection. operatorAlphaLong is the 199 * corresponding operator name. 200 */ 201 protected static class NetworkSelectMessage { 202 public Message message; 203 public String operatorNumeric; 204 public String operatorAlphaLong; 205 public String operatorAlphaShort; 206 } 207 208 /* Instance Variables */ 209 public CommandsInterface mCi; 210 private int mVmCount = 0; 211 boolean mDnsCheckDisabled; 212 public DcTrackerBase mDcTracker; 213 boolean mDoesRilSendMultipleCallRing; 214 int mCallRingContinueToken; 215 int mCallRingDelay; 216 public boolean mIsTheCurrentActivePhone = true; 217 boolean mIsVoiceCapable = true; 218 219 // Variable to cache the video capability. When RAT changes, we lose this info and are unable 220 // to recover from the state. We cache it and notify listeners when they register. 221 protected boolean mIsVideoCapable = false; 222 protected UiccController mUiccController = null; 223 public final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>(); 224 public SmsStorageMonitor mSmsStorageMonitor; 225 public SmsUsageMonitor mSmsUsageMonitor; 226 protected AtomicReference<UiccCardApplication> mUiccApplication = 227 new AtomicReference<UiccCardApplication>(); 228 229 private TelephonyTester mTelephonyTester; 230 private final String mName; 231 private final String mActionDetached; 232 private final String mActionAttached; 233 234 protected int mPhoneId; 235 236 private boolean mImsServiceReady = false; 237 protected ImsPhone mImsPhone = null; 238 239 private final AtomicReference<RadioCapability> mRadioCapability = 240 new AtomicReference<RadioCapability>(); 241 242 protected static final int DEFAULT_REPORT_INTERVAL_MS = 200; 243 protected static final boolean LCE_PULL_MODE = true; 244 protected int mReportInterval = 0; // ms 245 protected int mLceStatus = RILConstants.LCE_NOT_AVAILABLE; 246 247 @Override 248 public String getPhoneName() { 249 return mName; 250 } 251 252 public String getNai(){ 253 return null; 254 } 255 256 /** 257 * Return the ActionDetached string. When this action is received by components 258 * they are to simulate detaching from the network. 259 * 260 * @return com.android.internal.telephony.{mName}.action_detached 261 * {mName} is GSM, CDMA ... 262 */ 263 public String getActionDetached() { 264 return mActionDetached; 265 } 266 267 /** 268 * Return the ActionAttached string. When this action is received by components 269 * they are to simulate attaching to the network. 270 * 271 * @return com.android.internal.telephony.{mName}.action_detached 272 * {mName} is GSM, CDMA ... 273 */ 274 public String getActionAttached() { 275 return mActionAttached; 276 } 277 278 /** 279 * Set a system property, unless we're in unit test mode 280 */ 281 // CAF_MSIM TODO this need to be replated with TelephonyManager API ? 282 public void setSystemProperty(String property, String value) { 283 if(getUnitTestMode()) { 284 return; 285 } 286 SystemProperties.set(property, value); 287 } 288 289 /** 290 * Set a system property, unless we're in unit test mode 291 */ 292 // CAF_MSIM TODO this need to be replated with TelephonyManager API ? 293 public String getSystemProperty(String property, String defValue) { 294 if(getUnitTestMode()) { 295 return null; 296 } 297 return SystemProperties.get(property, defValue); 298 } 299 300 301 protected final RegistrantList mPreciseCallStateRegistrants 302 = new RegistrantList(); 303 304 protected final RegistrantList mHandoverRegistrants 305 = new RegistrantList(); 306 307 protected final RegistrantList mNewRingingConnectionRegistrants 308 = new RegistrantList(); 309 310 protected final RegistrantList mIncomingRingRegistrants 311 = new RegistrantList(); 312 313 protected final RegistrantList mDisconnectRegistrants 314 = new RegistrantList(); 315 316 protected final RegistrantList mServiceStateRegistrants 317 = new RegistrantList(); 318 319 protected final RegistrantList mMmiCompleteRegistrants 320 = new RegistrantList(); 321 322 protected final RegistrantList mMmiRegistrants 323 = new RegistrantList(); 324 325 protected final RegistrantList mUnknownConnectionRegistrants 326 = new RegistrantList(); 327 328 protected final RegistrantList mSuppServiceFailedRegistrants 329 = new RegistrantList(); 330 331 protected final RegistrantList mRadioOffOrNotAvailableRegistrants 332 = new RegistrantList(); 333 334 protected final RegistrantList mSimRecordsLoadedRegistrants 335 = new RegistrantList(); 336 337 protected final RegistrantList mVideoCapabilityChangedRegistrants 338 = new RegistrantList(); 339 340 protected final RegistrantList mEmergencyCallToggledRegistrants 341 = new RegistrantList(); 342 343 344 protected Looper mLooper; /* to insure registrants are in correct thread*/ 345 346 protected final Context mContext; 347 348 /** 349 * PhoneNotifier is an abstraction for all system-wide 350 * state change notification. DefaultPhoneNotifier is 351 * used here unless running we're inside a unit test. 352 */ 353 protected PhoneNotifier mNotifier; 354 355 protected SimulatedRadioControl mSimulatedRadioControl; 356 357 boolean mUnitTestMode; 358 359 /** 360 * Constructs a PhoneBase in normal (non-unit test) mode. 361 * 362 * @param notifier An instance of DefaultPhoneNotifier, 363 * @param context Context object from hosting application 364 * unless unit testing. 365 * @param ci the CommandsInterface 366 */ 367 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci) { 368 this(name, notifier, context, ci, false); 369 } 370 371 /** 372 * Constructs a PhoneBase in normal (non-unit test) mode. 373 * 374 * @param notifier An instance of DefaultPhoneNotifier, 375 * @param context Context object from hosting application 376 * unless unit testing. 377 * @param ci is CommandsInterface 378 * @param unitTestMode when true, prevents notifications 379 * of state change events 380 */ 381 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 382 boolean unitTestMode) { 383 this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX); 384 } 385 386 /** 387 * Constructs a PhoneBase in normal (non-unit test) mode. 388 * 389 * @param notifier An instance of DefaultPhoneNotifier, 390 * @param context Context object from hosting application 391 * unless unit testing. 392 * @param ci is CommandsInterface 393 * @param unitTestMode when true, prevents notifications 394 * of state change events 395 * @param phoneId the phone-id of this phone. 396 */ 397 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 398 boolean unitTestMode, int phoneId) { 399 mPhoneId = phoneId; 400 mName = name; 401 mNotifier = notifier; 402 mContext = context; 403 mLooper = Looper.myLooper(); 404 mCi = ci; 405 mActionDetached = this.getClass().getPackage().getName() + ".action_detached"; 406 mActionAttached = this.getClass().getPackage().getName() + ".action_attached"; 407 408 if (Build.IS_DEBUGGABLE) { 409 mTelephonyTester = new TelephonyTester(this); 410 } 411 412 setUnitTestMode(unitTestMode); 413 414 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 415 mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); 416 mCi.setOnCallRing(this, EVENT_CALL_RING, null); 417 418 /* "Voice capable" means that this device supports circuit-switched 419 * (i.e. voice) phone calls over the telephony network, and is allowed 420 * to display the in-call UI while a cellular voice call is active. 421 * This will be false on "data only" devices which can't make voice 422 * calls and don't support any in-call UI. 423 */ 424 mIsVoiceCapable = mContext.getResources().getBoolean( 425 com.android.internal.R.bool.config_voice_capable); 426 427 /** 428 * Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs 429 * to be generated locally. Ideally all ring tones should be loops 430 * and this wouldn't be necessary. But to minimize changes to upper 431 * layers it is requested that it be generated by lower layers. 432 * 433 * By default old phones won't have the property set but do generate 434 * the RIL_UNSOL_CALL_RING so the default if there is no property is 435 * true. 436 */ 437 mDoesRilSendMultipleCallRing = SystemProperties.getBoolean( 438 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true); 439 Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 440 441 mCallRingDelay = SystemProperties.getInt( 442 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000); 443 Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay); 444 445 if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 446 return; 447 } 448 449 // The locale from the "ro.carrier" system property or R.array.carrier_properties. 450 // This will be overwritten by the Locale from the SIM language settings (EF-PL, EF-LI) 451 // if applicable. 452 final Locale carrierLocale = getLocaleFromCarrierProperties(mContext); 453 if (carrierLocale != null && !TextUtils.isEmpty(carrierLocale.getCountry())) { 454 final String country = carrierLocale.getCountry(); 455 try { 456 Settings.Global.getInt(mContext.getContentResolver(), 457 Settings.Global.WIFI_COUNTRY_CODE); 458 } catch (Settings.SettingNotFoundException e) { 459 // note this is not persisting 460 WifiManager wM = (WifiManager) 461 mContext.getSystemService(Context.WIFI_SERVICE); 462 wM.setCountryCode(country, false); 463 } 464 } 465 466 // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers. 467 mSmsStorageMonitor = new SmsStorageMonitor(this); 468 mSmsUsageMonitor = new SmsUsageMonitor(context); 469 mUiccController = UiccController.getInstance(); 470 mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); 471 if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) { 472 mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null); 473 } 474 mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null); 475 mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE, 476 obtainMessage(EVENT_CONFIG_LCE)); 477 } 478 479 @Override 480 public void startMonitoringImsService() { 481 if (getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) { 482 return; 483 } 484 485 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 486 IntentFilter filter = new IntentFilter(); 487 filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP); 488 filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN); 489 mContext.registerReceiver(mImsIntentReceiver, filter); 490 mImsIntentReceiverRegistered = true; 491 492 // Monitor IMS service - but first poll to see if already up (could miss 493 // intent) 494 ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId()); 495 if (imsManager != null && imsManager.isServiceAvailable()) { 496 mImsServiceReady = true; 497 updateImsPhone(); 498 } 499 } 500 } 501 502 @Override 503 public void dispose() { 504 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 505 if (mImsIntentReceiverRegistered) { 506 mContext.unregisterReceiver(mImsIntentReceiver); 507 mImsIntentReceiverRegistered = false; 508 } 509 mCi.unSetOnCallRing(this); 510 // Must cleanup all connectionS and needs to use sendMessage! 511 mDcTracker.cleanUpAllConnections(null); 512 mIsTheCurrentActivePhone = false; 513 // Dispose the SMS usage and storage monitors 514 mSmsStorageMonitor.dispose(); 515 mSmsUsageMonitor.dispose(); 516 mUiccController.unregisterForIccChanged(this); 517 mCi.unregisterForSrvccStateChanged(this); 518 mCi.unSetOnUnsolOemHookRaw(this); 519 mCi.stopLceService(obtainMessage(EVENT_CONFIG_LCE)); 520 521 if (mTelephonyTester != null) { 522 mTelephonyTester.dispose(); 523 } 524 525 ImsPhone imsPhone = mImsPhone; 526 if (imsPhone != null) { 527 imsPhone.unregisterForSilentRedial(this); 528 imsPhone.dispose(); 529 } 530 } 531 } 532 533 @Override 534 public void removeReferences() { 535 mSmsStorageMonitor = null; 536 mSmsUsageMonitor = null; 537 mIccRecords.set(null); 538 mUiccApplication.set(null); 539 mDcTracker = null; 540 mUiccController = null; 541 542 ImsPhone imsPhone = mImsPhone; 543 if (imsPhone != null) { 544 imsPhone.removeReferences(); 545 mImsPhone = null; 546 } 547 } 548 549 /** 550 * When overridden the derived class needs to call 551 * super.handleMessage(msg) so this method has a 552 * a chance to process the message. 553 * 554 * @param msg 555 */ 556 @Override 557 public void handleMessage(Message msg) { 558 AsyncResult ar; 559 560 // messages to be handled whether or not the phone is being destroyed 561 // should only include messages which are being re-directed and do not use 562 // resources of the phone being destroyed 563 // Note: make sure to add code in GSMPhone/CDMAPhone to re-direct here before 564 // they check if phone destroyed. 565 switch (msg.what) { 566 // handle the select network completion callbacks. 567 case EVENT_SET_NETWORK_MANUAL_COMPLETE: 568 case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE: 569 handleSetSelectNetwork((AsyncResult) msg.obj); 570 return; 571 } 572 573 if (!mIsTheCurrentActivePhone) { 574 Rlog.e(LOG_TAG, "Received message " + msg + 575 "[" + msg.what + "] while being destroyed. Ignoring."); 576 return; 577 } 578 switch(msg.what) { 579 case EVENT_CALL_RING: 580 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState()); 581 ar = (AsyncResult)msg.obj; 582 if (ar.exception == null) { 583 PhoneConstants.State state = getState(); 584 if ((!mDoesRilSendMultipleCallRing) 585 && ((state == PhoneConstants.State.RINGING) || 586 (state == PhoneConstants.State.IDLE))) { 587 mCallRingContinueToken += 1; 588 sendIncomingCallRingNotification(mCallRingContinueToken); 589 } else { 590 notifyIncomingRing(); 591 } 592 } 593 break; 594 595 case EVENT_CALL_RING_CONTINUE: 596 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState()); 597 if (getState() == PhoneConstants.State.RINGING) { 598 sendIncomingCallRingNotification(msg.arg1); 599 } 600 break; 601 602 case EVENT_ICC_CHANGED: 603 onUpdateIccAvailability(); 604 break; 605 606 case EVENT_INITIATE_SILENT_REDIAL: 607 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received"); 608 ar = (AsyncResult) msg.obj; 609 if ((ar.exception == null) && (ar.result != null)) { 610 String dialString = (String) ar.result; 611 if (TextUtils.isEmpty(dialString)) return; 612 try { 613 dialInternal(dialString, null, VideoProfile.STATE_AUDIO_ONLY, null); 614 } catch (CallStateException e) { 615 Rlog.e(LOG_TAG, "silent redial failed: " + e); 616 } 617 } 618 break; 619 620 case EVENT_SRVCC_STATE_CHANGED: 621 ar = (AsyncResult)msg.obj; 622 if (ar.exception == null) { 623 handleSrvccStateChanged((int[]) ar.result); 624 } else { 625 Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception); 626 } 627 break; 628 629 case EVENT_UNSOL_OEM_HOOK_RAW: 630 ar = (AsyncResult)msg.obj; 631 if (ar.exception == null) { 632 byte[] data = (byte[])ar.result; 633 Rlog.d(LOG_TAG, "EVENT_UNSOL_OEM_HOOK_RAW data=" 634 + IccUtils.bytesToHexString(data)); 635 mNotifier.notifyOemHookRawEventForSubscriber(getSubId(), data); 636 } else { 637 Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception); 638 } 639 break; 640 641 case EVENT_GET_RADIO_CAPABILITY: 642 ar = (AsyncResult) msg.obj; 643 RadioCapability rc = (RadioCapability) ar.result; 644 if (ar.exception != null) { 645 Rlog.d(LOG_TAG, "get phone radio capability fail," 646 + "no need to change mRadioCapability"); 647 } else { 648 radioCapabilityUpdated(rc); 649 } 650 Rlog.d(LOG_TAG, "EVENT_GET_RADIO_CAPABILITY :" 651 + "phone rc : " + rc); 652 break; 653 654 case EVENT_CONFIG_LCE: 655 ar = (AsyncResult) msg.obj; 656 if (ar.exception != null) { 657 Rlog.d(LOG_TAG, "config LCE service failed: " + ar.exception); 658 } else { 659 final ArrayList<Integer> statusInfo = (ArrayList<Integer>)ar.result; 660 mLceStatus = statusInfo.get(0); 661 mReportInterval = statusInfo.get(1); 662 } 663 break; 664 665 case EVENT_CHECK_FOR_NETWORK_AUTOMATIC: { 666 onCheckForNetworkSelectionModeAutomatic(msg); 667 break; 668 } 669 default: 670 throw new RuntimeException("unexpected event not handled"); 671 } 672 } 673 674 private void handleSrvccStateChanged(int[] ret) { 675 Rlog.d(LOG_TAG, "handleSrvccStateChanged"); 676 677 ArrayList<Connection> conn = null; 678 ImsPhone imsPhone = mImsPhone; 679 Call.SrvccState srvccState = Call.SrvccState.NONE; 680 if (ret != null && ret.length != 0) { 681 int state = ret[0]; 682 switch(state) { 683 case VoLteServiceState.HANDOVER_STARTED: 684 srvccState = Call.SrvccState.STARTED; 685 if (imsPhone != null) { 686 conn = imsPhone.getHandoverConnection(); 687 migrateFrom(imsPhone); 688 } else { 689 Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null"); 690 } 691 break; 692 case VoLteServiceState.HANDOVER_COMPLETED: 693 srvccState = Call.SrvccState.COMPLETED; 694 if (imsPhone != null) { 695 imsPhone.notifySrvccState(srvccState); 696 } else { 697 Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null"); 698 } 699 break; 700 case VoLteServiceState.HANDOVER_FAILED: 701 case VoLteServiceState.HANDOVER_CANCELED: 702 srvccState = Call.SrvccState.FAILED; 703 break; 704 705 default: 706 //ignore invalid state 707 return; 708 } 709 710 getCallTracker().notifySrvccState(srvccState, conn); 711 712 VoLteServiceState lteState = new VoLteServiceState(state); 713 notifyVoLteServiceStateChanged(lteState); 714 } 715 } 716 717 // Inherited documentation suffices. 718 @Override 719 public Context getContext() { 720 return mContext; 721 } 722 723 // Will be called when icc changed 724 protected abstract void onUpdateIccAvailability(); 725 726 /** 727 * Disables the DNS check (i.e., allows "0.0.0.0"). 728 * Useful for lab testing environment. 729 * @param b true disables the check, false enables. 730 */ 731 @Override 732 public void disableDnsCheck(boolean b) { 733 mDnsCheckDisabled = b; 734 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 735 SharedPreferences.Editor editor = sp.edit(); 736 editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); 737 editor.apply(); 738 } 739 740 /** 741 * Returns true if the DNS check is currently disabled. 742 */ 743 @Override 744 public boolean isDnsCheckDisabled() { 745 return mDnsCheckDisabled; 746 } 747 748 // Inherited documentation suffices. 749 @Override 750 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { 751 checkCorrectThread(h); 752 753 mPreciseCallStateRegistrants.addUnique(h, what, obj); 754 } 755 756 // Inherited documentation suffices. 757 @Override 758 public void unregisterForPreciseCallStateChanged(Handler h) { 759 mPreciseCallStateRegistrants.remove(h); 760 } 761 762 /** 763 * Subclasses of Phone probably want to replace this with a 764 * version scoped to their packages 765 */ 766 protected void notifyPreciseCallStateChangedP() { 767 AsyncResult ar = new AsyncResult(null, this, null); 768 mPreciseCallStateRegistrants.notifyRegistrants(ar); 769 770 mNotifier.notifyPreciseCallState(this); 771 } 772 773 @Override 774 public void registerForHandoverStateChanged(Handler h, int what, Object obj) { 775 checkCorrectThread(h); 776 mHandoverRegistrants.addUnique(h, what, obj); 777 } 778 779 @Override 780 public void unregisterForHandoverStateChanged(Handler h) { 781 mHandoverRegistrants.remove(h); 782 } 783 784 /** 785 * Subclasses of Phone probably want to replace this with a 786 * version scoped to their packages 787 */ 788 public void notifyHandoverStateChanged(Connection cn) { 789 AsyncResult ar = new AsyncResult(null, cn, null); 790 mHandoverRegistrants.notifyRegistrants(ar); 791 } 792 793 public void migrateFrom(PhoneBase from) { 794 migrate(mHandoverRegistrants, from.mHandoverRegistrants); 795 migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants); 796 migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants); 797 migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants); 798 migrate(mDisconnectRegistrants, from.mDisconnectRegistrants); 799 migrate(mServiceStateRegistrants, from.mServiceStateRegistrants); 800 migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants); 801 migrate(mMmiRegistrants, from.mMmiRegistrants); 802 migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants); 803 migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants); 804 } 805 806 public void migrate(RegistrantList to, RegistrantList from) { 807 from.removeCleared(); 808 for (int i = 0, n = from.size(); i < n; i++) { 809 to.add((Registrant) from.get(i)); 810 } 811 } 812 813 // Inherited documentation suffices. 814 @Override 815 public void registerForUnknownConnection(Handler h, int what, Object obj) { 816 checkCorrectThread(h); 817 818 mUnknownConnectionRegistrants.addUnique(h, what, obj); 819 } 820 821 // Inherited documentation suffices. 822 @Override 823 public void unregisterForUnknownConnection(Handler h) { 824 mUnknownConnectionRegistrants.remove(h); 825 } 826 827 // Inherited documentation suffices. 828 @Override 829 public void registerForNewRingingConnection( 830 Handler h, int what, Object obj) { 831 checkCorrectThread(h); 832 833 mNewRingingConnectionRegistrants.addUnique(h, what, obj); 834 } 835 836 // Inherited documentation suffices. 837 @Override 838 public void unregisterForNewRingingConnection(Handler h) { 839 mNewRingingConnectionRegistrants.remove(h); 840 } 841 842 // Inherited documentation suffices. 843 @Override 844 public void registerForVideoCapabilityChanged( 845 Handler h, int what, Object obj) { 846 checkCorrectThread(h); 847 848 mVideoCapabilityChangedRegistrants.addUnique(h, what, obj); 849 850 // Notify any registrants of the cached video capability as soon as they register. 851 notifyForVideoCapabilityChanged(mIsVideoCapable); 852 } 853 854 // Inherited documentation suffices. 855 @Override 856 public void unregisterForVideoCapabilityChanged(Handler h) { 857 mVideoCapabilityChangedRegistrants.remove(h); 858 } 859 860 // Inherited documentation suffices. 861 @Override 862 public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ 863 mCi.registerForInCallVoicePrivacyOn(h, what, obj); 864 } 865 866 // Inherited documentation suffices. 867 @Override 868 public void unregisterForInCallVoicePrivacyOn(Handler h){ 869 mCi.unregisterForInCallVoicePrivacyOn(h); 870 } 871 872 // Inherited documentation suffices. 873 @Override 874 public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ 875 mCi.registerForInCallVoicePrivacyOff(h, what, obj); 876 } 877 878 // Inherited documentation suffices. 879 @Override 880 public void unregisterForInCallVoicePrivacyOff(Handler h){ 881 mCi.unregisterForInCallVoicePrivacyOff(h); 882 } 883 884 // Inherited documentation suffices. 885 @Override 886 public void registerForIncomingRing( 887 Handler h, int what, Object obj) { 888 checkCorrectThread(h); 889 890 mIncomingRingRegistrants.addUnique(h, what, obj); 891 } 892 893 // Inherited documentation suffices. 894 @Override 895 public void unregisterForIncomingRing(Handler h) { 896 mIncomingRingRegistrants.remove(h); 897 } 898 899 // Inherited documentation suffices. 900 @Override 901 public void registerForDisconnect(Handler h, int what, Object obj) { 902 checkCorrectThread(h); 903 904 mDisconnectRegistrants.addUnique(h, what, obj); 905 } 906 907 // Inherited documentation suffices. 908 @Override 909 public void unregisterForDisconnect(Handler h) { 910 mDisconnectRegistrants.remove(h); 911 } 912 913 // Inherited documentation suffices. 914 @Override 915 public void registerForSuppServiceFailed(Handler h, int what, Object obj) { 916 checkCorrectThread(h); 917 918 mSuppServiceFailedRegistrants.addUnique(h, what, obj); 919 } 920 921 // Inherited documentation suffices. 922 @Override 923 public void unregisterForSuppServiceFailed(Handler h) { 924 mSuppServiceFailedRegistrants.remove(h); 925 } 926 927 // Inherited documentation suffices. 928 @Override 929 public void registerForMmiInitiate(Handler h, int what, Object obj) { 930 checkCorrectThread(h); 931 932 mMmiRegistrants.addUnique(h, what, obj); 933 } 934 935 // Inherited documentation suffices. 936 @Override 937 public void unregisterForMmiInitiate(Handler h) { 938 mMmiRegistrants.remove(h); 939 } 940 941 // Inherited documentation suffices. 942 @Override 943 public void registerForMmiComplete(Handler h, int what, Object obj) { 944 checkCorrectThread(h); 945 946 mMmiCompleteRegistrants.addUnique(h, what, obj); 947 } 948 949 // Inherited documentation suffices. 950 @Override 951 public void unregisterForMmiComplete(Handler h) { 952 checkCorrectThread(h); 953 954 mMmiCompleteRegistrants.remove(h); 955 } 956 957 public void registerForSimRecordsLoaded(Handler h, int what, Object obj) { 958 logUnexpectedCdmaMethodCall("registerForSimRecordsLoaded"); 959 } 960 961 public void unregisterForSimRecordsLoaded(Handler h) { 962 logUnexpectedCdmaMethodCall("unregisterForSimRecordsLoaded"); 963 } 964 965 @Override 966 public void registerForTtyModeReceived(Handler h, int what, Object obj) { 967 } 968 969 @Override 970 public void unregisterForTtyModeReceived(Handler h) { 971 } 972 973 @Override 974 public void setNetworkSelectionModeAutomatic(Message response) { 975 Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode"); 976 // we don't want to do this unecesarily - it acutally causes 977 // the radio to repeate network selection and is costly 978 // first check if we're already in automatic mode 979 Message msg = obtainMessage(EVENT_CHECK_FOR_NETWORK_AUTOMATIC); 980 msg.obj = response; 981 mCi.getNetworkSelectionMode(msg); 982 } 983 984 private void onCheckForNetworkSelectionModeAutomatic(Message fromRil) { 985 AsyncResult ar = (AsyncResult)fromRil.obj; 986 Message response = (Message)ar.userObj; 987 boolean doAutomatic = true; 988 if (ar.exception == null && ar.result != null) { 989 try { 990 int[] modes = (int[])ar.result; 991 if (modes[0] == 0) { 992 // already confirmed to be in automatic mode - don't resend 993 doAutomatic = false; 994 } 995 } catch (Exception e) { 996 // send the setting on error 997 } 998 } 999 if (doAutomatic) { 1000 // wrap the response message in our own message along with 1001 // an empty string (to indicate automatic selection) for the 1002 // operator's id. 1003 NetworkSelectMessage nsm = new NetworkSelectMessage(); 1004 nsm.message = response; 1005 nsm.operatorNumeric = ""; 1006 nsm.operatorAlphaLong = ""; 1007 nsm.operatorAlphaShort = ""; 1008 1009 Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm); 1010 mCi.setNetworkSelectionModeAutomatic(msg); 1011 1012 updateSavedNetworkOperator(nsm); 1013 } else { 1014 Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - already auto, ignoring"); 1015 } 1016 } 1017 1018 @Override 1019 public void getNetworkSelectionMode(Message message) { 1020 mCi.getNetworkSelectionMode(message); 1021 } 1022 1023 @Override 1024 public void selectNetworkManually(OperatorInfo network, Message response) { 1025 // wrap the response message in our own message along with 1026 // the operator's id. 1027 NetworkSelectMessage nsm = new NetworkSelectMessage(); 1028 nsm.message = response; 1029 nsm.operatorNumeric = network.getOperatorNumeric(); 1030 nsm.operatorAlphaLong = network.getOperatorAlphaLong(); 1031 nsm.operatorAlphaShort = network.getOperatorAlphaShort(); 1032 1033 Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); 1034 mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg); 1035 1036 updateSavedNetworkOperator(nsm); 1037 } 1038 1039 /** 1040 * Registration point for emergency call/callback mode start. Message.obj is AsyncResult and 1041 * Message.obj.result will be Integer indicating start of call by value 1 or end of call by 1042 * value 0 1043 * @param h handler to notify 1044 * @param what what code of message when delivered 1045 * @param obj placed in Message.obj.userObj 1046 */ 1047 public void registerForEmergencyCallToggle(Handler h, int what, Object obj) { 1048 Registrant r = new Registrant(h, what, obj); 1049 mEmergencyCallToggledRegistrants.add(r); 1050 } 1051 1052 public void unregisterForEmergencyCallToggle(Handler h) { 1053 mEmergencyCallToggledRegistrants.remove(h); 1054 } 1055 1056 private void updateSavedNetworkOperator(NetworkSelectMessage nsm) { 1057 int subId = getSubId(); 1058 if (SubscriptionManager.isValidSubscriptionId(subId)) { 1059 // open the shared preferences editor, and write the value. 1060 // nsm.operatorNumeric is "" if we're in automatic.selection. 1061 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1062 SharedPreferences.Editor editor = sp.edit(); 1063 editor.putString(NETWORK_SELECTION_KEY + subId, nsm.operatorNumeric); 1064 editor.putString(NETWORK_SELECTION_NAME_KEY + subId, nsm.operatorAlphaLong); 1065 editor.putString(NETWORK_SELECTION_SHORT_KEY + subId, nsm.operatorAlphaShort); 1066 1067 // commit and log the result. 1068 if (!editor.commit()) { 1069 Rlog.e(LOG_TAG, "failed to commit network selection preference"); 1070 } 1071 } else { 1072 Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " + 1073 subId); 1074 } 1075 } 1076 1077 /** 1078 * Used to track the settings upon completion of the network change. 1079 */ 1080 private void handleSetSelectNetwork(AsyncResult ar) { 1081 // look for our wrapper within the asyncresult, skip the rest if it 1082 // is null. 1083 if (!(ar.userObj instanceof NetworkSelectMessage)) { 1084 Rlog.e(LOG_TAG, "unexpected result from user object."); 1085 return; 1086 } 1087 1088 NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj; 1089 1090 // found the object, now we send off the message we had originally 1091 // attached to the request. 1092 if (nsm.message != null) { 1093 AsyncResult.forMessage(nsm.message, ar.result, ar.exception); 1094 nsm.message.sendToTarget(); 1095 } 1096 } 1097 1098 /** 1099 * Method to retrieve the saved operator from the Shared Preferences 1100 */ 1101 private OperatorInfo getSavedNetworkSelection() { 1102 // open the shared preferences and search with our key. 1103 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1104 String numeric = sp.getString(NETWORK_SELECTION_KEY + getSubId(), ""); 1105 String name = sp.getString(NETWORK_SELECTION_NAME_KEY + getSubId(), ""); 1106 String shrt = sp.getString(NETWORK_SELECTION_SHORT_KEY + getSubId(), ""); 1107 return new OperatorInfo(numeric, name, shrt); 1108 } 1109 1110 /** 1111 * Method to restore the previously saved operator id, or reset to 1112 * automatic selection, all depending upon the value in the shared 1113 * preferences. 1114 */ 1115 public void restoreSavedNetworkSelection(Message response) { 1116 // retrieve the operator 1117 OperatorInfo networkSelection = getSavedNetworkSelection(); 1118 1119 // set to auto if the id is empty, otherwise select the network. 1120 if (networkSelection == null || TextUtils.isEmpty(networkSelection.getOperatorNumeric())) { 1121 setNetworkSelectionModeAutomatic(response); 1122 } else { 1123 selectNetworkManually(networkSelection, response); 1124 } 1125 } 1126 1127 // Inherited documentation suffices. 1128 @Override 1129 public void setUnitTestMode(boolean f) { 1130 mUnitTestMode = f; 1131 } 1132 1133 // Inherited documentation suffices. 1134 @Override 1135 public boolean getUnitTestMode() { 1136 return mUnitTestMode; 1137 } 1138 1139 /** 1140 * To be invoked when a voice call Connection disconnects. 1141 * 1142 * Subclasses of Phone probably want to replace this with a 1143 * version scoped to their packages 1144 */ 1145 protected void notifyDisconnectP(Connection cn) { 1146 AsyncResult ar = new AsyncResult(null, cn, null); 1147 mDisconnectRegistrants.notifyRegistrants(ar); 1148 } 1149 1150 // Inherited documentation suffices. 1151 @Override 1152 public void registerForServiceStateChanged( 1153 Handler h, int what, Object obj) { 1154 checkCorrectThread(h); 1155 1156 mServiceStateRegistrants.add(h, what, obj); 1157 } 1158 1159 // Inherited documentation suffices. 1160 @Override 1161 public void unregisterForServiceStateChanged(Handler h) { 1162 mServiceStateRegistrants.remove(h); 1163 } 1164 1165 // Inherited documentation suffices. 1166 @Override 1167 public void registerForRingbackTone(Handler h, int what, Object obj) { 1168 mCi.registerForRingbackTone(h, what, obj); 1169 } 1170 1171 // Inherited documentation suffices. 1172 @Override 1173 public void unregisterForRingbackTone(Handler h) { 1174 mCi.unregisterForRingbackTone(h); 1175 } 1176 1177 // Inherited documentation suffices. 1178 @Override 1179 public void registerForOnHoldTone(Handler h, int what, Object obj) { 1180 } 1181 1182 // Inherited documentation suffices. 1183 @Override 1184 public void unregisterForOnHoldTone(Handler h) { 1185 } 1186 1187 // Inherited documentation suffices. 1188 @Override 1189 public void registerForResendIncallMute(Handler h, int what, Object obj) { 1190 mCi.registerForResendIncallMute(h, what, obj); 1191 } 1192 1193 // Inherited documentation suffices. 1194 @Override 1195 public void unregisterForResendIncallMute(Handler h) { 1196 mCi.unregisterForResendIncallMute(h); 1197 } 1198 1199 @Override 1200 public void setEchoSuppressionEnabled() { 1201 // no need for regular phone 1202 } 1203 1204 /** 1205 * Subclasses of Phone probably want to replace this with a 1206 * version scoped to their packages 1207 */ 1208 protected void notifyServiceStateChangedP(ServiceState ss) { 1209 AsyncResult ar = new AsyncResult(null, ss, null); 1210 mServiceStateRegistrants.notifyRegistrants(ar); 1211 1212 mNotifier.notifyServiceState(this); 1213 } 1214 1215 // Inherited documentation suffices. 1216 @Override 1217 public SimulatedRadioControl getSimulatedRadioControl() { 1218 return mSimulatedRadioControl; 1219 } 1220 1221 /** 1222 * Verifies the current thread is the same as the thread originally 1223 * used in the initialization of this instance. Throws RuntimeException 1224 * if not. 1225 * 1226 * @exception RuntimeException if the current thread is not 1227 * the thread that originally obtained this PhoneBase instance. 1228 */ 1229 private void checkCorrectThread(Handler h) { 1230 if (h.getLooper() != mLooper) { 1231 throw new RuntimeException( 1232 "com.android.internal.telephony.Phone must be used from within one thread"); 1233 } 1234 } 1235 1236 /** 1237 * Set the properties by matching the carrier string in 1238 * a string-array resource 1239 */ 1240 private static Locale getLocaleFromCarrierProperties(Context ctx) { 1241 String carrier = SystemProperties.get("ro.carrier"); 1242 1243 if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { 1244 return null; 1245 } 1246 1247 CharSequence[] carrierLocales = ctx.getResources().getTextArray(R.array.carrier_properties); 1248 1249 for (int i = 0; i < carrierLocales.length; i+=3) { 1250 String c = carrierLocales[i].toString(); 1251 if (carrier.equals(c)) { 1252 return Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-')); 1253 } 1254 } 1255 1256 return null; 1257 } 1258 1259 /** 1260 * Get state 1261 */ 1262 @Override 1263 public abstract PhoneConstants.State getState(); 1264 1265 /** 1266 * Retrieves the IccFileHandler of the Phone instance 1267 */ 1268 public IccFileHandler getIccFileHandler(){ 1269 UiccCardApplication uiccApplication = mUiccApplication.get(); 1270 IccFileHandler fh; 1271 1272 if (uiccApplication == null) { 1273 Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null"); 1274 fh = null; 1275 } else { 1276 fh = uiccApplication.getIccFileHandler(); 1277 } 1278 1279 Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh); 1280 return fh; 1281 } 1282 1283 /* 1284 * Retrieves the Handler of the Phone instance 1285 */ 1286 public Handler getHandler() { 1287 return this; 1288 } 1289 1290 @Override 1291 public void updatePhoneObject(int voiceRadioTech) { 1292 // Only the PhoneProxy can update the phone object. 1293 PhoneFactory.getDefaultPhone().updatePhoneObject(voiceRadioTech); 1294 } 1295 1296 /** 1297 * Retrieves the ServiceStateTracker of the phone instance. 1298 */ 1299 public ServiceStateTracker getServiceStateTracker() { 1300 return null; 1301 } 1302 1303 /** 1304 * Get call tracker 1305 */ 1306 public CallTracker getCallTracker() { 1307 return null; 1308 } 1309 1310 public AppType getCurrentUiccAppType() { 1311 UiccCardApplication currentApp = mUiccApplication.get(); 1312 if (currentApp != null) { 1313 return currentApp.getType(); 1314 } 1315 return AppType.APPTYPE_UNKNOWN; 1316 } 1317 1318 @Override 1319 public IccCard getIccCard() { 1320 return null; 1321 //throw new Exception("getIccCard Shouldn't be called from PhoneBase"); 1322 } 1323 1324 @Override 1325 public String getIccSerialNumber() { 1326 IccRecords r = mIccRecords.get(); 1327 return (r != null) ? r.getIccId() : null; 1328 } 1329 1330 @Override 1331 public boolean getIccRecordsLoaded() { 1332 IccRecords r = mIccRecords.get(); 1333 return (r != null) ? r.getRecordsLoaded() : false; 1334 } 1335 1336 /** 1337 * @return all available cell information or null if none. 1338 */ 1339 @Override 1340 public List<CellInfo> getAllCellInfo() { 1341 List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo(); 1342 return privatizeCellInfoList(cellInfoList); 1343 } 1344 1345 /** 1346 * Clear CDMA base station lat/long values if location setting is disabled. 1347 * @param cellInfoList the original cell info list from the RIL 1348 * @return the original list with CDMA lat/long cleared if necessary 1349 */ 1350 private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) { 1351 if (cellInfoList == null) return null; 1352 int mode = Settings.Secure.getInt(getContext().getContentResolver(), 1353 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 1354 if (mode == Settings.Secure.LOCATION_MODE_OFF) { 1355 ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size()); 1356 // clear lat/lon values for location privacy 1357 for (CellInfo c : cellInfoList) { 1358 if (c instanceof CellInfoCdma) { 1359 CellInfoCdma cellInfoCdma = (CellInfoCdma) c; 1360 CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity(); 1361 CellIdentityCdma maskedCellIdentity = new CellIdentityCdma( 1362 cellIdentity.getNetworkId(), 1363 cellIdentity.getSystemId(), 1364 cellIdentity.getBasestationId(), 1365 Integer.MAX_VALUE, Integer.MAX_VALUE); 1366 CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma); 1367 privateCellInfoCdma.setCellIdentity(maskedCellIdentity); 1368 privateCellInfoList.add(privateCellInfoCdma); 1369 } else { 1370 privateCellInfoList.add(c); 1371 } 1372 } 1373 cellInfoList = privateCellInfoList; 1374 } 1375 return cellInfoList; 1376 } 1377 1378 /** 1379 * {@inheritDoc} 1380 */ 1381 @Override 1382 public void setCellInfoListRate(int rateInMillis) { 1383 mCi.setCellInfoListRate(rateInMillis, null); 1384 } 1385 1386 @Override 1387 /** @return true if there are messages waiting, false otherwise. */ 1388 public boolean getMessageWaitingIndicator() { 1389 return mVmCount != 0; 1390 } 1391 1392 @Override 1393 public boolean getCallForwardingIndicator() { 1394 IccRecords r = mIccRecords.get(); 1395 return (r != null) ? r.getVoiceCallForwardingFlag() : false; 1396 } 1397 1398 /** 1399 * Query the status of the CDMA roaming preference 1400 */ 1401 @Override 1402 public void queryCdmaRoamingPreference(Message response) { 1403 mCi.queryCdmaRoamingPreference(response); 1404 } 1405 1406 /** 1407 * Get the signal strength 1408 */ 1409 @Override 1410 public SignalStrength getSignalStrength() { 1411 ServiceStateTracker sst = getServiceStateTracker(); 1412 if (sst == null) { 1413 return new SignalStrength(); 1414 } else { 1415 return sst.getSignalStrength(); 1416 } 1417 } 1418 1419 /** 1420 * Set the status of the CDMA roaming preference 1421 */ 1422 @Override 1423 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 1424 mCi.setCdmaRoamingPreference(cdmaRoamingType, response); 1425 } 1426 1427 /** 1428 * Set the status of the CDMA subscription mode 1429 */ 1430 @Override 1431 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 1432 mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 1433 } 1434 1435 /** 1436 * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only 1437 */ 1438 @Override 1439 public void setPreferredNetworkType(int networkType, Message response) { 1440 // Only set preferred network types to that which the modem supports 1441 int modemRaf = getRadioAccessFamily(); 1442 int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType); 1443 1444 if (modemRaf == RadioAccessFamily.RAF_UNKNOWN 1445 || rafFromType == RadioAccessFamily.RAF_UNKNOWN) { 1446 Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: " 1447 + modemRaf + " " + rafFromType); 1448 if (response != null) { 1449 CommandException ex; 1450 1451 ex = new CommandException(CommandException.Error.GENERIC_FAILURE); 1452 AsyncResult.forMessage(response, null, ex); 1453 response.sendToTarget(); 1454 } 1455 return; 1456 } 1457 1458 int filteredRaf = (rafFromType & modemRaf); 1459 int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf); 1460 1461 Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType 1462 + " modemRaf = " + modemRaf 1463 + " rafFromType = " + rafFromType 1464 + " filteredType = " + filteredType); 1465 1466 mCi.setPreferredNetworkType(filteredType, response); 1467 } 1468 1469 @Override 1470 public void getPreferredNetworkType(Message response) { 1471 mCi.getPreferredNetworkType(response); 1472 } 1473 1474 @Override 1475 public void getSmscAddress(Message result) { 1476 mCi.getSmscAddress(result); 1477 } 1478 1479 @Override 1480 public void setSmscAddress(String address, Message result) { 1481 mCi.setSmscAddress(address, result); 1482 } 1483 1484 @Override 1485 public void setTTYMode(int ttyMode, Message onComplete) { 1486 mCi.setTTYMode(ttyMode, onComplete); 1487 } 1488 1489 @Override 1490 public void setUiTTYMode(int uiTtyMode, Message onComplete) { 1491 Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call"); 1492 } 1493 1494 @Override 1495 public void queryTTYMode(Message onComplete) { 1496 mCi.queryTTYMode(onComplete); 1497 } 1498 1499 @Override 1500 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 1501 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1502 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 1503 } 1504 1505 @Override 1506 public void getEnhancedVoicePrivacy(Message onComplete) { 1507 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1508 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 1509 } 1510 1511 @Override 1512 public void setBandMode(int bandMode, Message response) { 1513 mCi.setBandMode(bandMode, response); 1514 } 1515 1516 @Override 1517 public void queryAvailableBandMode(Message response) { 1518 mCi.queryAvailableBandMode(response); 1519 } 1520 1521 @Override 1522 public void invokeOemRilRequestRaw(byte[] data, Message response) { 1523 mCi.invokeOemRilRequestRaw(data, response); 1524 } 1525 1526 @Override 1527 public void invokeOemRilRequestStrings(String[] strings, Message response) { 1528 mCi.invokeOemRilRequestStrings(strings, response); 1529 } 1530 1531 @Override 1532 public void nvReadItem(int itemID, Message response) { 1533 mCi.nvReadItem(itemID, response); 1534 } 1535 1536 @Override 1537 public void nvWriteItem(int itemID, String itemValue, Message response) { 1538 mCi.nvWriteItem(itemID, itemValue, response); 1539 } 1540 1541 @Override 1542 public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) { 1543 mCi.nvWriteCdmaPrl(preferredRoamingList, response); 1544 } 1545 1546 @Override 1547 public void nvResetConfig(int resetType, Message response) { 1548 mCi.nvResetConfig(resetType, response); 1549 } 1550 1551 @Override 1552 public void notifyDataActivity() { 1553 mNotifier.notifyDataActivity(this); 1554 } 1555 1556 public void notifyMessageWaitingIndicator() { 1557 // Do not notify voice mail waiting if device doesn't support voice 1558 if (!mIsVoiceCapable) 1559 return; 1560 1561 // This function is added to send the notification to DefaultPhoneNotifier. 1562 mNotifier.notifyMessageWaitingChanged(this); 1563 } 1564 1565 public void notifyDataConnection(String reason, String apnType, 1566 PhoneConstants.DataState state) { 1567 mNotifier.notifyDataConnection(this, reason, apnType, state); 1568 } 1569 1570 public void notifyDataConnection(String reason, String apnType) { 1571 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 1572 } 1573 1574 public void notifyDataConnection(String reason) { 1575 String types[] = getActiveApnTypes(); 1576 for (String apnType : types) { 1577 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 1578 } 1579 } 1580 1581 public void notifyOtaspChanged(int otaspMode) { 1582 mNotifier.notifyOtaspChanged(this, otaspMode); 1583 } 1584 1585 public void notifySignalStrength() { 1586 mNotifier.notifySignalStrength(this); 1587 } 1588 1589 public void notifyCellInfo(List<CellInfo> cellInfo) { 1590 mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo)); 1591 } 1592 1593 public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) { 1594 mNotifier.notifyDataConnectionRealTimeInfo(this, dcRtInfo); 1595 } 1596 1597 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1598 mNotifier.notifyVoLteServiceStateChanged(this, lteState); 1599 } 1600 1601 /** 1602 * @return true if a mobile originating emergency call is active 1603 */ 1604 public boolean isInEmergencyCall() { 1605 return false; 1606 } 1607 1608 /** 1609 * @return {@code true} if we are in emergency call back mode. This is a period where the phone 1610 * should be using as little power as possible and be ready to receive an incoming call from the 1611 * emergency operator. 1612 */ 1613 public boolean isInEcm() { 1614 return false; 1615 } 1616 1617 private static int getVideoState(Call call) { 1618 int videoState = VideoProfile.STATE_AUDIO_ONLY; 1619 ImsPhoneConnection conn = (ImsPhoneConnection) call.getEarliestConnection(); 1620 if (conn != null) { 1621 videoState = conn.getVideoState(); 1622 } 1623 return videoState; 1624 } 1625 1626 private boolean isVideoCall(Call call) { 1627 int videoState = getVideoState(call); 1628 return (VideoProfile.isVideo(videoState)); 1629 } 1630 1631 @Override 1632 public boolean isVideoCallPresent() { 1633 boolean isVideoCallActive = false; 1634 if (mImsPhone != null) { 1635 isVideoCallActive = isVideoCall(mImsPhone.getForegroundCall()) || 1636 isVideoCall(mImsPhone.getBackgroundCall()) || 1637 isVideoCall(mImsPhone.getRingingCall()); 1638 } 1639 Rlog.d(LOG_TAG, "isVideoCallActive: " + isVideoCallActive); 1640 return isVideoCallActive; 1641 } 1642 1643 @Override 1644 public abstract int getPhoneType(); 1645 1646 /** @hide */ 1647 /** @return number of voicemails */ 1648 @Override 1649 public int getVoiceMessageCount(){ 1650 return mVmCount; 1651 } 1652 1653 /** sets the voice mail count of the phone and notifies listeners. */ 1654 public void setVoiceMessageCount(int countWaiting) { 1655 mVmCount = countWaiting; 1656 // notify listeners of voice mail 1657 notifyMessageWaitingIndicator(); 1658 } 1659 1660 /** gets the voice mail count from preferences */ 1661 protected int getStoredVoiceMessageCount() { 1662 int countVoiceMessages = 0; 1663 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 1664 String subscriberId = sp.getString(VM_ID, null); 1665 String currentSubscriberId = getSubscriberId(); 1666 1667 if ((subscriberId != null) && (currentSubscriberId != null) 1668 && (currentSubscriberId.equals(subscriberId))) { 1669 // get voice mail count from preferences 1670 countVoiceMessages = sp.getInt(VM_COUNT, 0); 1671 Rlog.d(LOG_TAG, "Voice Mail Count from preference = " + countVoiceMessages); 1672 } else { 1673 Rlog.d(LOG_TAG, "Voicemail count retrieval returning 0 as count for matching " + 1674 "subscriberId not found"); 1675 1676 } 1677 return countVoiceMessages; 1678 } 1679 1680 /** 1681 * Returns the CDMA ERI icon index to display 1682 */ 1683 @Override 1684 public int getCdmaEriIconIndex() { 1685 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 1686 return -1; 1687 } 1688 1689 /** 1690 * Returns the CDMA ERI icon mode, 1691 * 0 - ON 1692 * 1 - FLASHING 1693 */ 1694 @Override 1695 public int getCdmaEriIconMode() { 1696 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 1697 return -1; 1698 } 1699 1700 /** 1701 * Returns the CDMA ERI text, 1702 */ 1703 @Override 1704 public String getCdmaEriText() { 1705 logUnexpectedCdmaMethodCall("getCdmaEriText"); 1706 return "GSM nw, no ERI"; 1707 } 1708 1709 @Override 1710 public String getCdmaMin() { 1711 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1712 logUnexpectedCdmaMethodCall("getCdmaMin"); 1713 return null; 1714 } 1715 1716 @Override 1717 public boolean isMinInfoReady() { 1718 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1719 logUnexpectedCdmaMethodCall("isMinInfoReady"); 1720 return false; 1721 } 1722 1723 @Override 1724 public String getCdmaPrlVersion(){ 1725 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1726 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 1727 return null; 1728 } 1729 1730 @Override 1731 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 1732 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1733 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 1734 } 1735 1736 @Override 1737 public void exitEmergencyCallbackMode() { 1738 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1739 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 1740 } 1741 1742 @Override 1743 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 1744 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1745 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 1746 } 1747 1748 @Override 1749 public void unregisterForCdmaOtaStatusChange(Handler h) { 1750 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1751 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 1752 } 1753 1754 @Override 1755 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 1756 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1757 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 1758 } 1759 1760 @Override 1761 public void unregisterForSubscriptionInfoReady(Handler h) { 1762 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1763 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 1764 } 1765 1766 /** 1767 * Returns true if OTA Service Provisioning needs to be performed. 1768 * If not overridden return false. 1769 */ 1770 @Override 1771 public boolean needsOtaServiceProvisioning() { 1772 return false; 1773 } 1774 1775 /** 1776 * Return true if number is an OTASP number. 1777 * If not overridden return false. 1778 */ 1779 @Override 1780 public boolean isOtaSpNumber(String dialStr) { 1781 return false; 1782 } 1783 1784 @Override 1785 public void registerForCallWaiting(Handler h, int what, Object obj){ 1786 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1787 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 1788 } 1789 1790 @Override 1791 public void unregisterForCallWaiting(Handler h){ 1792 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1793 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 1794 } 1795 1796 @Override 1797 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 1798 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1799 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 1800 } 1801 1802 @Override 1803 public void unregisterForEcmTimerReset(Handler h) { 1804 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1805 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 1806 } 1807 1808 @Override 1809 public void registerForSignalInfo(Handler h, int what, Object obj) { 1810 mCi.registerForSignalInfo(h, what, obj); 1811 } 1812 1813 @Override 1814 public void unregisterForSignalInfo(Handler h) { 1815 mCi.unregisterForSignalInfo(h); 1816 } 1817 1818 @Override 1819 public void registerForDisplayInfo(Handler h, int what, Object obj) { 1820 mCi.registerForDisplayInfo(h, what, obj); 1821 } 1822 1823 @Override 1824 public void unregisterForDisplayInfo(Handler h) { 1825 mCi.unregisterForDisplayInfo(h); 1826 } 1827 1828 @Override 1829 public void registerForNumberInfo(Handler h, int what, Object obj) { 1830 mCi.registerForNumberInfo(h, what, obj); 1831 } 1832 1833 @Override 1834 public void unregisterForNumberInfo(Handler h) { 1835 mCi.unregisterForNumberInfo(h); 1836 } 1837 1838 @Override 1839 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 1840 mCi.registerForRedirectedNumberInfo(h, what, obj); 1841 } 1842 1843 @Override 1844 public void unregisterForRedirectedNumberInfo(Handler h) { 1845 mCi.unregisterForRedirectedNumberInfo(h); 1846 } 1847 1848 @Override 1849 public void registerForLineControlInfo(Handler h, int what, Object obj) { 1850 mCi.registerForLineControlInfo( h, what, obj); 1851 } 1852 1853 @Override 1854 public void unregisterForLineControlInfo(Handler h) { 1855 mCi.unregisterForLineControlInfo(h); 1856 } 1857 1858 @Override 1859 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 1860 mCi.registerFoT53ClirlInfo(h, what, obj); 1861 } 1862 1863 @Override 1864 public void unregisterForT53ClirInfo(Handler h) { 1865 mCi.unregisterForT53ClirInfo(h); 1866 } 1867 1868 @Override 1869 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 1870 mCi.registerForT53AudioControlInfo( h, what, obj); 1871 } 1872 1873 @Override 1874 public void unregisterForT53AudioControlInfo(Handler h) { 1875 mCi.unregisterForT53AudioControlInfo(h); 1876 } 1877 1878 @Override 1879 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 1880 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1881 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 1882 } 1883 1884 @Override 1885 public void unsetOnEcbModeExitResponse(Handler h){ 1886 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1887 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 1888 } 1889 1890 @Override 1891 public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) { 1892 mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj); 1893 } 1894 1895 @Override 1896 public void unregisterForRadioOffOrNotAvailable(Handler h) { 1897 mRadioOffOrNotAvailableRegistrants.remove(h); 1898 } 1899 1900 @Override 1901 public String[] getActiveApnTypes() { 1902 return mDcTracker.getActiveApnTypes(); 1903 } 1904 1905 @Override 1906 public boolean hasMatchedTetherApnSetting() { 1907 return mDcTracker.hasMatchedTetherApnSetting(); 1908 } 1909 1910 @Override 1911 public String getActiveApnHost(String apnType) { 1912 return mDcTracker.getActiveApnString(apnType); 1913 } 1914 1915 @Override 1916 public LinkProperties getLinkProperties(String apnType) { 1917 return mDcTracker.getLinkProperties(apnType); 1918 } 1919 1920 @Override 1921 public NetworkCapabilities getNetworkCapabilities(String apnType) { 1922 return mDcTracker.getNetworkCapabilities(apnType); 1923 } 1924 1925 @Override 1926 public boolean isDataConnectivityPossible() { 1927 return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT); 1928 } 1929 1930 @Override 1931 public boolean isDataConnectivityPossible(String apnType) { 1932 return ((mDcTracker != null) && 1933 (mDcTracker.isDataPossible(apnType))); 1934 } 1935 1936 /** 1937 * Notify registrants of a new ringing Connection. 1938 * Subclasses of Phone probably want to replace this with a 1939 * version scoped to their packages 1940 */ 1941 public void notifyNewRingingConnectionP(Connection cn) { 1942 if (!mIsVoiceCapable) 1943 return; 1944 AsyncResult ar = new AsyncResult(null, cn, null); 1945 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 1946 } 1947 1948 1949 /** 1950 * Notify registrants if phone is video capable. 1951 */ 1952 public void notifyForVideoCapabilityChanged(boolean isVideoCallCapable) { 1953 // Cache the current video capability so that we don't lose the information. 1954 mIsVideoCapable = isVideoCallCapable; 1955 1956 AsyncResult ar = new AsyncResult(null, isVideoCallCapable, null); 1957 mVideoCapabilityChangedRegistrants.notifyRegistrants(ar); 1958 } 1959 1960 /** 1961 * Notify registrants of a RING event. 1962 */ 1963 private void notifyIncomingRing() { 1964 if (!mIsVoiceCapable) 1965 return; 1966 AsyncResult ar = new AsyncResult(null, this, null); 1967 mIncomingRingRegistrants.notifyRegistrants(ar); 1968 } 1969 1970 /** 1971 * Send the incoming call Ring notification if conditions are right. 1972 */ 1973 private void sendIncomingCallRingNotification(int token) { 1974 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 1975 (token == mCallRingContinueToken)) { 1976 Rlog.d(LOG_TAG, "Sending notifyIncomingRing"); 1977 notifyIncomingRing(); 1978 sendMessageDelayed( 1979 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1980 } else { 1981 Rlog.d(LOG_TAG, "Ignoring ring notification request," 1982 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1983 + " token=" + token 1984 + " mCallRingContinueToken=" + mCallRingContinueToken 1985 + " mIsVoiceCapable=" + mIsVoiceCapable); 1986 } 1987 } 1988 1989 @Override 1990 public boolean isCspPlmnEnabled() { 1991 // This function should be overridden by the class GSMPhone. 1992 // Not implemented in CDMAPhone. 1993 logUnexpectedGsmMethodCall("isCspPlmnEnabled"); 1994 return false; 1995 } 1996 1997 @Override 1998 public IsimRecords getIsimRecords() { 1999 Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 2000 return null; 2001 } 2002 2003 @Override 2004 public String getMsisdn() { 2005 logUnexpectedGsmMethodCall("getMsisdn"); 2006 return null; 2007 } 2008 2009 /** 2010 * Common error logger method for unexpected calls to CDMA-only methods. 2011 */ 2012 private static void logUnexpectedCdmaMethodCall(String name) 2013 { 2014 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 2015 "called, CDMAPhone inactive."); 2016 } 2017 2018 @Override 2019 public PhoneConstants.DataState getDataConnectionState() { 2020 return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT); 2021 } 2022 2023 /** 2024 * Common error logger method for unexpected calls to GSM/WCDMA-only methods. 2025 */ 2026 private static void logUnexpectedGsmMethodCall(String name) { 2027 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 2028 "called, GSMPhone inactive."); 2029 } 2030 2031 // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone. 2032 public void notifyCallForwardingIndicator() { 2033 // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone. 2034 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); 2035 } 2036 2037 public void notifyDataConnectionFailed(String reason, String apnType) { 2038 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 2039 } 2040 2041 public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, 2042 String failCause) { 2043 mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause); 2044 } 2045 2046 /** 2047 * {@inheritDoc} 2048 */ 2049 @Override 2050 public int getLteOnCdmaMode() { 2051 return mCi.getLteOnCdmaMode(); 2052 } 2053 2054 public void setVoiceMessageWaiting(int line, int countWaiting) { 2055 // This function should be overridden by class GSMPhone and CDMAPhone. 2056 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone."); 2057 } 2058 2059 /** 2060 * Gets the USIM service table from the UICC, if present and available. 2061 * @return an interface to the UsimServiceTable record, or null if not available 2062 */ 2063 @Override 2064 public UsimServiceTable getUsimServiceTable() { 2065 IccRecords r = mIccRecords.get(); 2066 return (r != null) ? r.getUsimServiceTable() : null; 2067 } 2068 2069 /** 2070 * Gets the Uicc card corresponding to this phone. 2071 * @return the UiccCard object corresponding to the phone ID. 2072 */ 2073 @Override 2074 public UiccCard getUiccCard() { 2075 return mUiccController.getUiccCard(mPhoneId); 2076 } 2077 2078 /** 2079 * Get P-CSCF address from PCO after data connection is established or modified. 2080 * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN 2081 */ 2082 @Override 2083 public String[] getPcscfAddress(String apnType) { 2084 return mDcTracker.getPcscfAddress(apnType); 2085 } 2086 2087 /** 2088 * Set IMS registration state 2089 */ 2090 @Override 2091 public void setImsRegistrationState(boolean registered) { 2092 mDcTracker.setImsRegistrationState(registered); 2093 } 2094 2095 /** 2096 * Return an instance of a IMS phone 2097 */ 2098 @Override 2099 public Phone getImsPhone() { 2100 return mImsPhone; 2101 } 2102 2103 @Override 2104 public ImsPhone relinquishOwnershipOfImsPhone() { 2105 synchronized (PhoneProxy.lockForRadioTechnologyChange) { 2106 if (mImsPhone == null) 2107 return null; 2108 2109 if (mImsIntentReceiverRegistered) { 2110 mContext.unregisterReceiver(mImsIntentReceiver); 2111 mImsIntentReceiverRegistered = false; 2112 } 2113 2114 ImsPhone imsPhone = mImsPhone; 2115 mImsPhone = null; 2116 2117 CallManager.getInstance().unregisterPhone(imsPhone); 2118 imsPhone.unregisterForSilentRedial(this); 2119 2120 return imsPhone; 2121 } 2122 } 2123 2124 @Override 2125 public void acquireOwnershipOfImsPhone(ImsPhone imsPhone) { 2126 synchronized (PhoneProxy.lockForRadioTechnologyChange) { 2127 if (imsPhone == null) 2128 return; 2129 2130 if (mImsPhone != null) { 2131 Rlog.e(LOG_TAG, "acquireOwnershipOfImsPhone: non-null mImsPhone." + 2132 " Shouldn't happen - but disposing"); 2133 mImsPhone.dispose(); 2134 // Potential GC issue if someone keeps a reference to ImsPhone. 2135 // However: this change will make sure that such a reference does 2136 // not access functions through NULL pointer. 2137 //mImsPhone.removeReferences(); 2138 } 2139 2140 mImsPhone = imsPhone; 2141 2142 mImsServiceReady = true; 2143 mImsPhone.updateParentPhone(this); 2144 CallManager.getInstance().registerPhone(mImsPhone); 2145 mImsPhone.registerForSilentRedial( 2146 this, EVENT_INITIATE_SILENT_REDIAL, null); 2147 } 2148 } 2149 2150 protected void updateImsPhone() { 2151 Rlog.d(LOG_TAG, "updateImsPhone" 2152 + " mImsServiceReady=" + mImsServiceReady); 2153 2154 if (mImsServiceReady && (mImsPhone == null)) { 2155 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this); 2156 CallManager.getInstance().registerPhone(mImsPhone); 2157 mImsPhone.registerForSilentRedial( 2158 this, EVENT_INITIATE_SILENT_REDIAL, null); 2159 } else if (!mImsServiceReady && (mImsPhone != null)) { 2160 CallManager.getInstance().unregisterPhone(mImsPhone); 2161 mImsPhone.unregisterForSilentRedial(this); 2162 2163 mImsPhone.dispose(); 2164 // Potential GC issue if someone keeps a reference to ImsPhone. 2165 // However: this change will make sure that such a reference does 2166 // not access functions through NULL pointer. 2167 //mImsPhone.removeReferences(); 2168 mImsPhone = null; 2169 } 2170 } 2171 2172 /** 2173 * Dials a number. 2174 * 2175 * @param dialString The number to dial. 2176 * @param uusInfo The UUSInfo. 2177 * @param videoState The video state for the call. 2178 * @param intentExtras Extras from the original CALL intent. 2179 * @return The Connection. 2180 * @throws CallStateException 2181 */ 2182 protected Connection dialInternal( 2183 String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras) 2184 throws CallStateException { 2185 // dialInternal shall be overriden by GSMPhone and CDMAPhone 2186 return null; 2187 } 2188 2189 /** 2190 * Returns the subscription id. 2191 */ 2192 public int getSubId() { 2193 return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId); 2194 } 2195 2196 /** 2197 * Returns the phone id. 2198 */ 2199 public int getPhoneId() { 2200 return mPhoneId; 2201 } 2202 2203 /** 2204 * Return the service state of mImsPhone if it is STATE_IN_SERVICE 2205 * otherwise return the current voice service state 2206 */ 2207 @Override 2208 public int getVoicePhoneServiceState() { 2209 ImsPhone imsPhone = mImsPhone; 2210 if (imsPhone != null 2211 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) { 2212 return ServiceState.STATE_IN_SERVICE; 2213 } 2214 return getServiceState().getState(); 2215 } 2216 2217 @Override 2218 public boolean setOperatorBrandOverride(String brand) { 2219 return false; 2220 } 2221 2222 @Override 2223 public boolean setRoamingOverride(List<String> gsmRoamingList, 2224 List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 2225 List<String> cdmaNonRoamingList) { 2226 String iccId = getIccSerialNumber(); 2227 if (TextUtils.isEmpty(iccId)) { 2228 return false; 2229 } 2230 2231 setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2232 setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2233 setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2234 setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId); 2235 2236 // Refresh. 2237 ServiceStateTracker tracker = getServiceStateTracker(); 2238 if (tracker != null) { 2239 tracker.pollState(); 2240 } 2241 return true; 2242 } 2243 2244 private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) { 2245 SharedPreferences.Editor spEditor = 2246 PreferenceManager.getDefaultSharedPreferences(mContext).edit(); 2247 String key = prefix + iccId; 2248 if (list == null || list.isEmpty()) { 2249 spEditor.remove(key).commit(); 2250 } else { 2251 spEditor.putStringSet(key, new HashSet<String>(list)).commit(); 2252 } 2253 } 2254 2255 public boolean isMccMncMarkedAsRoaming(String mccMnc) { 2256 return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 2257 } 2258 2259 public boolean isMccMncMarkedAsNonRoaming(String mccMnc) { 2260 return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc); 2261 } 2262 2263 public boolean isSidMarkedAsRoaming(int SID) { 2264 return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX, 2265 Integer.toString(SID)); 2266 } 2267 2268 public boolean isSidMarkedAsNonRoaming(int SID) { 2269 return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, 2270 Integer.toString(SID)); 2271 } 2272 2273 /** 2274 * Get IMS Registration Status 2275 */ 2276 @Override 2277 public boolean isImsRegistered() { 2278 ImsPhone imsPhone = mImsPhone; 2279 boolean isImsRegistered = false; 2280 if (imsPhone != null) { 2281 isImsRegistered = imsPhone.isImsRegistered(); 2282 } else { 2283 ServiceStateTracker sst = getServiceStateTracker(); 2284 if (sst != null) { 2285 isImsRegistered = sst.isImsRegistered(); 2286 } 2287 } 2288 Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered); 2289 return isImsRegistered; 2290 } 2291 2292 /** 2293 * Get Wifi Calling Feature Availability 2294 */ 2295 @Override 2296 public boolean isWifiCallingEnabled() { 2297 ImsPhone imsPhone = mImsPhone; 2298 boolean isWifiCallingEnabled = false; 2299 if (imsPhone != null) { 2300 isWifiCallingEnabled = imsPhone.isVowifiEnabled(); 2301 } 2302 Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled); 2303 return isWifiCallingEnabled; 2304 } 2305 2306 /** 2307 * Get Volte Feature Availability 2308 */ 2309 @Override 2310 public boolean isVolteEnabled() { 2311 ImsPhone imsPhone = mImsPhone; 2312 boolean isVolteEnabled = false; 2313 if (imsPhone != null) { 2314 isVolteEnabled = imsPhone.isVolteEnabled(); 2315 } 2316 Rlog.d(LOG_TAG, "isImsRegistered =" + isVolteEnabled); 2317 return isVolteEnabled; 2318 } 2319 2320 private boolean getRoamingOverrideHelper(String prefix, String key) { 2321 String iccId = getIccSerialNumber(); 2322 if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) { 2323 return false; 2324 } 2325 2326 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 2327 Set<String> value = sp.getStringSet(prefix + iccId, null); 2328 if (value == null) { 2329 return false; 2330 } 2331 return value.contains(key); 2332 } 2333 2334 @Override 2335 public boolean isRadioAvailable() { 2336 return mCi.getRadioState().isAvailable(); 2337 } 2338 2339 @Override 2340 public boolean isRadioOn() { 2341 return mCi.getRadioState().isOn(); 2342 } 2343 2344 @Override 2345 public void shutdownRadio() { 2346 getServiceStateTracker().requestShutdown(); 2347 } 2348 2349 @Override 2350 public void setRadioCapability(RadioCapability rc, Message response) { 2351 mCi.setRadioCapability(rc, response); 2352 } 2353 2354 @Override 2355 public int getRadioAccessFamily() { 2356 final RadioCapability rc = getRadioCapability(); 2357 return (rc == null ? RadioAccessFamily.RAF_UNKNOWN : rc.getRadioAccessFamily()); 2358 } 2359 2360 @Override 2361 public String getModemUuId() { 2362 final RadioCapability rc = getRadioCapability(); 2363 return (rc == null ? "" : rc.getLogicalModemUuid()); 2364 } 2365 2366 @Override 2367 public RadioCapability getRadioCapability() { 2368 return mRadioCapability.get(); 2369 } 2370 2371 @Override 2372 public void radioCapabilityUpdated(RadioCapability rc) { 2373 // Called when radios first become available or after a capability switch 2374 // Update the cached value 2375 mRadioCapability.set(rc); 2376 2377 if (SubscriptionManager.isValidSubscriptionId(getSubId())) { 2378 sendSubscriptionSettings(true); 2379 } 2380 } 2381 2382 public void sendSubscriptionSettings(boolean restoreNetworkSelection) { 2383 // Send settings down 2384 int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId()); 2385 setPreferredNetworkType(type, null); 2386 2387 if (restoreNetworkSelection) { 2388 restoreSavedNetworkSelection(null); 2389 } 2390 mDcTracker.setDataEnabled(getDataEnabled()); 2391 } 2392 2393 protected void setPreferredNetworkTypeIfSimLoaded() { 2394 int subId = getSubId(); 2395 if (SubscriptionManager.isValidSubscriptionId(subId)) { 2396 int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId()); 2397 setPreferredNetworkType(type, null); 2398 } 2399 } 2400 2401 @Override 2402 public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) { 2403 mCi.registerForRadioCapabilityChanged(h, what, obj); 2404 } 2405 2406 @Override 2407 public void unregisterForRadioCapabilityChanged(Handler h) { 2408 mCi.unregisterForRadioCapabilityChanged(this); 2409 } 2410 2411 /** 2412 * Determines if IMS is enabled for call. 2413 * 2414 * @return {@code true} if IMS calling is enabled. 2415 */ 2416 public boolean isImsUseEnabled() { 2417 boolean imsUseEnabled = 2418 ((ImsManager.isVolteEnabledByPlatform(mContext) && 2419 ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext)) || 2420 (ImsManager.isWfcEnabledByPlatform(mContext) && 2421 ImsManager.isWfcEnabledByUser(mContext)) && 2422 ImsManager.isNonTtyOrTtyOnVolteEnabled(mContext)); 2423 return imsUseEnabled; 2424 } 2425 2426 /** 2427 * Determines if video calling is enabled for the IMS phone. 2428 * 2429 * @return {@code true} if video calling is enabled. 2430 */ 2431 @Override 2432 public boolean isVideoEnabled() { 2433 ImsPhone imsPhone = mImsPhone; 2434 if ((imsPhone != null) 2435 && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)) { 2436 return imsPhone.isVideoEnabled(); 2437 } 2438 return false; 2439 } 2440 2441 @Override 2442 public int getLceStatus() { 2443 return mLceStatus; 2444 } 2445 2446 @Override 2447 public void getModemActivityInfo(Message response) { 2448 mCi.getModemActivityInfo(response); 2449 } 2450 2451 /** 2452 * Starts LCE service after radio becomes available. 2453 * LCE service state may get destroyed on the modem when radio becomes unavailable. 2454 */ 2455 public void startLceAfterRadioIsAvailable() { 2456 if (mIsTheCurrentActivePhone) { 2457 mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE, 2458 obtainMessage(EVENT_CONFIG_LCE)); 2459 } 2460 } 2461 2462 @Override 2463 public Locale getLocaleFromSimAndCarrierPrefs() { 2464 final IccRecords records = mIccRecords.get(); 2465 if (records != null && records.getSimLanguage() != null) { 2466 return new Locale(records.getSimLanguage()); 2467 } 2468 2469 return getLocaleFromCarrierProperties(mContext); 2470 } 2471 2472 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2473 pw.println("PhoneBase: subId=" + getSubId()); 2474 pw.println(" mPhoneId=" + mPhoneId); 2475 pw.println(" mCi=" + mCi); 2476 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 2477 pw.println(" mDcTracker=" + mDcTracker); 2478 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 2479 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 2480 pw.println(" mCallRingDelay=" + mCallRingDelay); 2481 pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone); 2482 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 2483 pw.println(" mIccRecords=" + mIccRecords.get()); 2484 pw.println(" mUiccApplication=" + mUiccApplication.get()); 2485 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 2486 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 2487 pw.flush(); 2488 pw.println(" mLooper=" + mLooper); 2489 pw.println(" mContext=" + mContext); 2490 pw.println(" mNotifier=" + mNotifier); 2491 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 2492 pw.println(" mUnitTestMode=" + mUnitTestMode); 2493 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 2494 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 2495 pw.println(" getState()=" + getState()); 2496 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 2497 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 2498 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 2499 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 2500 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 2501 pw.flush(); 2502 pw.println(" isInEcm()=" + isInEcm()); 2503 pw.println(" getPhoneName()=" + getPhoneName()); 2504 pw.println(" getPhoneType()=" + getPhoneType()); 2505 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 2506 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 2507 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 2508 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 2509 pw.flush(); 2510 pw.println("++++++++++++++++++++++++++++++++"); 2511 2512 try { 2513 mDcTracker.dump(fd, pw, args); 2514 } catch (Exception e) { 2515 e.printStackTrace(); 2516 } 2517 pw.flush(); 2518 pw.println("++++++++++++++++++++++++++++++++"); 2519 2520 try { 2521 getServiceStateTracker().dump(fd, pw, args); 2522 } catch (Exception e) { 2523 e.printStackTrace(); 2524 } 2525 pw.flush(); 2526 pw.println("++++++++++++++++++++++++++++++++"); 2527 2528 try { 2529 getCallTracker().dump(fd, pw, args); 2530 } catch (Exception e) { 2531 e.printStackTrace(); 2532 } 2533 pw.flush(); 2534 pw.println("++++++++++++++++++++++++++++++++"); 2535 2536 try { 2537 ((RIL)mCi).dump(fd, pw, args); 2538 } catch (Exception e) { 2539 e.printStackTrace(); 2540 } 2541 pw.flush(); 2542 pw.println("++++++++++++++++++++++++++++++++"); 2543 } 2544 } 2545