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 static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; 20 21 import static com.android.internal.telephony.CommandException.Error.GENERIC_FAILURE; 22 import static com.android.internal.telephony.CommandException.Error.SIM_BUSY; 23 import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE; 24 import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE; 25 import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE; 26 import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION; 27 import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL; 28 import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL; 29 import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY; 30 import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE; 31 import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY; 32 import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL; 33 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE; 34 35 import android.annotation.NonNull; 36 import android.annotation.Nullable; 37 import android.app.ActivityManager; 38 import android.compat.annotation.UnsupportedAppUsage; 39 import android.content.BroadcastReceiver; 40 import android.content.ContentValues; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.IntentFilter; 44 import android.content.SharedPreferences; 45 import android.database.SQLException; 46 import android.hardware.radio.modem.ImeiInfo; 47 import android.net.Uri; 48 import android.os.AsyncResult; 49 import android.os.Build; 50 import android.os.Bundle; 51 import android.os.Handler; 52 import android.os.HandlerExecutor; 53 import android.os.Looper; 54 import android.os.Message; 55 import android.os.PersistableBundle; 56 import android.os.PowerManager; 57 import android.os.Registrant; 58 import android.os.RegistrantList; 59 import android.os.ResultReceiver; 60 import android.os.SystemProperties; 61 import android.os.UserHandle; 62 import android.os.WorkSource; 63 import android.preference.PreferenceManager; 64 import android.provider.DeviceConfig; 65 import android.provider.Settings; 66 import android.provider.Telephony; 67 import android.sysprop.TelephonyProperties; 68 import android.telecom.PhoneAccount; 69 import android.telecom.PhoneAccountHandle; 70 import android.telecom.TelecomManager; 71 import android.telecom.VideoProfile; 72 import android.telephony.AccessNetworkConstants.TransportType; 73 import android.telephony.Annotation.DataActivityType; 74 import android.telephony.Annotation.RadioPowerState; 75 import android.telephony.BarringInfo; 76 import android.telephony.CarrierConfigManager; 77 import android.telephony.CellBroadcastIdRange; 78 import android.telephony.CellIdentity; 79 import android.telephony.CellularIdentifierDisclosure; 80 import android.telephony.ImsiEncryptionInfo; 81 import android.telephony.LinkCapacityEstimate; 82 import android.telephony.NetworkScanRequest; 83 import android.telephony.PhoneNumberUtils; 84 import android.telephony.RadioAccessFamily; 85 import android.telephony.SecurityAlgorithmUpdate; 86 import android.telephony.ServiceState; 87 import android.telephony.ServiceState.RilRadioTechnology; 88 import android.telephony.SubscriptionInfo; 89 import android.telephony.SubscriptionManager; 90 import android.telephony.TelephonyManager; 91 import android.telephony.UiccAccessRule; 92 import android.telephony.UssdResponse; 93 import android.telephony.ims.ImsCallProfile; 94 import android.text.TextUtils; 95 import android.util.ArraySet; 96 import android.util.Log; 97 import android.util.Pair; 98 99 import com.android.ims.ImsManager; 100 import com.android.internal.annotations.VisibleForTesting; 101 import com.android.internal.telephony.cdma.CdmaMmiCode; 102 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 103 import com.android.internal.telephony.data.AccessNetworksManager; 104 import com.android.internal.telephony.data.DataNetworkController; 105 import com.android.internal.telephony.data.LinkBandwidthEstimator; 106 import com.android.internal.telephony.domainselection.DomainSelectionResolver; 107 import com.android.internal.telephony.emergency.EmergencyNumberTracker; 108 import com.android.internal.telephony.emergency.EmergencyStateTracker; 109 import com.android.internal.telephony.flags.FeatureFlags; 110 import com.android.internal.telephony.gsm.GsmMmiCode; 111 import com.android.internal.telephony.gsm.SsData; 112 import com.android.internal.telephony.gsm.SuppServiceNotification; 113 import com.android.internal.telephony.imsphone.ImsPhone; 114 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker; 115 import com.android.internal.telephony.imsphone.ImsPhoneMmiCode; 116 import com.android.internal.telephony.metrics.TelephonyMetrics; 117 import com.android.internal.telephony.metrics.VoiceCallSessionStats; 118 import com.android.internal.telephony.security.CellularIdentifierDisclosureNotifier; 119 import com.android.internal.telephony.security.CellularNetworkSecuritySafetySource; 120 import com.android.internal.telephony.security.NullCipherNotifier; 121 import com.android.internal.telephony.subscription.SubscriptionInfoInternal; 122 import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback; 123 import com.android.internal.telephony.test.SimulatedRadioControl; 124 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 125 import com.android.internal.telephony.uicc.IccCardStatus; 126 import com.android.internal.telephony.uicc.IccException; 127 import com.android.internal.telephony.uicc.IccRecords; 128 import com.android.internal.telephony.uicc.IccUtils; 129 import com.android.internal.telephony.uicc.IccVmNotSupportedException; 130 import com.android.internal.telephony.uicc.IsimRecords; 131 import com.android.internal.telephony.uicc.IsimUiccRecords; 132 import com.android.internal.telephony.uicc.RuimRecords; 133 import com.android.internal.telephony.uicc.SIMRecords; 134 import com.android.internal.telephony.uicc.UiccCardApplication; 135 import com.android.internal.telephony.uicc.UiccController; 136 import com.android.internal.telephony.uicc.UiccPort; 137 import com.android.internal.telephony.uicc.UiccProfile; 138 import com.android.internal.telephony.uicc.UiccSlot; 139 import com.android.internal.telephony.util.ArrayUtils; 140 import com.android.telephony.Rlog; 141 142 import java.io.FileDescriptor; 143 import java.io.PrintWriter; 144 import java.util.ArrayList; 145 import java.util.Arrays; 146 import java.util.Collections; 147 import java.util.Iterator; 148 import java.util.List; 149 import java.util.Locale; 150 import java.util.Set; 151 import java.util.function.Consumer; 152 import java.util.regex.Matcher; 153 import java.util.regex.Pattern; 154 155 /** 156 * {@hide} 157 */ 158 public class GsmCdmaPhone extends Phone { 159 // NOTE that LOG_TAG here is "GsmCdma", which means that log messages 160 // from this file will go into the radio log rather than the main 161 // log. (Use "adb logcat -b radio" to see them.) 162 public static final String LOG_TAG = "GsmCdmaPhone"; 163 private static final boolean DBG = true; 164 private static final boolean VDBG = false; /* STOPSHIP if true */ 165 166 /** Required throughput change between unsolicited LinkCapacityEstimate reports. */ 167 private static final int REPORTING_HYSTERESIS_KBPS = 50; 168 /** Minimum time between unsolicited LinkCapacityEstimate reports. */ 169 private static final int REPORTING_HYSTERESIS_MILLIS = 3000; 170 171 //GSM 172 // Key used to read/write voice mail number 173 private static final String VM_NUMBER = "vm_number_key"; 174 // Key used to read/write the SIM IMSI used for storing the voice mail 175 private static final String VM_SIM_IMSI = "vm_sim_imsi_key"; 176 /** List of Registrants to receive Supplementary Service Notifications. */ 177 // Key used to read/write the current sub Id. Updated on SIM loaded. 178 public static final String CURR_SUBID = "curr_subid"; 179 private RegistrantList mSsnRegistrants = new RegistrantList(); 180 181 //CDMA 182 // Default Emergency Callback Mode exit timer 183 private static final long DEFAULT_ECM_EXIT_TIMER_VALUE = 300000; 184 private static final String VM_NUMBER_CDMA = "vm_number_key_cdma"; 185 public static final int RESTART_ECM_TIMER = 0; // restart Ecm timer 186 public static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer 187 private CdmaSubscriptionSourceManager mCdmaSSM; 188 public int mCdmaSubscriptionSource = CdmaSubscriptionSourceManager.SUBSCRIPTION_SOURCE_UNKNOWN; 189 private PowerManager.WakeLock mWakeLock; 190 // mEcmExitRespRegistrant is informed after the phone has been exited 191 @UnsupportedAppUsage 192 private Registrant mEcmExitRespRegistrant; 193 private String mEsn; 194 private String mMeid; 195 // string to define how the carrier specifies its own ota sp number 196 private String mCarrierOtaSpNumSchema; 197 private Boolean mUiccApplicationsEnabled = null; 198 // keeps track of when we have triggered an emergency call due to the ril.test.emergencynumber 199 // param being set and we should generate a simulated exit from the modem upon exit of ECbM. 200 private boolean mIsTestingEmergencyCallbackMode = false; 201 @VisibleForTesting 202 public static int ENABLE_UICC_APPS_MAX_RETRIES = 3; 203 private static final int REAPPLY_UICC_APPS_SETTING_RETRY_TIME_GAP_IN_MS = 5000; 204 205 // A runnable which is used to automatically exit from Ecm after a period of time. 206 private Runnable mExitEcmRunnable = new Runnable() { 207 @Override 208 public void run() { 209 exitEmergencyCallbackMode(); 210 } 211 }; 212 public static final String PROPERTY_CDMA_HOME_OPERATOR_NUMERIC = 213 "ro.cdma.home.operator.numeric"; 214 215 //CDMALTE 216 /** PHONE_TYPE_CDMA_LTE in addition to RuimRecords needs access to SIMRecords and 217 * IsimUiccRecords 218 */ 219 private SIMRecords mSimRecords; 220 221 // For non-persisted manual network selection 222 private String mManualNetworkSelectionPlmn; 223 224 //Common 225 // Instance Variables 226 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 227 private IsimUiccRecords mIsimUiccRecords; 228 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 229 public GsmCdmaCallTracker mCT; 230 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 231 public ServiceStateTracker mSST; 232 public EmergencyNumberTracker mEmergencyNumberTracker; 233 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 234 private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>(); 235 private IccPhoneBookInterfaceManager mIccPhoneBookIntManager; 236 237 private int mPrecisePhoneType; 238 239 // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started 240 private final RegistrantList mEcmTimerResetRegistrants = new RegistrantList(); 241 242 private final RegistrantList mVolteSilentRedialRegistrants = new RegistrantList(); 243 private DialArgs mDialArgs = null; 244 private final RegistrantList mEmergencyDomainSelectedRegistrants = new RegistrantList(); 245 private String mImei; 246 private String mImeiSv; 247 private String mVmNumber; 248 private int mImeiType = IMEI_TYPE_UNKNOWN; 249 private int mSimState = TelephonyManager.SIM_STATE_UNKNOWN; 250 251 @VisibleForTesting 252 public CellBroadcastConfigTracker mCellBroadcastConfigTracker = 253 CellBroadcastConfigTracker.make(this, null, true); 254 255 private boolean mIsNullCipherAndIntegritySupported = false; 256 private boolean mIsIdentifierDisclosureTransparencySupported = false; 257 private boolean mIsNullCipherNotificationSupported = false; 258 259 // Create Cfu (Call forward unconditional) so that dialing number & 260 // mOnComplete (Message object passed by client) can be packed & 261 // given as a single Cfu object as user data to RIL. 262 private static class Cfu { 263 final String mSetCfNumber; 264 final Message mOnComplete; 265 266 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Cfu(String cfNumber, Message onComplete)267 Cfu(String cfNumber, Message onComplete) { 268 mSetCfNumber = cfNumber; 269 mOnComplete = onComplete; 270 } 271 } 272 273 /** 274 * Used to create ImsManager instances, which may be injected during testing. 275 */ 276 @VisibleForTesting 277 public interface ImsManagerFactory { 278 /** 279 * Create a new instance of ImsManager for the specified phoneId. 280 */ create(Context context, int phoneId)281 ImsManager create(Context context, int phoneId); 282 } 283 284 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 285 private IccSmsInterfaceManager mIccSmsInterfaceManager; 286 287 private boolean mResetModemOnRadioTechnologyChange = false; 288 private boolean mSsOverCdmaSupported = false; 289 290 private int mRilVersion; 291 private boolean mBroadcastEmergencyCallStateChanges = false; 292 private @ServiceState.RegState int mTelecomVoiceServiceStateOverride = 293 ServiceState.STATE_OUT_OF_SERVICE; 294 295 private CarrierKeyDownloadManager mCDM; 296 private CarrierInfoManager mCIM; 297 298 private final ImsManagerFactory mImsManagerFactory; 299 private final CarrierPrivilegesTracker mCarrierPrivilegesTracker; 300 301 private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener; 302 private final CallWaitingController mCallWaitingController; 303 304 private CellularNetworkSecuritySafetySource mSafetySource; 305 private CellularIdentifierDisclosureNotifier mIdentifierDisclosureNotifier; 306 private NullCipherNotifier mNullCipherNotifier; 307 308 /** 309 * Temporary placeholder variables until b/312788638 is resolved, whereupon these should be 310 * ported to TelephonyManager. 311 */ 312 // Set via Carrier Config 313 private static final Integer N1_MODE_DISALLOWED_REASON_CARRIER = 1; 314 // Set via a call to the method on Phone; the only caller is IMS, and all of this code will 315 // need to be updated to a voting mechanism (...enabled for reason...) if additional callers 316 // are desired. 317 private static final Integer N1_MODE_DISALLOWED_REASON_IMS = 2; 318 319 // Set of use callers/reasons why N1 Mode is disallowed. If the set is empty, it's allowed. 320 private final Set<Integer> mN1ModeDisallowedReasons = new ArraySet<>(); 321 322 // If this value is null, then the modem value is unknown. If a caller explicitly sets the 323 // N1 mode, this value will be initialized before any attempt to set the value in the modem. 324 private Boolean mModemN1Mode = null; 325 326 // Constructors 327 GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, int phoneId, int precisePhoneType, TelephonyComponentFactory telephonyComponentFactory, @NonNull FeatureFlags featureFlags)328 public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, int phoneId, 329 int precisePhoneType, TelephonyComponentFactory telephonyComponentFactory, 330 @NonNull FeatureFlags featureFlags) { 331 this(context, ci, notifier, false, phoneId, precisePhoneType, telephonyComponentFactory, 332 featureFlags); 333 } 334 GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode, int phoneId, int precisePhoneType, TelephonyComponentFactory telephonyComponentFactory, @NonNull FeatureFlags featureFlags)335 public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, 336 boolean unitTestMode, int phoneId, int precisePhoneType, 337 TelephonyComponentFactory telephonyComponentFactory, 338 @NonNull FeatureFlags featureFlags) { 339 this(context, ci, notifier, 340 unitTestMode, phoneId, precisePhoneType, 341 telephonyComponentFactory, 342 ImsManager::getInstance, featureFlags); 343 } 344 GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode, int phoneId, int precisePhoneType, TelephonyComponentFactory telephonyComponentFactory, ImsManagerFactory imsManagerFactory, @NonNull FeatureFlags featureFlags)345 public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, 346 boolean unitTestMode, int phoneId, int precisePhoneType, 347 TelephonyComponentFactory telephonyComponentFactory, 348 ImsManagerFactory imsManagerFactory, @NonNull FeatureFlags featureFlags) { 349 super(precisePhoneType == PhoneConstants.PHONE_TYPE_GSM ? "GSM" : "CDMA", 350 notifier, context, ci, unitTestMode, phoneId, telephonyComponentFactory, 351 featureFlags); 352 // phone type needs to be set before other initialization as other objects rely on it 353 mPrecisePhoneType = precisePhoneType; 354 mVoiceCallSessionStats = new VoiceCallSessionStats(mPhoneId, this, featureFlags); 355 mImsManagerFactory = imsManagerFactory; 356 initOnce(ci); 357 initRatSpecific(precisePhoneType); 358 // CarrierSignalAgent uses CarrierActionAgent in construction so it needs to be created 359 // after CarrierActionAgent. 360 mCarrierActionAgent = mTelephonyComponentFactory.inject(CarrierActionAgent.class.getName()) 361 .makeCarrierActionAgent(this); 362 mCarrierSignalAgent = mTelephonyComponentFactory.inject(CarrierSignalAgent.class.getName()) 363 .makeCarrierSignalAgent(this); 364 mAccessNetworksManager = mTelephonyComponentFactory 365 .inject(AccessNetworksManager.class.getName()) 366 .makeAccessNetworksManager(this, getLooper()); 367 // SST/DSM depends on SSC, so SSC is instanced before SST/DSM 368 mSignalStrengthController = mTelephonyComponentFactory.inject( 369 SignalStrengthController.class.getName()).makeSignalStrengthController(this); 370 mSST = mTelephonyComponentFactory.inject(ServiceStateTracker.class.getName()) 371 .makeServiceStateTracker(this, this.mCi, featureFlags); 372 if (hasCalling() || hasMessaging()) { 373 mEmergencyNumberTracker = mTelephonyComponentFactory 374 .inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker( 375 this, this.mCi, mFeatureFlags); 376 } 377 mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName()) 378 .makeDeviceStateMonitor(this, mFeatureFlags); 379 380 // DisplayInfoController creates an OverrideNetworkTypeController, which uses 381 // DeviceStateMonitor so needs to be crated after it is instantiated. 382 mDisplayInfoController = mTelephonyComponentFactory.inject( 383 DisplayInfoController.class.getName()) 384 .makeDisplayInfoController(this, featureFlags); 385 386 mDataNetworkController = mTelephonyComponentFactory.inject( 387 DataNetworkController.class.getName()) 388 .makeDataNetworkController(this, getLooper(), featureFlags); 389 390 mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName()) 391 .makeCarrierResolver(this, featureFlags); 392 mCarrierPrivilegesTracker = new CarrierPrivilegesTracker( 393 Looper.myLooper(), this, context, featureFlags); 394 395 getCarrierActionAgent().registerForCarrierAction( 396 CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this, 397 EVENT_SET_CARRIER_DATA_ENABLED, null, false); 398 399 mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); 400 mSST.registerForVoiceRegStateOrRatChanged(this, EVENT_VRS_OR_RAT_CHANGED, null); 401 mSST.getServiceStateStats().registerDataNetworkControllerCallback(); 402 403 mSubscriptionManagerService.registerCallback(new SubscriptionManagerServiceCallback( 404 this::post) { 405 @Override 406 public void onUiccApplicationsEnabledChanged(int subId) { 407 reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES); 408 } 409 }); 410 411 mLinkBandwidthEstimator = mTelephonyComponentFactory 412 .inject(LinkBandwidthEstimator.class.getName()) 413 .makeLinkBandwidthEstimator(this, getLooper()); 414 415 mCallWaitingController = new CallWaitingController(this); 416 417 if (hasCalling()) { 418 loadTtyMode(); 419 420 CallManager.getInstance().registerPhone(this); 421 } 422 423 mSubscriptionsChangedListener = 424 new SubscriptionManager.OnSubscriptionsChangedListener() { 425 @Override 426 public void onSubscriptionsChanged() { 427 sendEmptyMessage(EVENT_SUBSCRIPTIONS_CHANGED); 428 } 429 }; 430 431 SubscriptionManager subMan = context.getSystemService(SubscriptionManager.class); 432 subMan.addOnSubscriptionsChangedListener( 433 new HandlerExecutor(this), mSubscriptionsChangedListener); 434 435 logd("GsmCdmaPhone: constructor: sub = " + mPhoneId); 436 } 437 438 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 439 @Override 440 public void onReceive(Context context, Intent intent) { 441 Rlog.d(LOG_TAG, "mBroadcastReceiver: action " + intent.getAction()); 442 String action = intent.getAction(); 443 if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) { 444 // Only handle carrier config changes for this phone id. 445 if (mPhoneId == intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, -1)) { 446 sendMessage(obtainMessage(EVENT_CARRIER_CONFIG_CHANGED)); 447 } 448 } else if (TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED.equals(action)) { 449 int ttyMode = intent.getIntExtra( 450 TelecomManager.EXTRA_CURRENT_TTY_MODE, TelecomManager.TTY_MODE_OFF); 451 updateTtyMode(ttyMode); 452 } else if (TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED.equals(action)) { 453 int newPreferredTtyMode = intent.getIntExtra( 454 TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF); 455 updateUiTtyMode(newPreferredTtyMode); 456 } else if (TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED.equals(action)) { 457 if (mPhoneId == intent.getIntExtra( 458 SubscriptionManager.EXTRA_SLOT_INDEX, 459 SubscriptionManager.INVALID_SIM_SLOT_INDEX)) { 460 mSimState = intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE, 461 TelephonyManager.SIM_STATE_UNKNOWN); 462 if (mSimState == TelephonyManager.SIM_STATE_LOADED 463 && currentSlotSubIdChanged()) { 464 setNetworkSelectionModeAutomatic(null); 465 } 466 } 467 } 468 } 469 }; 470 initOnce(CommandsInterface ci)471 private void initOnce(CommandsInterface ci) { 472 if (ci instanceof SimulatedRadioControl) { 473 mSimulatedRadioControl = (SimulatedRadioControl) ci; 474 } 475 476 if (hasCalling()) { 477 mCT = mTelephonyComponentFactory.inject(GsmCdmaCallTracker.class.getName()) 478 .makeGsmCdmaCallTracker(this, mFeatureFlags); 479 } 480 mIccPhoneBookIntManager = mTelephonyComponentFactory 481 .inject(IccPhoneBookInterfaceManager.class.getName()) 482 .makeIccPhoneBookInterfaceManager(this); 483 PowerManager pm 484 = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 485 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); 486 mIccSmsInterfaceManager = mTelephonyComponentFactory 487 .inject(IccSmsInterfaceManager.class.getName()) 488 .makeIccSmsInterfaceManager(this, mFeatureFlags); 489 490 mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); 491 mCi.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); 492 mCi.registerForOn(this, EVENT_RADIO_ON, null); 493 mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); 494 mCi.registerUiccApplicationEnablementChanged(this, 495 EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED, 496 null); 497 mCi.setOnSuppServiceNotification(this, EVENT_SSN, null); 498 mCi.setOnRegistrationFailed(this, EVENT_REGISTRATION_FAILED, null); 499 mCi.registerForBarringInfoChanged(this, EVENT_BARRING_INFO_CHANGED, null); 500 501 //GSM 502 mCi.setOnUSSD(this, EVENT_USSD, null); 503 mCi.setOnSs(this, EVENT_SS, null); 504 505 //CDMA 506 mCdmaSSM = mTelephonyComponentFactory.inject(CdmaSubscriptionSourceManager.class.getName()) 507 .getCdmaSubscriptionSourceManagerInstance(mContext, 508 mCi, this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); 509 mCi.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null); 510 mCi.registerForExitEmergencyCallbackMode(this, EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE, 511 null); 512 mCi.registerForModemReset(this, EVENT_MODEM_RESET, null); 513 // get the string that specifies the carrier OTA Sp number 514 mCarrierOtaSpNumSchema = TelephonyManager.from(mContext).getOtaSpNumberSchemaForPhone( 515 getPhoneId(), ""); 516 517 mResetModemOnRadioTechnologyChange = TelephonyProperties.reset_on_radio_tech_change() 518 .orElse(false); 519 520 mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); 521 mCi.registerForVoiceRadioTechChanged(this, EVENT_VOICE_RADIO_TECH_CHANGED, null); 522 mCi.registerForLceInfo(this, EVENT_LINK_CAPACITY_CHANGED, null); 523 mCi.registerForCarrierInfoForImsiEncryption(this, 524 EVENT_RESET_CARRIER_KEY_IMSI_ENCRYPTION, null); 525 mCi.registerForTriggerImsDeregistration(this, EVENT_IMS_DEREGISTRATION_TRIGGERED, null); 526 mCi.registerForNotifyAnbr(this, EVENT_TRIGGER_NOTIFY_ANBR, null); 527 IntentFilter filter = new IntentFilter( 528 CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 529 filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED); 530 filter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED); 531 filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED); 532 mContext.registerReceiver(mBroadcastReceiver, filter, 533 android.Manifest.permission.MODIFY_PHONE_STATE, null, Context.RECEIVER_EXPORTED); 534 535 mCDM = new CarrierKeyDownloadManager(this); 536 mCIM = new CarrierInfoManager(); 537 538 mCi.registerForImeiMappingChanged(this, EVENT_IMEI_MAPPING_CHANGED, null); 539 540 mSafetySource = mTelephonyComponentFactory 541 .makeCellularNetworkSecuritySafetySource(mContext); 542 543 logi( 544 "enable_identifier_disclosure_transparency_unsol_events is on. Registering for " 545 + "cellular identifier disclosures from phone " 546 + getPhoneId()); 547 mIdentifierDisclosureNotifier = 548 mTelephonyComponentFactory 549 .inject(CellularIdentifierDisclosureNotifier.class.getName()) 550 .makeIdentifierDisclosureNotifier(mSafetySource); 551 mCi.registerForCellularIdentifierDisclosures( 552 this, EVENT_CELL_IDENTIFIER_DISCLOSURE, null); 553 554 logi( 555 "enable_modem_cipher_transparency_unsol_events is on. Registering for security " 556 + "algorithm updates from phone " 557 + getPhoneId()); 558 mNullCipherNotifier = 559 mTelephonyComponentFactory 560 .inject(NullCipherNotifier.class.getName()) 561 .makeNullCipherNotifier(mSafetySource); 562 mCi.registerForSecurityAlgorithmUpdates( 563 this, EVENT_SECURITY_ALGORITHM_UPDATE, null); 564 565 initializeCarrierApps(); 566 } 567 initRatSpecific(int precisePhoneType)568 private void initRatSpecific(int precisePhoneType) { 569 mPendingMMIs.clear(); 570 mIccPhoneBookIntManager.updateIccRecords(null); 571 572 mPrecisePhoneType = precisePhoneType; 573 logd("Precise phone type " + mPrecisePhoneType); 574 575 TelephonyManager tm = TelephonyManager.from(mContext); 576 UiccProfile uiccProfile = getUiccProfile(); 577 if (isPhoneTypeGsm()) { 578 mCi.setPhoneType(PhoneConstants.PHONE_TYPE_GSM); 579 tm.setPhoneType(getPhoneId(), PhoneConstants.PHONE_TYPE_GSM); 580 if (uiccProfile != null) { 581 uiccProfile.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS); 582 } 583 } else { 584 mCdmaSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource(); 585 // This is needed to handle phone process crashes 586 mIsPhoneInEcmState = getInEcmMode(); 587 if (mIsPhoneInEcmState) { 588 if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { 589 EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(); 590 } else { 591 // Send a message which will invoke handleExitEmergencyCallbackMode 592 mCi.exitEmergencyCallbackMode(null); 593 } 594 } 595 596 mCi.setPhoneType(PhoneConstants.PHONE_TYPE_CDMA); 597 tm.setPhoneType(getPhoneId(), PhoneConstants.PHONE_TYPE_CDMA); 598 if (uiccProfile != null) { 599 uiccProfile.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT); 600 } 601 // Sets operator properties by retrieving from build-time system property 602 String operatorAlpha = SystemProperties.get("ro.cdma.home.operator.alpha"); 603 String operatorNumeric = SystemProperties.get(PROPERTY_CDMA_HOME_OPERATOR_NUMERIC); 604 logd("init: operatorAlpha='" + operatorAlpha 605 + "' operatorNumeric='" + operatorNumeric + "'"); 606 if (!TextUtils.isEmpty(operatorAlpha)) { 607 logd("init: set 'gsm.sim.operator.alpha' to operator='" + operatorAlpha + "'"); 608 tm.setSimOperatorNameForPhone(mPhoneId, operatorAlpha); 609 } 610 if (!TextUtils.isEmpty(operatorNumeric)) { 611 logd("init: set 'gsm.sim.operator.numeric' to operator='" + operatorNumeric + 612 "'"); 613 logd("update icc_operator_numeric=" + operatorNumeric); 614 tm.setSimOperatorNumericForPhone(mPhoneId, operatorNumeric); 615 616 mSubscriptionManagerService.setMccMnc(getSubId(), operatorNumeric); 617 618 // Sets iso country property by retrieving from build-time system property 619 String iso = ""; 620 try { 621 iso = MccTable.countryCodeForMcc(operatorNumeric.substring(0, 3)); 622 } catch (StringIndexOutOfBoundsException ex) { 623 Rlog.e(LOG_TAG, "init: countryCodeForMcc error", ex); 624 } 625 626 logd("init: set 'gsm.sim.operator.iso-country' to iso=" + iso); 627 tm.setSimCountryIsoForPhone(mPhoneId, iso); 628 mSubscriptionManagerService.setCountryIso(getSubId(), iso); 629 630 // Updates MCC MNC device configuration information 631 logd("update mccmnc=" + operatorNumeric); 632 MccTable.updateMccMncConfiguration(mContext, operatorNumeric); 633 } 634 635 // Sets current entry in the telephony carrier table 636 updateCurrentCarrierInProvider(operatorNumeric); 637 } 638 } 639 640 /** 641 * Initialize the carrier apps. 642 */ initializeCarrierApps()643 private void initializeCarrierApps() { 644 // Only perform on the default phone. There is no need to do it twice on the DSDS device. 645 if (mPhoneId != 0) return; 646 647 logd("initializeCarrierApps"); 648 mContext.registerReceiverForAllUsers(new BroadcastReceiver() { 649 @Override 650 public void onReceive(Context context, Intent intent) { 651 // Remove this line after testing 652 if (Intent.ACTION_USER_FOREGROUND.equals(intent.getAction())) { 653 UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER); 654 // If couldn't get current user ID, guess it's 0. 655 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), 656 TelephonyManager.getDefault(), 657 userHandle != null ? userHandle.getIdentifier() : 0, mContext); 658 } 659 } 660 }, new IntentFilter(Intent.ACTION_USER_FOREGROUND), null, null); 661 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), 662 TelephonyManager.getDefault(), ActivityManager.getCurrentUser(), mContext); 663 } 664 665 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isPhoneTypeGsm()666 public boolean isPhoneTypeGsm() { 667 return mPrecisePhoneType == PhoneConstants.PHONE_TYPE_GSM; 668 } 669 isPhoneTypeCdma()670 public boolean isPhoneTypeCdma() { 671 return mPrecisePhoneType == PhoneConstants.PHONE_TYPE_CDMA; 672 } 673 isPhoneTypeCdmaLte()674 public boolean isPhoneTypeCdmaLte() { 675 return mPrecisePhoneType == PhoneConstants.PHONE_TYPE_CDMA_LTE; 676 } 677 switchPhoneType(int precisePhoneType)678 private void switchPhoneType(int precisePhoneType) { 679 removeCallbacks(mExitEcmRunnable); 680 681 initRatSpecific(precisePhoneType); 682 683 mSST.updatePhoneType(); 684 setPhoneName(precisePhoneType == PhoneConstants.PHONE_TYPE_GSM ? "GSM" : "CDMA"); 685 onUpdateIccAvailability(); 686 // if is possible that onUpdateIccAvailability() does not unregister and re-register for 687 // ICC events, for example if mUiccApplication does not change which can happen if phone 688 // type is transitioning from CDMA to GSM but 3gpp2 application was not available. 689 // To handle such cases, unregister and re-register here. They still need to be called in 690 // onUpdateIccAvailability(), since in normal cases register/unregister calls can be on 691 // different IccRecords objects. Here they are on the same IccRecords object. 692 unregisterForIccRecordEvents(); 693 registerForIccRecordEvents(); 694 695 if (mCT != null) mCT.updatePhoneType(); 696 697 int radioState = mCi.getRadioState(); 698 if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE) { 699 handleRadioAvailable(); 700 if (radioState == TelephonyManager.RADIO_POWER_ON) { 701 handleRadioOn(); 702 } 703 } 704 if (radioState != TelephonyManager.RADIO_POWER_ON) { 705 handleRadioOffOrNotAvailable(); 706 } 707 } 708 updateLinkCapacityEstimate(List<LinkCapacityEstimate> linkCapacityEstimateList)709 private void updateLinkCapacityEstimate(List<LinkCapacityEstimate> linkCapacityEstimateList) { 710 if (DBG) logd("updateLinkCapacityEstimate: lce list=" + linkCapacityEstimateList); 711 if (linkCapacityEstimateList == null) { 712 return; 713 } 714 notifyLinkCapacityEstimateChanged(linkCapacityEstimateList); 715 } 716 717 @Override finalize()718 protected void finalize() { 719 if(DBG) logd("GsmCdmaPhone finalized"); 720 if (mWakeLock != null && mWakeLock.isHeld()) { 721 Rlog.e(LOG_TAG, "UNEXPECTED; mWakeLock is held when finalizing."); 722 mWakeLock.release(); 723 } 724 } 725 726 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 727 @Override 728 @NonNull getServiceState()729 public ServiceState getServiceState() { 730 ServiceState baseSs = mSST != null ? mSST.getServiceState() : new ServiceState(); 731 ServiceState imsSs = mImsPhone != null ? mImsPhone.getServiceState() : new ServiceState(); 732 return mergeVoiceServiceStates(baseSs, imsSs, mTelecomVoiceServiceStateOverride); 733 } 734 735 @Override setVoiceServiceStateOverride(boolean hasService)736 public void setVoiceServiceStateOverride(boolean hasService) { 737 int newOverride = 738 hasService ? ServiceState.STATE_IN_SERVICE : ServiceState.STATE_OUT_OF_SERVICE; 739 boolean changed = newOverride != mTelecomVoiceServiceStateOverride; 740 mTelecomVoiceServiceStateOverride = newOverride; 741 if (changed && mSST != null) { 742 mSST.onTelecomVoiceServiceStateOverrideChanged(); 743 mSST.getServiceStateStats().onVoiceServiceStateOverrideChanged(hasService); 744 } 745 } 746 747 @Override getCellIdentity(WorkSource workSource, Message rspMsg)748 public void getCellIdentity(WorkSource workSource, Message rspMsg) { 749 mSST.requestCellIdentity(workSource, rspMsg); 750 } 751 752 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 753 @Override getState()754 public PhoneConstants.State getState() { 755 if (!hasCalling()) return PhoneConstants.State.IDLE; 756 757 if (mImsPhone != null) { 758 PhoneConstants.State imsState = mImsPhone.getState(); 759 if (imsState != PhoneConstants.State.IDLE) { 760 return imsState; 761 } 762 } 763 764 return mCT.mState; 765 } 766 767 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 768 @Override getPhoneType()769 public int getPhoneType() { 770 if (mFeatureFlags.cleanupCdma()) return PhoneConstants.PHONE_TYPE_GSM; 771 if (mPrecisePhoneType == PhoneConstants.PHONE_TYPE_GSM) { 772 return PhoneConstants.PHONE_TYPE_GSM; 773 } else { 774 return PhoneConstants.PHONE_TYPE_CDMA; 775 } 776 } 777 778 @Override getServiceStateTracker()779 public ServiceStateTracker getServiceStateTracker() { 780 return mSST; 781 } 782 783 @Override getEmergencyNumberTracker()784 public EmergencyNumberTracker getEmergencyNumberTracker() { 785 return mEmergencyNumberTracker; 786 } 787 788 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 789 @Override getCallTracker()790 public CallTracker getCallTracker() { 791 return mCT; 792 } 793 794 @Override getAccessNetworksManager()795 public AccessNetworksManager getAccessNetworksManager() { 796 return mAccessNetworksManager; 797 } 798 799 @Override getDeviceStateMonitor()800 public DeviceStateMonitor getDeviceStateMonitor() { 801 return mDeviceStateMonitor; 802 } 803 804 @Override getDisplayInfoController()805 public DisplayInfoController getDisplayInfoController() { 806 return mDisplayInfoController; 807 } 808 809 @Override getSignalStrengthController()810 public SignalStrengthController getSignalStrengthController() { 811 return mSignalStrengthController; 812 } 813 814 @Override updateVoiceMail()815 public void updateVoiceMail() { 816 if (isPhoneTypeGsm()) { 817 int countVoiceMessages = 0; 818 IccRecords r = mIccRecords.get(); 819 if (r != null) { 820 // get voice mail count from SIM 821 countVoiceMessages = r.getVoiceMessageCount(); 822 } 823 if (countVoiceMessages == IccRecords.DEFAULT_VOICE_MESSAGE_COUNT) { 824 countVoiceMessages = getStoredVoiceMessageCount(); 825 } 826 logd("updateVoiceMail countVoiceMessages = " + countVoiceMessages 827 + " subId " + getSubId()); 828 setVoiceMessageCount(countVoiceMessages); 829 } else { 830 setVoiceMessageCount(getStoredVoiceMessageCount()); 831 } 832 } 833 834 @Override 835 public List<? extends MmiCode> getPendingMmiCodes()836 getPendingMmiCodes() { 837 return mPendingMMIs; 838 } 839 840 @Override isDataSuspended()841 public boolean isDataSuspended() { 842 if (mCT == null) return false; 843 return mCT.mState != PhoneConstants.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed(); 844 } 845 846 @Override getDataActivityState()847 public @DataActivityType int getDataActivityState() { 848 return getDataNetworkController().getDataActivity(); 849 } 850 851 /** 852 * Notify any interested party of a Phone state change 853 * {@link com.android.internal.telephony.PhoneConstants.State} 854 */ notifyPhoneStateChanged()855 public void notifyPhoneStateChanged() { 856 mNotifier.notifyPhoneState(this); 857 } 858 859 /** 860 * Notify registrants of a change in the call state. This notifies changes in 861 * {@link com.android.internal.telephony.Call.State}. Use this when changes 862 * in the precise call state are needed, else use notifyPhoneStateChanged. 863 */ 864 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) notifyPreciseCallStateChanged()865 public void notifyPreciseCallStateChanged() { 866 /* we'd love it if this was package-scoped*/ 867 AsyncResult ar = new AsyncResult(null, this, null); 868 mPreciseCallStateRegistrants.notifyRegistrants(ar); 869 870 mNotifier.notifyPreciseCallState(this, null, null, null); 871 } 872 notifyNewRingingConnection(Connection c)873 public void notifyNewRingingConnection(Connection c) { 874 super.notifyNewRingingConnectionP(c); 875 } 876 notifyDisconnect(Connection cn)877 public void notifyDisconnect(Connection cn) { 878 mDisconnectRegistrants.notifyResult(cn); 879 880 mNotifier.notifyDisconnectCause(this, cn.getDisconnectCause(), 881 cn.getPreciseDisconnectCause()); 882 } 883 notifyUnknownConnection(Connection cn)884 public void notifyUnknownConnection(Connection cn) { 885 super.notifyUnknownConnectionP(cn); 886 } 887 888 @Override isInEmergencyCall()889 public boolean isInEmergencyCall() { 890 if (!hasCalling() || isPhoneTypeGsm()) { 891 return false; 892 } else { 893 return mCT.isInEmergencyCall(); 894 } 895 } 896 897 @Override setIsInEmergencyCall()898 protected void setIsInEmergencyCall() { 899 if (!hasCalling() && !isPhoneTypeGsm()) { 900 mCT.setIsInEmergencyCall(); 901 } 902 } 903 904 @Override isInEmergencySmsMode()905 public boolean isInEmergencySmsMode() { 906 return super.isInEmergencySmsMode() 907 || (mImsPhone != null && mImsPhone.isInEmergencySmsMode()); 908 } 909 910 //CDMA sendEmergencyCallbackModeChange()911 private void sendEmergencyCallbackModeChange(){ 912 //Send an Intent 913 Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); 914 intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, isInEcm()); 915 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, getPhoneId()); 916 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 917 logi("sendEmergencyCallbackModeChange"); 918 } 919 920 @Override sendEmergencyCallStateChange(boolean callActive)921 public void sendEmergencyCallStateChange(boolean callActive) { 922 if (!isPhoneTypeCdma()) { 923 // It possible that this method got called from ImsPhoneCallTracker# 924 logi("sendEmergencyCallStateChange - skip for non-cdma"); 925 return; 926 } 927 if (mBroadcastEmergencyCallStateChanges) { 928 Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED); 929 intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, callActive); 930 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, getPhoneId()); 931 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 932 if (DBG) Rlog.d(LOG_TAG, "sendEmergencyCallStateChange: callActive " + callActive); 933 } 934 } 935 936 @Override setBroadcastEmergencyCallStateChanges(boolean broadcast)937 public void setBroadcastEmergencyCallStateChanges(boolean broadcast) { 938 mBroadcastEmergencyCallStateChanges = broadcast; 939 } 940 notifySuppServiceFailed(SuppService code)941 public void notifySuppServiceFailed(SuppService code) { 942 mSuppServiceFailedRegistrants.notifyResult(code); 943 } 944 945 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) notifyServiceStateChanged(ServiceState ss)946 public void notifyServiceStateChanged(ServiceState ss) { 947 super.notifyServiceStateChangedP(ss); 948 } 949 notifyServiceStateChangedForSubId(ServiceState ss, int subId)950 void notifyServiceStateChangedForSubId(ServiceState ss, int subId) { 951 super.notifyServiceStateChangedPForSubId(ss, subId); 952 } 953 954 /** 955 * Notify that the cell location has changed. 956 * 957 * @param cellIdentity the new CellIdentity 958 */ notifyLocationChanged(CellIdentity cellIdentity)959 public void notifyLocationChanged(CellIdentity cellIdentity) { 960 mNotifier.notifyCellLocation(this, cellIdentity); 961 } 962 963 @Override notifyCallForwardingIndicator()964 public void notifyCallForwardingIndicator() { 965 mNotifier.notifyCallForwardingChanged(this); 966 } 967 968 @Override registerForSuppServiceNotification( Handler h, int what, Object obj)969 public void registerForSuppServiceNotification( 970 Handler h, int what, Object obj) { 971 mSsnRegistrants.addUnique(h, what, obj); 972 } 973 974 @Override unregisterForSuppServiceNotification(Handler h)975 public void unregisterForSuppServiceNotification(Handler h) { 976 mSsnRegistrants.remove(h); 977 } 978 979 @Override registerForSimRecordsLoaded(Handler h, int what, Object obj)980 public void registerForSimRecordsLoaded(Handler h, int what, Object obj) { 981 mSimRecordsLoadedRegistrants.addUnique(h, what, obj); 982 } 983 984 @Override unregisterForSimRecordsLoaded(Handler h)985 public void unregisterForSimRecordsLoaded(Handler h) { 986 mSimRecordsLoadedRegistrants.remove(h); 987 } 988 989 @Override acceptCall(int videoState)990 public void acceptCall(int videoState) throws CallStateException { 991 if (!hasCalling()) throw new CallStateException(); 992 Phone imsPhone = mImsPhone; 993 if ( imsPhone != null && imsPhone.getRingingCall().isRinging() ) { 994 imsPhone.acceptCall(videoState); 995 } else { 996 mCT.acceptCall(); 997 } 998 } 999 1000 @Override rejectCall()1001 public void rejectCall() throws CallStateException { 1002 if (!hasCalling()) throw new CallStateException(); 1003 mCT.rejectCall(); 1004 } 1005 1006 @Override switchHoldingAndActive()1007 public void switchHoldingAndActive() throws CallStateException { 1008 mCT.switchWaitingOrHoldingAndActive(); 1009 } 1010 1011 @Override getIccSerialNumber()1012 public String getIccSerialNumber() { 1013 IccRecords r = mIccRecords.get(); 1014 if (!isPhoneTypeGsm() && r == null) { 1015 // to get ICCID form SIMRecords because it is on MF. 1016 r = mUiccController.getIccRecords(mPhoneId, UiccController.APP_FAM_3GPP); 1017 } 1018 return (r != null) ? r.getIccId() : null; 1019 } 1020 1021 @Override getFullIccSerialNumber()1022 public String getFullIccSerialNumber() { 1023 IccRecords r = mIccRecords.get(); 1024 if (!isPhoneTypeGsm() && r == null) { 1025 // to get ICCID form SIMRecords because it is on MF. 1026 r = mUiccController.getIccRecords(mPhoneId, UiccController.APP_FAM_3GPP); 1027 } 1028 return (r != null) ? r.getFullIccId() : null; 1029 } 1030 1031 @Override canConference()1032 public boolean canConference() { 1033 if (!hasCalling()) return false; 1034 if (mImsPhone != null && mImsPhone.canConference()) { 1035 return true; 1036 } 1037 if (isPhoneTypeGsm()) { 1038 return mCT.canConference(); 1039 } else { 1040 loge("canConference: not possible in CDMA"); 1041 return false; 1042 } 1043 } 1044 1045 @Override conference()1046 public void conference() { 1047 if (mImsPhone != null && mImsPhone.canConference()) { 1048 logd("conference() - delegated to IMS phone"); 1049 try { 1050 mImsPhone.conference(); 1051 } catch (CallStateException e) { 1052 loge(e.toString()); 1053 } 1054 return; 1055 } 1056 if (isPhoneTypeGsm()) { 1057 mCT.conference(); 1058 } else { 1059 // three way calls in CDMA will be handled by feature codes 1060 loge("conference: not possible in CDMA"); 1061 } 1062 } 1063 1064 @Override enableEnhancedVoicePrivacy(boolean enable, Message onComplete)1065 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 1066 if (isPhoneTypeGsm()) { 1067 loge("enableEnhancedVoicePrivacy: not expected on GSM"); 1068 } else { 1069 mCi.setPreferredVoicePrivacy(enable, onComplete); 1070 } 1071 } 1072 1073 @Override getEnhancedVoicePrivacy(Message onComplete)1074 public void getEnhancedVoicePrivacy(Message onComplete) { 1075 if (isPhoneTypeGsm()) { 1076 loge("getEnhancedVoicePrivacy: not expected on GSM"); 1077 } else { 1078 mCi.getPreferredVoicePrivacy(onComplete); 1079 } 1080 } 1081 1082 @Override clearDisconnected()1083 public void clearDisconnected() { 1084 if (!hasCalling()) return; 1085 mCT.clearDisconnected(); 1086 } 1087 1088 @Override canTransfer()1089 public boolean canTransfer() { 1090 if (hasCalling() && isPhoneTypeGsm()) { 1091 return mCT.canTransfer(); 1092 } else { 1093 loge("canTransfer: not possible in CDMA"); 1094 return false; 1095 } 1096 } 1097 1098 @Override explicitCallTransfer()1099 public void explicitCallTransfer() { 1100 if (hasCalling() && isPhoneTypeGsm()) { 1101 mCT.explicitCallTransfer(); 1102 } else { 1103 loge("explicitCallTransfer: not possible in CDMA"); 1104 } 1105 } 1106 1107 @Override getForegroundCall()1108 public GsmCdmaCall getForegroundCall() { 1109 if (!hasCalling()) return null; 1110 return mCT.mForegroundCall; 1111 } 1112 1113 @Override getBackgroundCall()1114 public GsmCdmaCall getBackgroundCall() { 1115 if (!hasCalling()) return null; 1116 return mCT.mBackgroundCall; 1117 } 1118 1119 @Override getRingingCall()1120 public Call getRingingCall() { 1121 if (!hasCalling()) return null; 1122 Phone imsPhone = mImsPhone; 1123 // It returns the ringing call of ImsPhone if the ringing call of GSMPhone isn't ringing. 1124 // In CallManager.registerPhone(), it always registers ringing call of ImsPhone, because 1125 // the ringing call of GSMPhone isn't ringing. Consequently, it can't answer GSM call 1126 // successfully by invoking TelephonyManager.answerRingingCall() since the implementation 1127 // in PhoneInterfaceManager.answerRingingCallInternal() could not get the correct ringing 1128 // call from CallManager. So we check the ringing call state of imsPhone first as 1129 // accpetCall() does. 1130 if ( imsPhone != null && imsPhone.getRingingCall().isRinging()) { 1131 return imsPhone.getRingingCall(); 1132 } 1133 //It returns the ringing connections which during SRVCC handover 1134 if (!mCT.mRingingCall.isRinging() 1135 && mCT.getRingingHandoverConnection() != null 1136 && mCT.getRingingHandoverConnection().getCall() != null 1137 && mCT.getRingingHandoverConnection().getCall().isRinging()) { 1138 return mCT.getRingingHandoverConnection().getCall(); 1139 } 1140 return mCT.mRingingCall; 1141 } 1142 1143 @Override 1144 @NonNull getCarrierPrivilegesTracker()1145 public CarrierPrivilegesTracker getCarrierPrivilegesTracker() { 1146 return mCarrierPrivilegesTracker; 1147 } 1148 1149 /** 1150 * Amends {@code baseSs} if its voice registration state is {@code OUT_OF_SERVICE}. 1151 * 1152 * <p>Even if the device has lost the CS link to the tower, there are two potential additional 1153 * sources of voice capability not directly saved inside ServiceStateTracker: 1154 * 1155 * <ul> 1156 * <li>IMS voice registration state ({@code imsSs}) - if this is {@code IN_SERVICE} for voice, 1157 * we substite {@code baseSs#getDataRegState} as the final voice service state (ImsService 1158 * reports {@code IN_SERVICE} for its voice registration state even if the device has lost 1159 * the physical link to the tower) 1160 * <li>OTT voice capability provided through telecom ({@code telecomSs}) - if this is {@code 1161 * IN_SERVICE}, we directly substitute it as the final voice service state 1162 * </ul> 1163 */ mergeVoiceServiceStates( ServiceState baseSs, ServiceState imsSs, @ServiceState.RegState int telecomSs)1164 private static ServiceState mergeVoiceServiceStates( 1165 ServiceState baseSs, ServiceState imsSs, @ServiceState.RegState int telecomSs) { 1166 if (baseSs.getState() == ServiceState.STATE_IN_SERVICE) { 1167 // No need to merge states if the baseSs is IN_SERVICE. 1168 return baseSs; 1169 } 1170 // If any of the following additional sources are IN_SERVICE, we use that since voice calls 1171 // can be routed through something other than the CS link. 1172 @ServiceState.RegState int finalVoiceSs = ServiceState.STATE_OUT_OF_SERVICE; 1173 if (telecomSs == ServiceState.STATE_IN_SERVICE) { 1174 // If telecom reports there's a PhoneAccount that can provide voice service 1175 // (CAPABILITY_VOICE_CALLING_AVAILABLE), then we trust that info as it may account for 1176 // external possibilities like wi-fi calling provided by the SIM call manager app. Note 1177 // that CAPABILITY_PLACE_EMERGENCY_CALLS is handled separately. 1178 finalVoiceSs = telecomSs; 1179 } else if (imsSs.getState() == ServiceState.STATE_IN_SERVICE) { 1180 // Voice override for IMS case. In this case, voice registration is OUT_OF_SERVICE, but 1181 // IMS is available, so use data registration state as a basis for determining 1182 // whether or not the physical link is available. 1183 finalVoiceSs = baseSs.getDataRegistrationState(); 1184 } 1185 if (finalVoiceSs != ServiceState.STATE_IN_SERVICE) { 1186 // None of the additional sources provide a usable route, and they only use IN/OUT. 1187 return baseSs; 1188 } 1189 ServiceState newSs = new ServiceState(baseSs); 1190 newSs.setVoiceRegState(finalVoiceSs); 1191 newSs.setEmergencyOnly(false); // Must be IN_SERVICE if we're here 1192 return newSs; 1193 } 1194 handleCallDeflectionIncallSupplementaryService( String dialString)1195 private boolean handleCallDeflectionIncallSupplementaryService( 1196 String dialString) { 1197 if (!hasCalling() || dialString.length() > 1) { 1198 return false; 1199 } 1200 1201 if (getRingingCall().getState() != GsmCdmaCall.State.IDLE) { 1202 if (DBG) logd("MmiCode 0: rejectCall"); 1203 try { 1204 mCT.rejectCall(); 1205 } catch (CallStateException e) { 1206 if (DBG) Rlog.d(LOG_TAG, 1207 "reject failed", e); 1208 notifySuppServiceFailed(Phone.SuppService.REJECT); 1209 } 1210 } else if (getBackgroundCall().getState() != GsmCdmaCall.State.IDLE) { 1211 if (DBG) logd("MmiCode 0: hangupWaitingOrBackground"); 1212 mCT.hangupWaitingOrBackground(); 1213 } 1214 1215 return true; 1216 } 1217 1218 //GSM handleCallWaitingIncallSupplementaryService(String dialString)1219 private boolean handleCallWaitingIncallSupplementaryService(String dialString) { 1220 int len = dialString.length(); 1221 1222 if (!hasCalling() || len > 2) { 1223 return false; 1224 } 1225 1226 GsmCdmaCall call = getForegroundCall(); 1227 1228 try { 1229 if (len > 1) { 1230 char ch = dialString.charAt(1); 1231 int callIndex = ch - '0'; 1232 1233 if (callIndex >= 1 && callIndex <= GsmCdmaCallTracker.MAX_CONNECTIONS_GSM) { 1234 if (DBG) logd("MmiCode 1: hangupConnectionByIndex " + callIndex); 1235 mCT.hangupConnectionByIndex(call, callIndex); 1236 } 1237 } else { 1238 if (call.getState() != GsmCdmaCall.State.IDLE) { 1239 if (DBG) logd("MmiCode 1: hangup foreground"); 1240 //mCT.hangupForegroundResumeBackground(); 1241 mCT.hangup(call); 1242 } else { 1243 if (DBG) logd("MmiCode 1: switchWaitingOrHoldingAndActive"); 1244 mCT.switchWaitingOrHoldingAndActive(); 1245 } 1246 } 1247 } catch (CallStateException e) { 1248 if (DBG) Rlog.d(LOG_TAG, 1249 "hangup failed", e); 1250 notifySuppServiceFailed(Phone.SuppService.HANGUP); 1251 } 1252 1253 return true; 1254 } 1255 handleCallHoldIncallSupplementaryService(String dialString)1256 private boolean handleCallHoldIncallSupplementaryService(String dialString) { 1257 int len = dialString.length(); 1258 1259 if (len > 2) { 1260 return false; 1261 } 1262 1263 GsmCdmaCall call = getForegroundCall(); 1264 1265 if (len > 1) { 1266 try { 1267 char ch = dialString.charAt(1); 1268 int callIndex = ch - '0'; 1269 GsmCdmaConnection conn = mCT.getConnectionByIndex(call, callIndex); 1270 1271 // GsmCdma index starts at 1, up to 5 connections in a call, 1272 if (conn != null && callIndex >= 1 && callIndex <= GsmCdmaCallTracker.MAX_CONNECTIONS_GSM) { 1273 if (DBG) logd("MmiCode 2: separate call " + callIndex); 1274 mCT.separate(conn); 1275 } else { 1276 if (DBG) logd("separate: invalid call index " + callIndex); 1277 notifySuppServiceFailed(Phone.SuppService.SEPARATE); 1278 } 1279 } catch (CallStateException e) { 1280 if (DBG) Rlog.d(LOG_TAG, "separate failed", e); 1281 notifySuppServiceFailed(Phone.SuppService.SEPARATE); 1282 } 1283 } else { 1284 try { 1285 if (getRingingCall().getState() != GsmCdmaCall.State.IDLE) { 1286 if (DBG) logd("MmiCode 2: accept ringing call"); 1287 mCT.acceptCall(); 1288 } else { 1289 if (DBG) logd("MmiCode 2: switchWaitingOrHoldingAndActive"); 1290 mCT.switchWaitingOrHoldingAndActive(); 1291 } 1292 } catch (CallStateException e) { 1293 if (DBG) Rlog.d(LOG_TAG, "switch failed", e); 1294 notifySuppServiceFailed(Phone.SuppService.SWITCH); 1295 } 1296 } 1297 1298 return true; 1299 } 1300 handleMultipartyIncallSupplementaryService(String dialString)1301 private boolean handleMultipartyIncallSupplementaryService(String dialString) { 1302 if (dialString.length() > 1) { 1303 return false; 1304 } 1305 1306 if (DBG) logd("MmiCode 3: merge calls"); 1307 conference(); 1308 return true; 1309 } 1310 handleEctIncallSupplementaryService(String dialString)1311 private boolean handleEctIncallSupplementaryService(String dialString) { 1312 1313 int len = dialString.length(); 1314 1315 if (len != 1) { 1316 return false; 1317 } 1318 1319 if (DBG) logd("MmiCode 4: explicit call transfer"); 1320 explicitCallTransfer(); 1321 return true; 1322 } 1323 handleCcbsIncallSupplementaryService(String dialString)1324 private boolean handleCcbsIncallSupplementaryService(String dialString) { 1325 if (dialString.length() > 1) { 1326 return false; 1327 } 1328 1329 Rlog.i(LOG_TAG, "MmiCode 5: CCBS not supported!"); 1330 // Treat it as an "unknown" service. 1331 notifySuppServiceFailed(Phone.SuppService.UNKNOWN); 1332 return true; 1333 } 1334 1335 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1336 @Override handleInCallMmiCommands(String dialString)1337 public boolean handleInCallMmiCommands(String dialString) throws CallStateException { 1338 if (!isPhoneTypeGsm()) { 1339 loge("method handleInCallMmiCommands is NOT supported in CDMA!"); 1340 return false; 1341 } 1342 1343 Phone imsPhone = mImsPhone; 1344 if (imsPhone != null 1345 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) { 1346 return imsPhone.handleInCallMmiCommands(dialString); 1347 } 1348 1349 if (!isInCall()) { 1350 return false; 1351 } 1352 1353 if (TextUtils.isEmpty(dialString)) { 1354 return false; 1355 } 1356 1357 boolean result = false; 1358 char ch = dialString.charAt(0); 1359 switch (ch) { 1360 case '0': 1361 result = handleCallDeflectionIncallSupplementaryService(dialString); 1362 break; 1363 case '1': 1364 result = handleCallWaitingIncallSupplementaryService(dialString); 1365 break; 1366 case '2': 1367 result = handleCallHoldIncallSupplementaryService(dialString); 1368 break; 1369 case '3': 1370 result = handleMultipartyIncallSupplementaryService(dialString); 1371 break; 1372 case '4': 1373 result = handleEctIncallSupplementaryService(dialString); 1374 break; 1375 case '5': 1376 result = handleCcbsIncallSupplementaryService(dialString); 1377 break; 1378 default: 1379 break; 1380 } 1381 1382 return result; 1383 } 1384 1385 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isInCall()1386 public boolean isInCall() { 1387 if (!hasCalling()) return false; 1388 1389 GsmCdmaCall.State foregroundCallState = getForegroundCall().getState(); 1390 GsmCdmaCall.State backgroundCallState = getBackgroundCall().getState(); 1391 GsmCdmaCall.State ringingCallState = getRingingCall().getState(); 1392 1393 return (foregroundCallState.isAlive() || 1394 backgroundCallState.isAlive() || 1395 ringingCallState.isAlive()); 1396 } 1397 useImsForCall(DialArgs dialArgs)1398 private boolean useImsForCall(DialArgs dialArgs) { 1399 return isImsUseEnabled() 1400 && mImsPhone != null 1401 && (mImsPhone.isVoiceOverCellularImsEnabled() || mImsPhone.isWifiCallingEnabled() 1402 || (mImsPhone.isVideoEnabled() && VideoProfile.isVideo(dialArgs.videoState))) 1403 && (mImsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE); 1404 } 1405 useImsForEmergency()1406 public boolean useImsForEmergency() { 1407 CarrierConfigManager configManager = 1408 (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 1409 boolean alwaysTryImsForEmergencyCarrierConfig = configManager.getConfigForSubId(getSubId()) 1410 .getBoolean(CarrierConfigManager.KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL); 1411 return mImsPhone != null 1412 && alwaysTryImsForEmergencyCarrierConfig 1413 && ImsManager.getInstance(mContext, mPhoneId).isNonTtyOrTtyOnVolteEnabled() 1414 && mImsPhone.isImsAvailable(); 1415 } 1416 1417 @Override startConference(String[] participantsToDial, DialArgs dialArgs)1418 public Connection startConference(String[] participantsToDial, DialArgs dialArgs) 1419 throws CallStateException { 1420 Phone imsPhone = mImsPhone; 1421 boolean useImsForCall = useImsForCall(dialArgs); 1422 logd("useImsForCall=" + useImsForCall); 1423 if (useImsForCall) { 1424 try { 1425 if (DBG) logd("Trying IMS PS Conference call"); 1426 return imsPhone.startConference(participantsToDial, dialArgs); 1427 } catch (CallStateException e) { 1428 if (DBG) logd("IMS PS conference call exception " + e + 1429 "useImsForCall =" + useImsForCall + ", imsPhone =" + imsPhone); 1430 CallStateException ce = new CallStateException(e.getError(), e.getMessage()); 1431 ce.setStackTrace(e.getStackTrace()); 1432 throw ce; 1433 } 1434 } else { 1435 throw new CallStateException( 1436 CallStateException.ERROR_OUT_OF_SERVICE, 1437 "cannot dial conference call in out of service"); 1438 } 1439 } 1440 1441 @Override dial(String dialString, @NonNull DialArgs dialArgs, Consumer<Phone> chosenPhoneConsumer)1442 public Connection dial(String dialString, @NonNull DialArgs dialArgs, 1443 Consumer<Phone> chosenPhoneConsumer) throws CallStateException { 1444 if (!hasCalling()) { 1445 throw new CallStateException("Calling feature is not supported!"); 1446 } 1447 if (!isPhoneTypeGsm() && dialArgs.uusInfo != null) { 1448 throw new CallStateException("Sending UUS information NOT supported in CDMA!"); 1449 } 1450 String possibleEmergencyNumber = checkForTestEmergencyNumber(dialString); 1451 // Record if the dialed number was swapped for a test emergency number. 1452 boolean isDialedNumberSwapped = !TextUtils.equals(dialString, possibleEmergencyNumber); 1453 if (isDialedNumberSwapped) { 1454 logi("dialString replaced for possible emergency number: " + dialString + " -> " 1455 + possibleEmergencyNumber); 1456 dialString = possibleEmergencyNumber; 1457 } 1458 1459 CarrierConfigManager configManager = 1460 (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 1461 PersistableBundle carrierConfig = configManager.getConfigForSubId(getSubId()); 1462 boolean allowWpsOverIms = carrierConfig.getBoolean( 1463 CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL); 1464 boolean useOnlyDialedSimEccList = carrierConfig.getBoolean( 1465 CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL); 1466 1467 1468 TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); 1469 boolean isEmergency; 1470 // Check if the carrier wants to treat a call as an emergency call based on its own list of 1471 // known emergency numbers. 1472 // useOnlyDialedSimEccList is false for the vast majority of carriers. There are, however, 1473 // some carriers which do not want to handle dial requests for numbers which are in the 1474 // emergency number list on another SIM, but is not on theirs. In this case we will use the 1475 // emergency number list for this carrier's SIM only. 1476 if (useOnlyDialedSimEccList) { 1477 isEmergency = getEmergencyNumberTracker().isEmergencyNumber(dialString); 1478 logi("dial; isEmergency=" + isEmergency 1479 + " (based on this phone only); globalIsEmergency=" 1480 + tm.isEmergencyNumber(dialString)); 1481 } else { 1482 isEmergency = tm.isEmergencyNumber(dialString); 1483 logi("dial; isEmergency=" + isEmergency + " (based on all phones)"); 1484 } 1485 1486 // Undetectable emergeny number indicated by new domain selection service 1487 if (dialArgs.isEmergency) { 1488 logi("dial; isEmergency=" + isEmergency + " (domain selection module)"); 1489 isEmergency = true; 1490 } 1491 1492 /** Check if the call is Wireless Priority Service call */ 1493 boolean isWpsCall = PhoneNumberUtils.isWpsCallNumber(dialString); 1494 1495 ImsPhone.ImsDialArgs.Builder imsDialArgsBuilder; 1496 imsDialArgsBuilder = ImsPhone.ImsDialArgs.Builder.from(dialArgs) 1497 .setIsEmergency(isEmergency) 1498 .setIsWpsCall(isWpsCall); 1499 mDialArgs = dialArgs = imsDialArgsBuilder.build(); 1500 1501 Phone imsPhone = mImsPhone; 1502 1503 boolean useImsForEmergency = isEmergency && useImsForEmergency(); 1504 1505 String dialPart = PhoneNumberUtils.extractNetworkPortionAlt(PhoneNumberUtils. 1506 stripSeparators(dialString)); 1507 boolean isMmiCode = (dialPart.startsWith("*") || dialPart.startsWith("#")) 1508 && dialPart.endsWith("#"); 1509 boolean isSuppServiceCode = ImsPhoneMmiCode.isSuppServiceCodes(dialPart, this); 1510 boolean isPotentialUssdCode = isMmiCode && !isSuppServiceCode; 1511 boolean useImsForUt = imsPhone != null && imsPhone.isUtEnabled(); 1512 boolean useImsForCall = useImsForCall(dialArgs) 1513 && (isWpsCall ? allowWpsOverIms : true); 1514 1515 Bundle extras = dialArgs.intentExtras; 1516 // Only when the domain selection service is supported, EXTRA_DIAL_DOMAIN extra shall exist. 1517 if (extras != null && extras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)) { 1518 int domain = extras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN); 1519 logi("dial domain=" + domain); 1520 useImsForCall = false; 1521 useImsForUt = false; 1522 useImsForEmergency = false; 1523 if (domain == DOMAIN_PS) { 1524 if (isEmergency) { 1525 useImsForEmergency = true; 1526 } else if (!isMmiCode || isPotentialUssdCode) { 1527 useImsForCall = true; 1528 } else { 1529 // should not reach here 1530 loge("dial unexpected Ut domain selection, ignored"); 1531 } 1532 } else if (domain == PhoneConstants.DOMAIN_NON_3GPP_PS) { 1533 if (isEmergency) { 1534 useImsForEmergency = true; 1535 extras.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE, 1536 String.valueOf(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)); 1537 } else { 1538 // should not reach here 1539 loge("dial DOMAIN_NON_3GPP_PS should be used only for emergency calls"); 1540 } 1541 } 1542 1543 extras.remove(PhoneConstants.EXTRA_DIAL_DOMAIN); 1544 } 1545 1546 if (DBG) { 1547 logi("useImsForCall=" + useImsForCall 1548 + ", useOnlyDialedSimEccList=" + useOnlyDialedSimEccList 1549 + ", isEmergency=" + isEmergency 1550 + ", useImsForEmergency=" + useImsForEmergency 1551 + ", useImsForUt=" + useImsForUt 1552 + ", isUt=" + isMmiCode 1553 + ", isSuppServiceCode=" + isSuppServiceCode 1554 + ", isPotentialUssdCode=" + isPotentialUssdCode 1555 + ", isWpsCall=" + isWpsCall 1556 + ", allowWpsOverIms=" + allowWpsOverIms 1557 + ", imsPhone=" + imsPhone 1558 + ", imsPhone.isVoiceOverCellularImsEnabled()=" 1559 + ((imsPhone != null) ? imsPhone.isVoiceOverCellularImsEnabled() : "N/A") 1560 + ", imsPhone.isVowifiEnabled()=" 1561 + ((imsPhone != null) ? imsPhone.isWifiCallingEnabled() : "N/A") 1562 + ", imsPhone.isVideoEnabled()=" 1563 + ((imsPhone != null) ? imsPhone.isVideoEnabled() : "N/A") 1564 + ", imsPhone.getServiceState().getState()=" 1565 + ((imsPhone != null) ? imsPhone.getServiceState().getState() : "N/A")); 1566 } 1567 1568 // Perform FDN check for non-emergency calls - shouldn't dial if number is blocked by FDN 1569 if(!isEmergency && FdnUtils.isNumberBlockedByFDN(mPhoneId, dialString, getCountryIso())) { 1570 throw new CallStateException(CallStateException.ERROR_FDN_BLOCKED, 1571 "cannot dial number blocked by FDN"); 1572 } 1573 1574 // Bypass WiFi Only WFC check if this is an emergency call - we should still try to 1575 // place over cellular if possible. 1576 if (!isEmergency) { 1577 Phone.checkWfcWifiOnlyModeBeforeDial(mImsPhone, mPhoneId, mContext); 1578 } 1579 if (imsPhone != null && !allowWpsOverIms && !useImsForCall && isWpsCall 1580 && imsPhone.getCallTracker() instanceof ImsPhoneCallTracker) { 1581 logi("WPS call placed over CS; disconnecting all IMS calls.."); 1582 ImsPhoneCallTracker tracker = (ImsPhoneCallTracker) imsPhone.getCallTracker(); 1583 tracker.hangupAllConnections(); 1584 } 1585 1586 if ((useImsForCall && (!isMmiCode || isPotentialUssdCode)) 1587 || (isMmiCode && useImsForUt) 1588 || useImsForEmergency) { 1589 try { 1590 if (DBG) logd("Trying IMS PS call"); 1591 chosenPhoneConsumer.accept(imsPhone); 1592 return imsPhone.dial(dialString, dialArgs); 1593 } catch (CallStateException e) { 1594 if (DBG) logd("IMS PS call exception " + e + 1595 "useImsForCall =" + useImsForCall + ", imsPhone =" + imsPhone); 1596 // Do not throw a CallStateException and instead fall back to Circuit switch 1597 // for emergency calls and MMI codes. 1598 if (Phone.CS_FALLBACK.equals(e.getMessage()) || isEmergency) { 1599 logi("IMS call failed with Exception: " + e.getMessage() + ". Falling back " 1600 + "to CS."); 1601 } else { 1602 CallStateException ce = new CallStateException(e.getError(), e.getMessage()); 1603 ce.setStackTrace(e.getStackTrace()); 1604 throw ce; 1605 } 1606 } 1607 } 1608 1609 if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_OUT_OF_SERVICE 1610 && mSST.mSS.getDataRegistrationState() != ServiceState.STATE_IN_SERVICE 1611 && !isEmergency) { 1612 throw new CallStateException("cannot dial in current state"); 1613 } 1614 // Check non-emergency voice CS call - shouldn't dial when POWER_OFF 1615 if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_POWER_OFF /* CS POWER_OFF */ 1616 && !VideoProfile.isVideo(dialArgs.videoState) /* voice call */ 1617 && !isEmergency /* non-emergency call */ 1618 && !(isMmiCode && useImsForUt) /* not UT */ 1619 /* If config_allow_ussd_over_ims is false, USSD is sent over the CS pipe instead */ 1620 && !isPotentialUssdCode) { 1621 throw new CallStateException( 1622 CallStateException.ERROR_POWER_OFF, 1623 "cannot dial voice call in airplane mode"); 1624 } 1625 // Check for service before placing non emergency CS voice call. 1626 // Allow dial only if either CS is camped on any RAT (or) PS is in LTE/NR service. 1627 if (mSST != null 1628 && mSST.mSS.getState() == ServiceState.STATE_OUT_OF_SERVICE /* CS out of service */ 1629 && !(mSST.mSS.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE 1630 && ServiceState.isPsOnlyTech( 1631 mSST.mSS.getRilDataRadioTechnology())) /* PS not in LTE/NR */ 1632 && !VideoProfile.isVideo(dialArgs.videoState) /* voice call */ 1633 && !isEmergency /* non-emergency call */ 1634 /* If config_allow_ussd_over_ims is false, USSD is sent over the CS pipe instead */ 1635 && !isPotentialUssdCode) { 1636 throw new CallStateException( 1637 CallStateException.ERROR_OUT_OF_SERVICE, 1638 "cannot dial voice call in out of service"); 1639 } 1640 if (DBG) logd("Trying (non-IMS) CS call"); 1641 if (isDialedNumberSwapped && isEmergency) { 1642 // If domain selection is enabled, ECM testing is handled in EmergencyStateTracker 1643 if (!DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { 1644 // Triggers ECM when CS call ends only for test emergency calls using 1645 // ril.test.emergencynumber. 1646 mIsTestingEmergencyCallbackMode = true; 1647 mCi.testingEmergencyCall(); 1648 } 1649 } 1650 1651 chosenPhoneConsumer.accept(this); 1652 return dialInternal(dialString, dialArgs); 1653 } 1654 1655 /** 1656 * @return {@code true} if the user should be informed of an attempt to dial an international 1657 * number while on WFC only, {@code false} otherwise. 1658 */ isNotificationOfWfcCallRequired(String dialString)1659 public boolean isNotificationOfWfcCallRequired(String dialString) { 1660 CarrierConfigManager configManager = 1661 (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 1662 PersistableBundle config = configManager.getConfigForSubId(getSubId()); 1663 1664 // Determine if carrier config indicates that international calls over WFC should trigger a 1665 // notification to the user. This is controlled by carrier configuration and is off by 1666 // default. 1667 boolean shouldNotifyInternationalCallOnWfc = config != null 1668 && config.getBoolean( 1669 CarrierConfigManager.KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL); 1670 1671 if (!shouldNotifyInternationalCallOnWfc) { 1672 return false; 1673 } 1674 1675 Phone imsPhone = mImsPhone; 1676 TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); 1677 boolean isEmergency = tm.isEmergencyNumber(dialString); 1678 boolean shouldConfirmCall = 1679 // Using IMS 1680 isImsUseEnabled() 1681 && imsPhone != null 1682 // VoLTE not available 1683 && !imsPhone.isVoiceOverCellularImsEnabled() 1684 // WFC is available 1685 && imsPhone.isWifiCallingEnabled() 1686 && !isEmergency 1687 // Dialing international number 1688 && PhoneNumberUtils.isInternationalNumber(dialString, getCountryIso()); 1689 return shouldConfirmCall; 1690 } 1691 1692 @Override dialInternal(String dialString, DialArgs dialArgs)1693 protected Connection dialInternal(String dialString, DialArgs dialArgs) 1694 throws CallStateException { 1695 return dialInternal(dialString, dialArgs, null); 1696 } 1697 dialInternal(String dialString, DialArgs dialArgs, ResultReceiver wrappedCallback)1698 protected Connection dialInternal(String dialString, DialArgs dialArgs, 1699 ResultReceiver wrappedCallback) 1700 throws CallStateException { 1701 1702 // Need to make sure dialString gets parsed properly 1703 String newDialString = PhoneNumberUtils.stripSeparators(dialString); 1704 1705 if (isPhoneTypeGsm()) { 1706 if (mFeatureFlags.skipMmiCodeCheckForEmergencyCall()) { 1707 // If not emergency number, handle in-call MMI first if applicable 1708 if (!dialArgs.isEmergency && handleInCallMmiCommands(newDialString)) { 1709 return null; 1710 } 1711 } else { 1712 // handle in-call MMI first if applicable 1713 if (handleInCallMmiCommands(newDialString)) { 1714 return null; 1715 } 1716 } 1717 1718 // Only look at the Network portion for mmi 1719 String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString); 1720 GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this, 1721 mUiccApplication.get(), wrappedCallback); 1722 if (DBG) logd("dialInternal: dialing w/ mmi '" + mmi + "'..."); 1723 1724 if (mmi == null) { 1725 return mCT.dialGsm(newDialString, dialArgs); 1726 } else if (mmi.isTemporaryModeCLIR()) { 1727 return mCT.dialGsm(mmi.mDialingNumber, mmi.getCLIRMode(), dialArgs.uusInfo, 1728 dialArgs.intentExtras); 1729 } else { 1730 mPendingMMIs.add(mmi); 1731 mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); 1732 mmi.processCode(); 1733 return null; 1734 } 1735 } else { 1736 return mCT.dial(newDialString, dialArgs); 1737 } 1738 } 1739 1740 @Override handlePinMmi(String dialString)1741 public boolean handlePinMmi(String dialString) { 1742 MmiCode mmi; 1743 if (isPhoneTypeGsm()) { 1744 mmi = GsmMmiCode.newFromDialString(dialString, this, mUiccApplication.get()); 1745 } else { 1746 mmi = CdmaMmiCode.newFromDialString(dialString, this, mUiccApplication.get()); 1747 } 1748 1749 if (mmi != null && mmi.isPinPukCommand()) { 1750 mPendingMMIs.add(mmi); 1751 mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); 1752 try { 1753 mmi.processCode(); 1754 } catch (CallStateException e) { 1755 //do nothing 1756 } 1757 return true; 1758 } 1759 1760 loge("Mmi is null or unrecognized!"); 1761 return false; 1762 } 1763 sendUssdResponse(String ussdRequest, CharSequence message, int returnCode, ResultReceiver wrappedCallback)1764 private void sendUssdResponse(String ussdRequest, CharSequence message, int returnCode, 1765 ResultReceiver wrappedCallback) { 1766 UssdResponse response = new UssdResponse(ussdRequest, message); 1767 Bundle returnData = new Bundle(); 1768 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response); 1769 wrappedCallback.send(returnCode, returnData); 1770 } 1771 1772 @Override handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback)1773 public boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback) { 1774 if (!isPhoneTypeGsm() || mPendingMMIs.size() > 0) { 1775 //todo: replace the generic failure with specific error code. 1776 sendUssdResponse(ussdRequest, null, TelephonyManager.USSD_RETURN_FAILURE, 1777 wrappedCallback ); 1778 return true; 1779 } 1780 1781 // Perform FDN check 1782 if(FdnUtils.isNumberBlockedByFDN(mPhoneId, ussdRequest, getCountryIso())) { 1783 sendUssdResponse(ussdRequest, null, TelephonyManager.USSD_RETURN_FAILURE, 1784 wrappedCallback ); 1785 return true; 1786 } 1787 1788 // Try over IMS if possible. 1789 Phone imsPhone = mImsPhone; 1790 if ((imsPhone != null) 1791 && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) 1792 || imsPhone.isUtEnabled())) { 1793 try { 1794 logd("handleUssdRequest: attempting over IMS"); 1795 return imsPhone.handleUssdRequest(ussdRequest, wrappedCallback); 1796 } catch (CallStateException cse) { 1797 if (!CS_FALLBACK.equals(cse.getMessage())) { 1798 return false; 1799 } 1800 // At this point we've tried over IMS but have been informed we need to handover 1801 // back to GSM. 1802 logd("handleUssdRequest: fallback to CS required"); 1803 } 1804 } 1805 1806 // Try USSD over GSM. 1807 try { 1808 dialInternal(ussdRequest, new DialArgs.Builder<>().build(), wrappedCallback); 1809 } catch (Exception e) { 1810 logd("handleUssdRequest: exception" + e); 1811 return false; 1812 } 1813 return true; 1814 } 1815 1816 @Override sendUssdResponse(String ussdMessge)1817 public void sendUssdResponse(String ussdMessge) { 1818 if (isPhoneTypeGsm()) { 1819 GsmMmiCode mmi = GsmMmiCode.newFromUssdUserInput(ussdMessge, this, mUiccApplication.get()); 1820 mPendingMMIs.add(mmi); 1821 mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); 1822 mmi.sendUssd(ussdMessge); 1823 } else { 1824 loge("sendUssdResponse: not possible in CDMA"); 1825 } 1826 } 1827 1828 @Override sendDtmf(char c)1829 public void sendDtmf(char c) { 1830 if (!PhoneNumberUtils.is12Key(c)) { 1831 loge("sendDtmf called with invalid character '" + c + "'"); 1832 } else { 1833 if (mCT.mState == PhoneConstants.State.OFFHOOK) { 1834 mCi.sendDtmf(c, null); 1835 } 1836 } 1837 } 1838 1839 @Override startDtmf(char c)1840 public void startDtmf(char c) { 1841 if (!PhoneNumberUtils.is12Key(c)) { 1842 loge("startDtmf called with invalid character '" + c + "'"); 1843 } else { 1844 mCi.startDtmf(c, null); 1845 } 1846 } 1847 1848 @Override stopDtmf()1849 public void stopDtmf() { 1850 mCi.stopDtmf(null); 1851 } 1852 1853 @Override sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)1854 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 1855 if (isPhoneTypeGsm()) { 1856 loge("[GsmCdmaPhone] sendBurstDtmf() is a CDMA method"); 1857 } else { 1858 boolean check = true; 1859 for (int itr = 0;itr < dtmfString.length(); itr++) { 1860 if (!PhoneNumberUtils.is12Key(dtmfString.charAt(itr))) { 1861 Rlog.e( 1862 LOG_TAG, 1863 "sendDtmf called with invalid character '" 1864 + dtmfString.charAt(itr) 1865 + "'"); 1866 check = false; 1867 break; 1868 } 1869 } 1870 if (mCT.mState == PhoneConstants.State.OFFHOOK && check) { 1871 mCi.sendBurstDtmf(dtmfString, on, off, onComplete); 1872 } 1873 } 1874 } 1875 1876 @Override setRadioPowerOnForTestEmergencyCall(boolean isSelectedPhoneForEmergencyCall)1877 public void setRadioPowerOnForTestEmergencyCall(boolean isSelectedPhoneForEmergencyCall) { 1878 mSST.clearAllRadioOffReasons(); 1879 1880 // We don't want to have forEmergency call be true to prevent radio emergencyDial command 1881 // from being called for a test emergency number because the network may not be able to 1882 // find emergency routing for it and dial it do the default emergency services line. 1883 setRadioPower(true, false, isSelectedPhoneForEmergencyCall, false); 1884 } 1885 1886 @Override setRadioPower(boolean power, boolean forEmergencyCall, boolean isSelectedPhoneForEmergencyCall, boolean forceApply)1887 public void setRadioPower(boolean power, boolean forEmergencyCall, 1888 boolean isSelectedPhoneForEmergencyCall, boolean forceApply) { 1889 setRadioPowerForReason(power, forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply, 1890 TelephonyManager.RADIO_POWER_REASON_USER); 1891 } 1892 1893 @Override setRadioPowerForReason(boolean power, boolean forEmergencyCall, boolean isSelectedPhoneForEmergencyCall, boolean forceApply, int reason)1894 public void setRadioPowerForReason(boolean power, boolean forEmergencyCall, 1895 boolean isSelectedPhoneForEmergencyCall, boolean forceApply, int reason) { 1896 if (mFeatureFlags.powerDownRaceFix()) { 1897 // setRadioPowerForReason can be called by the binder thread. We need to move that into 1898 // the main thread to prevent race condition. 1899 post(() -> mSST.setRadioPowerForReason(power, forEmergencyCall, 1900 isSelectedPhoneForEmergencyCall, forceApply, reason)); 1901 } else { 1902 mSST.setRadioPowerForReason(power, forEmergencyCall, isSelectedPhoneForEmergencyCall, 1903 forceApply, reason); 1904 } 1905 } 1906 1907 @Override getRadioPowerOffReasons()1908 public Set<Integer> getRadioPowerOffReasons() { 1909 return mSST.getRadioPowerOffReasons(); 1910 } 1911 storeVoiceMailNumber(String number)1912 private void storeVoiceMailNumber(String number) { 1913 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1914 SharedPreferences.Editor editor = sp.edit(); 1915 setVmSimImsi(getSubscriberId()); 1916 logd("storeVoiceMailNumber: mPrecisePhoneType=" + mPrecisePhoneType + " vmNumber=" 1917 + Rlog.pii(LOG_TAG, number)); 1918 if (isPhoneTypeGsm()) { 1919 editor.putString(VM_NUMBER + getPhoneId(), number); 1920 editor.apply(); 1921 } else { 1922 editor.putString(VM_NUMBER_CDMA + getPhoneId(), number); 1923 editor.apply(); 1924 } 1925 } 1926 1927 @Override getVoiceMailNumber()1928 public String getVoiceMailNumber() { 1929 String number = null; 1930 if (isPhoneTypeGsm() || mSimRecords != null) { 1931 // Read from the SIM. If its null, try reading from the shared preference area. 1932 IccRecords r = isPhoneTypeGsm() ? mIccRecords.get() : mSimRecords; 1933 number = (r != null) ? r.getVoiceMailNumber() : ""; 1934 if (TextUtils.isEmpty(number)) { 1935 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1936 String spName = isPhoneTypeGsm() ? VM_NUMBER : VM_NUMBER_CDMA; 1937 number = sp.getString(spName + getPhoneId(), null); 1938 logd("getVoiceMailNumber: from " + spName + " number=" 1939 + Rlog.piiHandle(number)); 1940 } else { 1941 logd("getVoiceMailNumber: from IccRecords number=" + Rlog.piiHandle(number)); 1942 } 1943 } 1944 if (!isPhoneTypeGsm() && TextUtils.isEmpty(number)) { 1945 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1946 number = sp.getString(VM_NUMBER_CDMA + getPhoneId(), null); 1947 logd("getVoiceMailNumber: from VM_NUMBER_CDMA number=" + Rlog.piiHandle(number)); 1948 } 1949 1950 if (TextUtils.isEmpty(number)) { 1951 CarrierConfigManager configManager = (CarrierConfigManager) 1952 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 1953 PersistableBundle b = configManager.getConfigForSubId(getSubId()); 1954 if (b != null) { 1955 String defaultVmNumber = 1956 b.getString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING); 1957 String defaultVmNumberRoaming = 1958 b.getString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_ROAMING_STRING); 1959 String defaultVmNumberRoamingAndImsUnregistered = b.getString( 1960 CarrierConfigManager 1961 .KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING); 1962 1963 if (!TextUtils.isEmpty(defaultVmNumber)) number = defaultVmNumber; 1964 if (mSST.mSS.getRoaming()) { 1965 if (!TextUtils.isEmpty(defaultVmNumberRoamingAndImsUnregistered) 1966 && !mSST.isImsRegistered()) { 1967 // roaming and IMS unregistered case if CC configured 1968 number = defaultVmNumberRoamingAndImsUnregistered; 1969 logd("getVoiceMailNumber: from defaultVmNumberRoamingAndImsUnregistered " 1970 + "number=" + Rlog.piiHandle(number)); 1971 } else if (!TextUtils.isEmpty(defaultVmNumberRoaming)) { 1972 // roaming default case if CC configured 1973 number = defaultVmNumberRoaming; 1974 logd("getVoiceMailNumber: from defaultVmNumberRoaming number=" + 1975 Rlog.piiHandle(number)); 1976 } 1977 } 1978 } 1979 } 1980 1981 if (TextUtils.isEmpty(number)) { 1982 // Read platform settings for dynamic voicemail number 1983 CarrierConfigManager configManager = (CarrierConfigManager) 1984 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 1985 PersistableBundle b = configManager.getConfigForSubId(getSubId()); 1986 if (b != null && b.getBoolean( 1987 CarrierConfigManager.KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL)) { 1988 number = getLine1Number(); 1989 logd("getVoiceMailNumber: from MSISDN number=" + Rlog.piiHandle(number)); 1990 } 1991 } 1992 return number; 1993 } 1994 1995 getVmSimImsi()1996 private String getVmSimImsi() { 1997 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 1998 return sp.getString(VM_SIM_IMSI + getPhoneId(), null); 1999 } 2000 setVmSimImsi(String imsi)2001 private void setVmSimImsi(String imsi) { 2002 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 2003 SharedPreferences.Editor editor = sp.edit(); 2004 editor.putString(VM_SIM_IMSI + getPhoneId(), imsi); 2005 editor.apply(); 2006 } 2007 2008 @Override getVoiceMailAlphaTag()2009 public String getVoiceMailAlphaTag() { 2010 String ret = ""; 2011 2012 if (isPhoneTypeGsm() || mSimRecords != null) { 2013 IccRecords r = isPhoneTypeGsm() ? mIccRecords.get() : mSimRecords; 2014 2015 ret = (r != null) ? r.getVoiceMailAlphaTag() : ""; 2016 } 2017 2018 if (ret == null || ret.length() == 0) { 2019 return mContext.getText( 2020 com.android.internal.R.string.defaultVoiceMailAlphaTag).toString(); 2021 } 2022 2023 return ret; 2024 } 2025 2026 @Override getDeviceId()2027 public String getDeviceId() { 2028 if (isPhoneTypeGsm()) { 2029 return mImei; 2030 } else { 2031 CarrierConfigManager configManager = (CarrierConfigManager) 2032 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 2033 boolean force_imei = configManager.getConfigForSubId(getSubId()) 2034 .getBoolean(CarrierConfigManager.KEY_FORCE_IMEI_BOOL); 2035 if (force_imei) return mImei; 2036 2037 String id = getMeid(); 2038 if ((id == null) || id.matches("^0*$")) { 2039 loge("getDeviceId(): MEID is not initialized use ESN"); 2040 id = getEsn(); 2041 } 2042 return id; 2043 } 2044 } 2045 2046 @Override getDeviceSvn()2047 public String getDeviceSvn() { 2048 if (isPhoneTypeGsm() || isPhoneTypeCdmaLte()) { 2049 return mImeiSv; 2050 } else { 2051 loge("getDeviceSvn(): return 0"); 2052 return "0"; 2053 } 2054 } 2055 2056 @Override getIsimRecords()2057 public IsimRecords getIsimRecords() { 2058 return mIsimUiccRecords; 2059 } 2060 2061 @Override getImei()2062 public String getImei() { 2063 return mImei; 2064 } 2065 2066 @Override getImeiType()2067 public int getImeiType() { 2068 return mImeiType; 2069 } 2070 2071 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2072 @Override getEsn()2073 public String getEsn() { 2074 if (isPhoneTypeGsm()) { 2075 loge("[GsmCdmaPhone] getEsn() is a CDMA method"); 2076 return "0"; 2077 } else { 2078 return mEsn; 2079 } 2080 } 2081 2082 @Override getMeid()2083 public String getMeid() { 2084 return mMeid; 2085 } 2086 2087 @Override getNai()2088 public String getNai() { 2089 IccRecords r = mUiccController.getIccRecords(mPhoneId, UiccController.APP_FAM_3GPP2); 2090 if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) { 2091 Rlog.v(LOG_TAG, "IccRecords is " + r); 2092 } 2093 return (r != null) ? r.getNAI() : null; 2094 } 2095 2096 @Override 2097 @Nullable getSubscriberId()2098 public String getSubscriberId() { 2099 String subscriberId = null; 2100 if (isPhoneTypeCdma()) { 2101 subscriberId = mSST.getImsi(); 2102 } else { 2103 // Both Gsm and CdmaLte get the IMSI from Usim. 2104 IccRecords iccRecords = mUiccController.getIccRecords( 2105 mPhoneId, UiccController.APP_FAM_3GPP); 2106 if (iccRecords != null) { 2107 subscriberId = iccRecords.getIMSI(); 2108 } 2109 } 2110 return subscriberId; 2111 } 2112 2113 @Override getCarrierInfoForImsiEncryption(int keyType, boolean fallback)2114 public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback) { 2115 final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class) 2116 .createForSubscriptionId(getSubId()); 2117 String operatorNumeric = telephonyManager.getSimOperator(); 2118 int carrierId = telephonyManager.getSimCarrierId(); 2119 return CarrierInfoManager.getCarrierInfoForImsiEncryption(keyType, 2120 mContext, operatorNumeric, carrierId, fallback, getSubId()); 2121 } 2122 2123 @Override setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo)2124 public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo) { 2125 CarrierInfoManager.setCarrierInfoForImsiEncryption(imsiEncryptionInfo, mContext, mPhoneId); 2126 mCi.setCarrierInfoForImsiEncryption(imsiEncryptionInfo, null); 2127 } 2128 2129 @Override deleteCarrierInfoForImsiEncryption(int carrierId)2130 public void deleteCarrierInfoForImsiEncryption(int carrierId) { 2131 CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext, getSubId(), carrierId); 2132 } 2133 2134 @Override deleteCarrierInfoForImsiEncryption(int carrierId, String simOperator)2135 public void deleteCarrierInfoForImsiEncryption(int carrierId, String simOperator) { 2136 CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext, getSubId(), 2137 carrierId, simOperator); 2138 } 2139 2140 @Override getCarrierId()2141 public int getCarrierId() { 2142 return mCarrierResolver != null 2143 ? mCarrierResolver.getCarrierId() : super.getCarrierId(); 2144 } 2145 2146 @Override getCarrierName()2147 public String getCarrierName() { 2148 return mCarrierResolver != null 2149 ? mCarrierResolver.getCarrierName() : super.getCarrierName(); 2150 } 2151 2152 @Override getMNOCarrierId()2153 public int getMNOCarrierId() { 2154 return mCarrierResolver != null 2155 ? mCarrierResolver.getMnoCarrierId() : super.getMNOCarrierId(); 2156 } 2157 2158 @Override getSpecificCarrierId()2159 public int getSpecificCarrierId() { 2160 return mCarrierResolver != null 2161 ? mCarrierResolver.getSpecificCarrierId() : super.getSpecificCarrierId(); 2162 } 2163 2164 @Override getSpecificCarrierName()2165 public String getSpecificCarrierName() { 2166 return mCarrierResolver != null 2167 ? mCarrierResolver.getSpecificCarrierName() : super.getSpecificCarrierName(); 2168 } 2169 2170 @Override resolveSubscriptionCarrierId(String simState)2171 public void resolveSubscriptionCarrierId(String simState) { 2172 if (mCarrierResolver != null) { 2173 mCarrierResolver.resolveSubscriptionCarrierId(simState); 2174 } 2175 } 2176 2177 @Override getCarrierIdListVersion()2178 public int getCarrierIdListVersion() { 2179 return mCarrierResolver != null 2180 ? mCarrierResolver.getCarrierListVersion() : super.getCarrierIdListVersion(); 2181 } 2182 2183 @Override getEmergencyNumberDbVersion()2184 public int getEmergencyNumberDbVersion() { 2185 EmergencyNumberTracker tracker = getEmergencyNumberTracker(); 2186 if (tracker == null) return -1; 2187 return tracker.getEmergencyNumberDbVersion(); 2188 } 2189 2190 @Override resetCarrierKeysForImsiEncryption()2191 public void resetCarrierKeysForImsiEncryption() { 2192 mCIM.resetCarrierKeysForImsiEncryption(mContext, mPhoneId, false); 2193 } 2194 2195 @Override resetCarrierKeysForImsiEncryption(boolean forceResetAll)2196 public void resetCarrierKeysForImsiEncryption(boolean forceResetAll) { 2197 mCIM.resetCarrierKeysForImsiEncryption(mContext, mPhoneId, forceResetAll); 2198 } 2199 2200 @Override setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1, String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn)2201 public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1, 2202 String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn) { 2203 mCarrierResolver.setTestOverrideApn(apn); 2204 UiccProfile uiccProfile = mUiccController.getUiccProfileForPhone(getPhoneId()); 2205 if (uiccProfile != null) { 2206 List<UiccAccessRule> testRules; 2207 if (carrierPrivilegeRules == null) { 2208 testRules = null; 2209 } else if (carrierPrivilegeRules.isEmpty()) { 2210 testRules = Collections.emptyList(); 2211 } else { 2212 UiccAccessRule accessRule = new UiccAccessRule( 2213 IccUtils.hexStringToBytes(carrierPrivilegeRules), null, 0); 2214 testRules = Collections.singletonList(accessRule); 2215 } 2216 uiccProfile.setTestOverrideCarrierPrivilegeRules(testRules); 2217 } else { 2218 // TODO: Fix "privilege" typo throughout telephony. 2219 mCarrierResolver.setTestOverrideCarrierPriviledgeRule(carrierPrivilegeRules); // NOTYPO 2220 } 2221 IccRecords r = null; 2222 if (isPhoneTypeGsm()) { 2223 r = mIccRecords.get(); 2224 } else if (isPhoneTypeCdmaLte()) { 2225 r = mSimRecords; 2226 } else { 2227 loge("setCarrierTestOverride fails in CDMA only"); 2228 } 2229 if (r != null) { 2230 r.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, pnn, spn); 2231 } 2232 } 2233 2234 @Override getGroupIdLevel1()2235 public String getGroupIdLevel1() { 2236 if (isPhoneTypeGsm()) { 2237 IccRecords r = mIccRecords.get(); 2238 return (r != null) ? r.getGid1() : null; 2239 } else if (isPhoneTypeCdma()) { 2240 loge("GID1 is not available in CDMA"); 2241 return null; 2242 } else { //isPhoneTypeCdmaLte() 2243 return (mSimRecords != null) ? mSimRecords.getGid1() : ""; 2244 } 2245 } 2246 2247 @Override getGroupIdLevel2()2248 public String getGroupIdLevel2() { 2249 if (isPhoneTypeGsm()) { 2250 IccRecords r = mIccRecords.get(); 2251 return (r != null) ? r.getGid2() : null; 2252 } else if (isPhoneTypeCdma()) { 2253 loge("GID2 is not available in CDMA"); 2254 return null; 2255 } else { //isPhoneTypeCdmaLte() 2256 return (mSimRecords != null) ? mSimRecords.getGid2() : ""; 2257 } 2258 } 2259 2260 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2261 @Override getLine1Number()2262 public String getLine1Number() { 2263 if (isPhoneTypeGsm()) { 2264 IccRecords r = mIccRecords.get(); 2265 return (r != null) ? r.getMsisdnNumber() : null; 2266 } else { 2267 CarrierConfigManager configManager = (CarrierConfigManager) 2268 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 2269 boolean use_usim = configManager.getConfigForSubId(getSubId()).getBoolean( 2270 CarrierConfigManager.KEY_USE_USIM_BOOL); 2271 if (use_usim) { 2272 return (mSimRecords != null) ? mSimRecords.getMsisdnNumber() : null; 2273 } 2274 return mSST.getMdnNumber(); 2275 } 2276 } 2277 2278 @Override getPlmn()2279 public String getPlmn() { 2280 if (isPhoneTypeGsm()) { 2281 IccRecords r = mIccRecords.get(); 2282 return (r != null) ? r.getPnnHomeName() : null; 2283 } else if (isPhoneTypeCdma()) { 2284 loge("Plmn is not available in CDMA"); 2285 return null; 2286 } else { //isPhoneTypeCdmaLte() 2287 return (mSimRecords != null) ? mSimRecords.getPnnHomeName() : null; 2288 } 2289 } 2290 2291 /** 2292 * Update non-persisited manual network selection. 2293 * 2294 * @param nsm contains Plmn info 2295 */ 2296 @Override updateManualNetworkSelection(NetworkSelectMessage nsm)2297 protected void updateManualNetworkSelection(NetworkSelectMessage nsm) { 2298 int subId = getSubId(); 2299 if (SubscriptionManager.isValidSubscriptionId(subId)) { 2300 mManualNetworkSelectionPlmn = nsm.operatorNumeric; 2301 } else { 2302 //on Phone0 in emergency mode (no SIM), or in some races then clear the cache 2303 mManualNetworkSelectionPlmn = null; 2304 Rlog.e(LOG_TAG, "Cannot update network selection due to invalid subId " 2305 + subId); 2306 } 2307 } 2308 2309 @Override getManualNetworkSelectionPlmn()2310 public String getManualNetworkSelectionPlmn() { 2311 return (mManualNetworkSelectionPlmn == null) ? "" : mManualNetworkSelectionPlmn; 2312 } 2313 2314 @Override onSetNetworkSelectionModeCompleted()2315 protected void onSetNetworkSelectionModeCompleted() { 2316 mSST.pollState(); 2317 } 2318 2319 @Override getCdmaPrlVersion()2320 public String getCdmaPrlVersion() { 2321 return mSST.getPrlVersion(); 2322 } 2323 2324 @Override getCdmaMin()2325 public String getCdmaMin() { 2326 return mSST.getCdmaMin(); 2327 } 2328 2329 @Override isMinInfoReady()2330 public boolean isMinInfoReady() { 2331 return mSST.isMinInfoReady(); 2332 } 2333 2334 @Override getMsisdn()2335 public String getMsisdn() { 2336 if (isPhoneTypeGsm()) { 2337 IccRecords r = mIccRecords.get(); 2338 return (r != null) ? r.getMsisdnNumber() : null; 2339 } else if (isPhoneTypeCdmaLte()) { 2340 return (mSimRecords != null) ? mSimRecords.getMsisdnNumber() : null; 2341 } else { 2342 loge("getMsisdn: not expected on CDMA"); 2343 return null; 2344 } 2345 } 2346 2347 @Override getLine1AlphaTag()2348 public String getLine1AlphaTag() { 2349 if (isPhoneTypeGsm()) { 2350 IccRecords r = mIccRecords.get(); 2351 return (r != null) ? r.getMsisdnAlphaTag() : null; 2352 } else { 2353 loge("getLine1AlphaTag: not possible in CDMA"); 2354 return null; 2355 } 2356 } 2357 2358 @Override setLine1Number(String alphaTag, String number, Message onComplete)2359 public boolean setLine1Number(String alphaTag, String number, Message onComplete) { 2360 if (isPhoneTypeGsm()) { 2361 IccRecords r = mIccRecords.get(); 2362 if (r != null) { 2363 r.setMsisdnNumber(alphaTag, number, onComplete); 2364 return true; 2365 } else { 2366 return false; 2367 } 2368 } else { 2369 loge("setLine1Number: not possible in CDMA"); 2370 return false; 2371 } 2372 } 2373 2374 @Override setVoiceMailNumber(String alphaTag, String voiceMailNumber, Message onComplete)2375 public void setVoiceMailNumber(String alphaTag, String voiceMailNumber, Message onComplete) { 2376 Message resp; 2377 mVmNumber = voiceMailNumber; 2378 resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete); 2379 2380 IccRecords r = mIccRecords.get(); 2381 2382 if (!isPhoneTypeGsm() && mSimRecords != null) { 2383 r = mSimRecords; 2384 } 2385 2386 if (r != null) { 2387 r.setVoiceMailNumber(alphaTag, mVmNumber, resp); 2388 } 2389 } 2390 2391 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isValidCommandInterfaceCFReason(int commandInterfaceCFReason)2392 private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) { 2393 switch (commandInterfaceCFReason) { 2394 case CF_REASON_UNCONDITIONAL: 2395 case CF_REASON_BUSY: 2396 case CF_REASON_NO_REPLY: 2397 case CF_REASON_NOT_REACHABLE: 2398 case CF_REASON_ALL: 2399 case CF_REASON_ALL_CONDITIONAL: 2400 return true; 2401 default: 2402 return false; 2403 } 2404 } 2405 2406 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2407 @Override getSystemProperty(String property, String defValue)2408 public String getSystemProperty(String property, String defValue) { 2409 if (getUnitTestMode()) { 2410 return null; 2411 } 2412 return TelephonyManager.getTelephonyProperty(mPhoneId, property, defValue); 2413 } 2414 2415 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isValidCommandInterfaceCFAction(int commandInterfaceCFAction)2416 private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) { 2417 switch (commandInterfaceCFAction) { 2418 case CF_ACTION_DISABLE: 2419 case CF_ACTION_ENABLE: 2420 case CF_ACTION_REGISTRATION: 2421 case CF_ACTION_ERASURE: 2422 return true; 2423 default: 2424 return false; 2425 } 2426 } 2427 2428 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isCfEnable(int action)2429 private boolean isCfEnable(int action) { 2430 return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION); 2431 } 2432 isImsUtEnabledOverCdma()2433 private boolean isImsUtEnabledOverCdma() { 2434 return isPhoneTypeCdmaLte() 2435 && mImsPhone != null 2436 && mImsPhone.isUtEnabled(); 2437 } 2438 isCsRetry(Message onComplete)2439 private boolean isCsRetry(Message onComplete) { 2440 if (onComplete != null) { 2441 return onComplete.getData().getBoolean(CS_FALLBACK_SS, false); 2442 } 2443 return false; 2444 } 2445 updateSsOverCdmaSupported(@onNull PersistableBundle b)2446 private void updateSsOverCdmaSupported(@NonNull PersistableBundle b) { 2447 mSsOverCdmaSupported = b.getBoolean(CarrierConfigManager.KEY_SUPPORT_SS_OVER_CDMA_BOOL); 2448 } 2449 2450 /** 2451 * Enables or disables N1 mode (access to 5G core network) in accordance with 2452 * 3GPP TS 24.501 4.9. 2453 * 2454 * <p> To prevent redundant calls down to the modem and to support a mechanism whereby 2455 * N1 mode is only on if both IMS and carrier config believe that it should be on, this 2456 * method will first sync the value from the modem prior to possibly setting it. In addition 2457 * N1 mode will not be set to enabled unless both IMS and Carrier want it, since the use 2458 * cases require all entities to agree lest it default to disabled. 2459 * 2460 * @param enable {@code true} to enable N1 mode, {@code false} to disable N1 mode. 2461 * @param result Callback message to receive the result or null. 2462 */ 2463 @Override setN1ModeEnabled(boolean enable, @Nullable Message result)2464 public void setN1ModeEnabled(boolean enable, @Nullable Message result) { 2465 // This might be called by IMS on another thread, so to avoid the requirement to 2466 // lock, post it through the handler. 2467 post(() -> { 2468 if (enable) { 2469 mN1ModeDisallowedReasons.remove(N1_MODE_DISALLOWED_REASON_IMS); 2470 } else { 2471 mN1ModeDisallowedReasons.add(N1_MODE_DISALLOWED_REASON_IMS); 2472 } 2473 if (mModemN1Mode == null) { 2474 mCi.isN1ModeEnabled(obtainMessage(EVENT_GET_N1_MODE_ENABLED_DONE, result)); 2475 } else { 2476 maybeUpdateModemN1Mode(result); 2477 } 2478 }); 2479 } 2480 2481 /** Only called on the handler thread. */ maybeUpdateModemN1Mode(@ullable Message result)2482 private void maybeUpdateModemN1Mode(@Nullable Message result) { 2483 final boolean wantN1Enabled = mN1ModeDisallowedReasons.isEmpty(); 2484 2485 logd("N1 Mode: isModemN1Enabled=" + mModemN1Mode + ", wantN1Enabled=" + wantN1Enabled); 2486 2487 // mModemN1Mode is never null here 2488 if (mModemN1Mode != wantN1Enabled) { 2489 // Assume success pending a response, which avoids multiple concurrent requests 2490 // going down to the modem. If it fails, that is addressed in the response. 2491 mModemN1Mode = wantN1Enabled; 2492 super.setN1ModeEnabled( 2493 wantN1Enabled, obtainMessage(EVENT_SET_N1_MODE_ENABLED_DONE, result)); 2494 } else if (result != null) { 2495 AsyncResult.forMessage(result); 2496 result.sendToTarget(); 2497 } 2498 } 2499 2500 /** Only called on the handler thread. */ updateCarrierN1ModeSupported(@onNull PersistableBundle b)2501 private void updateCarrierN1ModeSupported(@NonNull PersistableBundle b) { 2502 if (!CarrierConfigManager.isConfigForIdentifiedCarrier(b)) return; 2503 2504 final int[] supportedNrModes = b.getIntArray( 2505 CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY); 2506 2507 2508 if (ArrayUtils.contains( 2509 supportedNrModes, 2510 CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA)) { 2511 mN1ModeDisallowedReasons.remove(N1_MODE_DISALLOWED_REASON_CARRIER); 2512 } else { 2513 mN1ModeDisallowedReasons.add(N1_MODE_DISALLOWED_REASON_CARRIER); 2514 } 2515 2516 if (mModemN1Mode == null) { 2517 mCi.isN1ModeEnabled(obtainMessage(EVENT_GET_N1_MODE_ENABLED_DONE)); 2518 } else { 2519 maybeUpdateModemN1Mode(null); 2520 } 2521 } 2522 2523 @Override useSsOverIms(Message onComplete)2524 public boolean useSsOverIms(Message onComplete) { 2525 boolean isUtEnabled = isUtEnabled(); 2526 2527 Rlog.d(LOG_TAG, "useSsOverIms: isUtEnabled()= " + isUtEnabled + 2528 " isCsRetry(onComplete))= " + isCsRetry(onComplete)); 2529 2530 if (isUtEnabled && !isCsRetry(onComplete)) { 2531 return true; 2532 } 2533 return false; 2534 } 2535 2536 @Override getCallForwardingOption(int commandInterfaceCFReason, Message onComplete)2537 public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) { 2538 getCallForwardingOption(commandInterfaceCFReason, 2539 CommandsInterface.SERVICE_CLASS_VOICE, onComplete); 2540 } 2541 2542 @Override getCallForwardingOption(int commandInterfaceCFReason, int serviceClass, Message onComplete)2543 public void getCallForwardingOption(int commandInterfaceCFReason, int serviceClass, 2544 Message onComplete) { 2545 // Perform FDN check 2546 SsData.ServiceType serviceType = GsmMmiCode.cfReasonToServiceType(commandInterfaceCFReason); 2547 if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, serviceType)) { 2548 AsyncResult.forMessage(onComplete, null, 2549 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2550 onComplete.sendToTarget(); 2551 return; 2552 } 2553 2554 Phone imsPhone = mImsPhone; 2555 if (useSsOverIms(onComplete)) { 2556 imsPhone.getCallForwardingOption(commandInterfaceCFReason, serviceClass, onComplete); 2557 return; 2558 } 2559 2560 if (isPhoneTypeGsm()) { 2561 if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) { 2562 if (DBG) logd("requesting call forwarding query."); 2563 Message resp; 2564 if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) { 2565 resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete); 2566 } else { 2567 resp = onComplete; 2568 } 2569 mCi.queryCallForwardStatus(commandInterfaceCFReason, serviceClass, null, resp); 2570 } 2571 } else { 2572 if (!mSsOverCdmaSupported) { 2573 // If SS over CDMA is not supported and UT is not at the time, notify the user of 2574 // the error and disable the option. 2575 AsyncResult.forMessage(onComplete, null, 2576 new CommandException(CommandException.Error.INVALID_STATE, 2577 "Call Forwarding over CDMA unavailable")); 2578 } else { 2579 loge("getCallForwardingOption: not possible in CDMA, just return empty result"); 2580 AsyncResult.forMessage(onComplete, makeEmptyCallForward(), null); 2581 } 2582 onComplete.sendToTarget(); 2583 } 2584 } 2585 2586 @Override setCallForwardingOption(int commandInterfaceCFAction, int commandInterfaceCFReason, String dialingNumber, int timerSeconds, Message onComplete)2587 public void setCallForwardingOption(int commandInterfaceCFAction, 2588 int commandInterfaceCFReason, 2589 String dialingNumber, 2590 int timerSeconds, 2591 Message onComplete) { 2592 setCallForwardingOption(commandInterfaceCFAction, commandInterfaceCFReason, 2593 dialingNumber, CommandsInterface.SERVICE_CLASS_VOICE, timerSeconds, onComplete); 2594 } 2595 2596 @Override setCallForwardingOption(int commandInterfaceCFAction, int commandInterfaceCFReason, String dialingNumber, int serviceClass, int timerSeconds, Message onComplete)2597 public void setCallForwardingOption(int commandInterfaceCFAction, 2598 int commandInterfaceCFReason, 2599 String dialingNumber, 2600 int serviceClass, 2601 int timerSeconds, 2602 Message onComplete) { 2603 // Perform FDN check 2604 SsData.RequestType requestType = GsmMmiCode.cfActionToRequestType(commandInterfaceCFAction); 2605 SsData.ServiceType serviceType = GsmMmiCode.cfReasonToServiceType(commandInterfaceCFReason); 2606 if(isRequestBlockedByFDN(requestType, serviceType)) { 2607 AsyncResult.forMessage(onComplete, null, 2608 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2609 onComplete.sendToTarget(); 2610 return; 2611 } 2612 2613 Phone imsPhone = mImsPhone; 2614 if (useSsOverIms(onComplete)) { 2615 imsPhone.setCallForwardingOption(commandInterfaceCFAction, commandInterfaceCFReason, 2616 dialingNumber, serviceClass, timerSeconds, onComplete); 2617 return; 2618 } 2619 2620 if (isPhoneTypeGsm()) { 2621 if ((isValidCommandInterfaceCFAction(commandInterfaceCFAction)) && 2622 (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) { 2623 2624 Message resp; 2625 if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) { 2626 Cfu cfu = new Cfu(dialingNumber, onComplete); 2627 resp = obtainMessage(EVENT_SET_CALL_FORWARD_DONE, 2628 isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, cfu); 2629 } else { 2630 resp = onComplete; 2631 } 2632 mCi.setCallForward(commandInterfaceCFAction, 2633 commandInterfaceCFReason, 2634 serviceClass, 2635 dialingNumber, 2636 timerSeconds, 2637 resp); 2638 } 2639 } else if (mSsOverCdmaSupported) { 2640 String formatNumber = GsmCdmaConnection.formatDialString(dialingNumber); 2641 String cfNumber = CdmaMmiCode.getCallForwardingPrefixAndNumber( 2642 commandInterfaceCFAction, commandInterfaceCFReason, formatNumber); 2643 loge("setCallForwardingOption: dial for set call forwarding" 2644 + " prefixWithNumber= " + cfNumber + " number= " + dialingNumber); 2645 2646 PhoneAccountHandle phoneAccountHandle = subscriptionIdToPhoneAccountHandle(getSubId()); 2647 Bundle extras = new Bundle(); 2648 extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle); 2649 2650 final TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class); 2651 telecomManager.placeCall( 2652 Uri.fromParts(PhoneAccount.SCHEME_TEL, cfNumber, null), extras); 2653 2654 AsyncResult.forMessage(onComplete, CommandsInterface.SS_STATUS_UNKNOWN, null); 2655 onComplete.sendToTarget(); 2656 } else { 2657 loge("setCallForwardingOption: SS over CDMA not supported, can not complete"); 2658 AsyncResult.forMessage(onComplete, CommandsInterface.SS_STATUS_UNKNOWN, null); 2659 onComplete.sendToTarget(); 2660 } 2661 } 2662 2663 @Override getCallBarring(String facility, String password, Message onComplete, int serviceClass)2664 public void getCallBarring(String facility, String password, Message onComplete, 2665 int serviceClass) { 2666 // Perform FDN check 2667 SsData.ServiceType serviceType = GsmMmiCode.cbFacilityToServiceType(facility); 2668 if (isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, serviceType)) { 2669 AsyncResult.forMessage(onComplete, null, 2670 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2671 onComplete.sendToTarget(); 2672 return; 2673 } 2674 2675 Phone imsPhone = mImsPhone; 2676 if (useSsOverIms(onComplete)) { 2677 imsPhone.getCallBarring(facility, password, onComplete, serviceClass); 2678 return; 2679 } 2680 2681 if (isPhoneTypeGsm()) { 2682 mCi.queryFacilityLock(facility, password, serviceClass, onComplete); 2683 } else { 2684 loge("getCallBarringOption: not possible in CDMA"); 2685 } 2686 } 2687 2688 @Override setCallBarring(String facility, boolean lockState, String password, Message onComplete, int serviceClass)2689 public void setCallBarring(String facility, boolean lockState, String password, 2690 Message onComplete, int serviceClass) { 2691 // Perform FDN check 2692 SsData.RequestType requestType = lockState ? SsData.RequestType.SS_ACTIVATION : 2693 SsData.RequestType.SS_DEACTIVATION; 2694 SsData.ServiceType serviceType = GsmMmiCode.cbFacilityToServiceType(facility); 2695 if (isRequestBlockedByFDN(requestType, serviceType)) { 2696 AsyncResult.forMessage(onComplete, null, 2697 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2698 onComplete.sendToTarget(); 2699 return; 2700 } 2701 2702 Phone imsPhone = mImsPhone; 2703 if (useSsOverIms(onComplete)) { 2704 imsPhone.setCallBarring(facility, lockState, password, onComplete, serviceClass); 2705 return; 2706 } 2707 2708 if (isPhoneTypeGsm()) { 2709 mCi.setFacilityLock(facility, lockState, password, serviceClass, onComplete); 2710 } else { 2711 loge("setCallBarringOption: not possible in CDMA"); 2712 } 2713 } 2714 2715 /** 2716 * Changes access code used for call barring 2717 * 2718 * @param facility is one of CB_FACILTY_* 2719 * @param oldPwd is old password 2720 * @param newPwd is new password 2721 * @param onComplete is callback message when the action is completed. 2722 */ changeCallBarringPassword(String facility, String oldPwd, String newPwd, Message onComplete)2723 public void changeCallBarringPassword(String facility, String oldPwd, String newPwd, 2724 Message onComplete) { 2725 // Perform FDN check 2726 SsData.ServiceType serviceType = GsmMmiCode.cbFacilityToServiceType(facility); 2727 ArrayList<String> controlStrings = GsmMmiCode.getControlStringsForPwd( 2728 SsData.RequestType.SS_REGISTRATION, 2729 serviceType); 2730 if(FdnUtils.isSuppServiceRequestBlockedByFdn(mPhoneId, controlStrings, getCountryIso())) { 2731 AsyncResult.forMessage(onComplete, null, 2732 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2733 onComplete.sendToTarget(); 2734 return; 2735 } 2736 2737 if (isPhoneTypeGsm()) { 2738 mCi.changeBarringPassword(facility, oldPwd, newPwd, onComplete); 2739 } else { 2740 loge("changeCallBarringPassword: not possible in CDMA"); 2741 } 2742 } 2743 2744 @Override getOutgoingCallerIdDisplay(Message onComplete)2745 public void getOutgoingCallerIdDisplay(Message onComplete) { 2746 // Perform FDN check 2747 if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, SsData.ServiceType.SS_CLIR)){ 2748 AsyncResult.forMessage(onComplete, null, 2749 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2750 onComplete.sendToTarget(); 2751 return; 2752 } 2753 2754 Phone imsPhone = mImsPhone; 2755 2756 if (useSsOverIms(onComplete)) { 2757 imsPhone.getOutgoingCallerIdDisplay(onComplete); 2758 return; 2759 } 2760 2761 if (isPhoneTypeGsm()) { 2762 mCi.getCLIR(onComplete); 2763 } else { 2764 loge("getOutgoingCallerIdDisplay: not possible in CDMA"); 2765 AsyncResult.forMessage(onComplete, null, 2766 new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)); 2767 onComplete.sendToTarget(); 2768 } 2769 } 2770 2771 @Override setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete)2772 public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) { 2773 // Perform FDN check 2774 SsData.RequestType requestType = GsmMmiCode.clirModeToRequestType(commandInterfaceCLIRMode); 2775 if (isRequestBlockedByFDN(requestType, SsData.ServiceType.SS_CLIR)) { 2776 AsyncResult.forMessage(onComplete, null, 2777 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2778 onComplete.sendToTarget(); 2779 return; 2780 } 2781 2782 Phone imsPhone = mImsPhone; 2783 if (useSsOverIms(onComplete)) { 2784 imsPhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode, onComplete); 2785 return; 2786 } 2787 2788 if (isPhoneTypeGsm()) { 2789 // Packing CLIR value in the message. This will be required for 2790 // SharedPreference caching, if the message comes back as part of 2791 // a success response. 2792 mCi.setCLIR(commandInterfaceCLIRMode, 2793 obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete)); 2794 } else { 2795 loge("setOutgoingCallerIdDisplay: not possible in CDMA"); 2796 AsyncResult.forMessage(onComplete, null, 2797 new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)); 2798 onComplete.sendToTarget(); 2799 } 2800 } 2801 2802 @Override queryCLIP(Message onComplete)2803 public void queryCLIP(Message onComplete) { 2804 // Perform FDN check 2805 if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, SsData.ServiceType.SS_CLIP)){ 2806 AsyncResult.forMessage(onComplete, null, 2807 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2808 onComplete.sendToTarget(); 2809 return; 2810 } 2811 2812 Phone imsPhone = mImsPhone; 2813 if (useSsOverIms(onComplete)) { 2814 imsPhone.queryCLIP(onComplete); 2815 return; 2816 } 2817 2818 if (isPhoneTypeGsm()) { 2819 mCi.queryCLIP(onComplete); 2820 } else { 2821 loge("queryCLIP: not possible in CDMA"); 2822 AsyncResult.forMessage(onComplete, null, 2823 new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)); 2824 onComplete.sendToTarget(); 2825 } 2826 } 2827 2828 @Override getCallWaiting(Message onComplete)2829 public void getCallWaiting(Message onComplete) { 2830 // Perform FDN check 2831 if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, SsData.ServiceType.SS_WAIT)){ 2832 AsyncResult.forMessage(onComplete, null, 2833 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2834 onComplete.sendToTarget(); 2835 return; 2836 } 2837 2838 if (mCallWaitingController.getCallWaiting(onComplete)) return; 2839 2840 Phone imsPhone = mImsPhone; 2841 if (useSsOverIms(onComplete)) { 2842 imsPhone.getCallWaiting(onComplete); 2843 return; 2844 } 2845 2846 if (isPhoneTypeGsm()) { 2847 //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service 2848 //class parameter in call waiting interrogation to network 2849 mCi.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete); 2850 } else { 2851 if (!mSsOverCdmaSupported) { 2852 // If SS over CDMA is not supported and UT is not at the time, notify the user of 2853 // the error and disable the option. 2854 AsyncResult.forMessage(onComplete, null, 2855 new CommandException(CommandException.Error.INVALID_STATE, 2856 "Call Waiting over CDMA unavailable")); 2857 } else { 2858 int[] arr = 2859 {CommandsInterface.SS_STATUS_UNKNOWN, CommandsInterface.SERVICE_CLASS_NONE}; 2860 AsyncResult.forMessage(onComplete, arr, null); 2861 } 2862 onComplete.sendToTarget(); 2863 } 2864 } 2865 2866 @Override setCallWaiting(boolean enable, Message onComplete)2867 public void setCallWaiting(boolean enable, Message onComplete) { 2868 int serviceClass = CommandsInterface.SERVICE_CLASS_VOICE; 2869 CarrierConfigManager configManager = (CarrierConfigManager) 2870 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 2871 PersistableBundle b = configManager.getConfigForSubId(getSubId()); 2872 if (b != null) { 2873 serviceClass = b.getInt(CarrierConfigManager.KEY_CALL_WAITING_SERVICE_CLASS_INT, 2874 CommandsInterface.SERVICE_CLASS_VOICE); 2875 } 2876 setCallWaiting(enable, serviceClass, onComplete); 2877 } 2878 2879 @Override setCallWaiting(boolean enable, int serviceClass, Message onComplete)2880 public void setCallWaiting(boolean enable, int serviceClass, Message onComplete) { 2881 // Perform FDN check 2882 SsData.RequestType requestType = enable ? SsData.RequestType.SS_ACTIVATION : 2883 SsData.RequestType.SS_DEACTIVATION; 2884 if (isRequestBlockedByFDN(requestType, SsData.ServiceType.SS_WAIT)) { 2885 AsyncResult.forMessage(onComplete, null, 2886 new CommandException(CommandException.Error.FDN_CHECK_FAILURE)); 2887 onComplete.sendToTarget(); 2888 return; 2889 } 2890 2891 if (mCallWaitingController.setCallWaiting(enable, serviceClass, onComplete)) return; 2892 2893 Phone imsPhone = mImsPhone; 2894 if (useSsOverIms(onComplete)) { 2895 imsPhone.setCallWaiting(enable, onComplete); 2896 return; 2897 } 2898 2899 if (isPhoneTypeGsm()) { 2900 mCi.setCallWaiting(enable, serviceClass, onComplete); 2901 } else if (mSsOverCdmaSupported) { 2902 String cwPrefix = CdmaMmiCode.getCallWaitingPrefix(enable); 2903 Rlog.i( 2904 LOG_TAG, 2905 "setCallWaiting in CDMA : dial for set call waiting" + " prefix= " + cwPrefix); 2906 2907 PhoneAccountHandle phoneAccountHandle = subscriptionIdToPhoneAccountHandle(getSubId()); 2908 Bundle extras = new Bundle(); 2909 extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle); 2910 2911 final TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class); 2912 telecomManager.placeCall( 2913 Uri.fromParts(PhoneAccount.SCHEME_TEL, cwPrefix, null), extras); 2914 2915 AsyncResult.forMessage(onComplete, CommandsInterface.SS_STATUS_UNKNOWN, null); 2916 onComplete.sendToTarget(); 2917 } else { 2918 loge("setCallWaiting: SS over CDMA not supported, can not complete"); 2919 AsyncResult.forMessage(onComplete, CommandsInterface.SS_STATUS_UNKNOWN, null); 2920 onComplete.sendToTarget(); 2921 } 2922 } 2923 2924 @Override getTerminalBasedCallWaitingState(boolean forCsOnly)2925 public int getTerminalBasedCallWaitingState(boolean forCsOnly) { 2926 return mCallWaitingController.getTerminalBasedCallWaitingState(forCsOnly); 2927 } 2928 2929 @Override setTerminalBasedCallWaitingStatus(int state)2930 public void setTerminalBasedCallWaitingStatus(int state) { 2931 if (mImsPhone != null) { 2932 mImsPhone.setTerminalBasedCallWaitingStatus(state); 2933 } 2934 } 2935 2936 @Override setTerminalBasedCallWaitingSupported(boolean supported)2937 public void setTerminalBasedCallWaitingSupported(boolean supported) { 2938 mCallWaitingController.setTerminalBasedCallWaitingSupported(supported); 2939 } 2940 2941 @Override getAvailableNetworks(Message response)2942 public void getAvailableNetworks(Message response) { 2943 if (isPhoneTypeGsm() || isPhoneTypeCdmaLte()) { 2944 Message msg = obtainMessage(EVENT_GET_AVAILABLE_NETWORKS_DONE, response); 2945 mCi.getAvailableNetworks(msg); 2946 } else { 2947 loge("getAvailableNetworks: not possible in CDMA"); 2948 } 2949 } 2950 2951 @Override startNetworkScan(NetworkScanRequest nsr, Message response)2952 public void startNetworkScan(NetworkScanRequest nsr, Message response) { 2953 mCi.startNetworkScan(nsr, response); 2954 } 2955 2956 @Override stopNetworkScan(Message response)2957 public void stopNetworkScan(Message response) { 2958 mCi.stopNetworkScan(response); 2959 } 2960 2961 @Override setTTYMode(int ttyMode, Message onComplete)2962 public void setTTYMode(int ttyMode, Message onComplete) { 2963 // Send out the TTY Mode change over RIL as well 2964 super.setTTYMode(ttyMode, onComplete); 2965 if (mImsPhone != null) { 2966 mImsPhone.setTTYMode(ttyMode, onComplete); 2967 } 2968 } 2969 2970 @Override setUiTTYMode(int uiTtyMode, Message onComplete)2971 public void setUiTTYMode(int uiTtyMode, Message onComplete) { 2972 if (mImsPhone != null) { 2973 mImsPhone.setUiTTYMode(uiTtyMode, onComplete); 2974 } 2975 } 2976 2977 @Override setMute(boolean muted)2978 public void setMute(boolean muted) { 2979 mCT.setMute(muted); 2980 } 2981 2982 @Override getMute()2983 public boolean getMute() { 2984 return mCT.getMute(); 2985 } 2986 2987 @Override updateServiceLocation(WorkSource workSource)2988 public void updateServiceLocation(WorkSource workSource) { 2989 mSST.enableSingleLocationUpdate(workSource); 2990 } 2991 2992 @Override enableLocationUpdates()2993 public void enableLocationUpdates() { 2994 mSST.enableLocationUpdates(); 2995 } 2996 2997 @Override disableLocationUpdates()2998 public void disableLocationUpdates() { 2999 mSST.disableLocationUpdates(); 3000 } 3001 3002 @Override getDataRoamingEnabled()3003 public boolean getDataRoamingEnabled() { 3004 return getDataSettingsManager().isDataRoamingEnabled(); 3005 } 3006 3007 @Override setDataRoamingEnabled(boolean enable)3008 public void setDataRoamingEnabled(boolean enable) { 3009 getDataSettingsManager().setDataRoamingEnabled(enable); 3010 } 3011 3012 @Override registerForCdmaOtaStatusChange(Handler h, int what, Object obj)3013 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 3014 mCi.registerForCdmaOtaProvision(h, what, obj); 3015 } 3016 3017 @Override unregisterForCdmaOtaStatusChange(Handler h)3018 public void unregisterForCdmaOtaStatusChange(Handler h) { 3019 mCi.unregisterForCdmaOtaProvision(h); 3020 } 3021 3022 @Override registerForSubscriptionInfoReady(Handler h, int what, Object obj)3023 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 3024 mSST.registerForSubscriptionInfoReady(h, what, obj); 3025 } 3026 3027 @Override unregisterForSubscriptionInfoReady(Handler h)3028 public void unregisterForSubscriptionInfoReady(Handler h) { 3029 mSST.unregisterForSubscriptionInfoReady(h); 3030 } 3031 3032 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 3033 @Override setOnEcbModeExitResponse(Handler h, int what, Object obj)3034 public void setOnEcbModeExitResponse(Handler h, int what, Object obj) { 3035 mEcmExitRespRegistrant = new Registrant(h, what, obj); 3036 } 3037 3038 @Override unsetOnEcbModeExitResponse(Handler h)3039 public void unsetOnEcbModeExitResponse(Handler h) { 3040 mEcmExitRespRegistrant.clear(); 3041 } 3042 3043 @Override registerForCallWaiting(Handler h, int what, Object obj)3044 public void registerForCallWaiting(Handler h, int what, Object obj) { 3045 if (mCT != null) mCT.registerForCallWaiting(h, what, obj); 3046 } 3047 3048 @Override unregisterForCallWaiting(Handler h)3049 public void unregisterForCallWaiting(Handler h) { 3050 if (mCT != null) mCT.unregisterForCallWaiting(h); 3051 } 3052 3053 /** 3054 * Whether data is enabled by user. 3055 */ 3056 @Override isUserDataEnabled()3057 public boolean isUserDataEnabled() { 3058 return getDataSettingsManager().isDataEnabledForReason( 3059 TelephonyManager.DATA_ENABLED_REASON_USER); 3060 } 3061 3062 /** 3063 * Removes the given MMI from the pending list and notifies 3064 * registrants that it is complete. 3065 * @param mmi MMI that is done 3066 */ onMMIDone(MmiCode mmi)3067 public void onMMIDone(MmiCode mmi) { 3068 /* Only notify complete if it's on the pending list. 3069 * Otherwise, it's already been handled (eg, previously canceled). 3070 * The exception is cancellation of an incoming USSD-REQUEST, which is 3071 * not on the list. 3072 */ 3073 if (mPendingMMIs.remove(mmi) || (isPhoneTypeGsm() && (mmi.isUssdRequest() || 3074 ((GsmMmiCode)mmi).isSsInfo()))) { 3075 ResultReceiver receiverCallback = mmi.getUssdCallbackReceiver(); 3076 if (receiverCallback != null) { 3077 Rlog.i(LOG_TAG, "onMMIDone: invoking callback: " + mmi); 3078 int returnCode = (mmi.getState() == MmiCode.State.COMPLETE) ? 3079 TelephonyManager.USSD_RETURN_SUCCESS : TelephonyManager.USSD_RETURN_FAILURE; 3080 sendUssdResponse(mmi.getDialString(), mmi.getMessage(), returnCode, 3081 receiverCallback ); 3082 } else { 3083 Rlog.i(LOG_TAG, "onMMIDone: notifying registrants: " + mmi); 3084 mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); 3085 } 3086 } else { 3087 Rlog.i(LOG_TAG, "onMMIDone: invalid response or already handled; ignoring: " + mmi); 3088 } 3089 } 3090 supports3gppCallForwardingWhileRoaming()3091 public boolean supports3gppCallForwardingWhileRoaming() { 3092 CarrierConfigManager configManager = (CarrierConfigManager) 3093 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 3094 PersistableBundle b = configManager.getConfigForSubId(getSubId()); 3095 if (b != null) { 3096 return b.getBoolean( 3097 CarrierConfigManager.KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL, true); 3098 } else { 3099 // Default value set in CarrierConfigManager 3100 return true; 3101 } 3102 } 3103 onNetworkInitiatedUssd(MmiCode mmi)3104 private void onNetworkInitiatedUssd(MmiCode mmi) { 3105 Rlog.v(LOG_TAG, "onNetworkInitiatedUssd: mmi=" + mmi); 3106 mMmiCompleteRegistrants.notifyRegistrants( 3107 new AsyncResult(null, mmi, null)); 3108 } 3109 3110 /** ussdMode is one of CommandsInterface.USSD_MODE_* */ onIncomingUSSD(int ussdMode, String ussdMessage)3111 private void onIncomingUSSD (int ussdMode, String ussdMessage) { 3112 if (!isPhoneTypeGsm()) { 3113 loge("onIncomingUSSD: not expected on GSM"); 3114 } 3115 3116 boolean isUssdError; 3117 boolean isUssdRequest; 3118 boolean isUssdRelease; 3119 3120 isUssdRequest 3121 = (ussdMode == CommandsInterface.USSD_MODE_REQUEST); 3122 3123 isUssdError 3124 = (ussdMode != CommandsInterface.USSD_MODE_NOTIFY 3125 && ussdMode != CommandsInterface.USSD_MODE_REQUEST); 3126 3127 isUssdRelease = (ussdMode == CommandsInterface.USSD_MODE_NW_RELEASE); 3128 3129 3130 // See comments in GsmMmiCode.java 3131 // USSD requests aren't finished until one 3132 // of these two events happen 3133 GsmMmiCode found = null; 3134 for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) { 3135 if(((GsmMmiCode)mPendingMMIs.get(i)).isPendingUSSD()) { 3136 found = (GsmMmiCode)mPendingMMIs.get(i); 3137 break; 3138 } 3139 } 3140 3141 if (found != null) { 3142 // Complete pending USSD 3143 if (isUssdRelease) { 3144 found.onUssdRelease(); 3145 } else if (isUssdError) { 3146 found.onUssdFinishedError(); 3147 } else { 3148 found.onUssdFinished(ussdMessage, isUssdRequest); 3149 } 3150 } else if (!isUssdError && !TextUtils.isEmpty(ussdMessage)) { 3151 // pending USSD not found 3152 // The network may initiate its own USSD request 3153 3154 // ignore everything that isnt a Notify or a Request 3155 // also, discard if there is no message to present 3156 GsmMmiCode mmi; 3157 mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage, 3158 isUssdRequest, 3159 GsmCdmaPhone.this, 3160 mUiccApplication.get()); 3161 onNetworkInitiatedUssd(mmi); 3162 } else if (isUssdError && !isUssdRelease) { 3163 GsmMmiCode mmi; 3164 mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage, 3165 true, 3166 GsmCdmaPhone.this, 3167 mUiccApplication.get()); 3168 mmi.onUssdFinishedError(); 3169 } 3170 } 3171 3172 /** 3173 * Make sure the network knows our preferred setting. 3174 */ 3175 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) syncClirSetting()3176 private void syncClirSetting() { 3177 if (!hasCalling()) return; 3178 3179 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 3180 migrateClirSettingIfNeeded(sp); 3181 3182 int clirSetting = sp.getInt(CLIR_KEY + getSubId(), -1); 3183 Rlog.i(LOG_TAG, "syncClirSetting: " + CLIR_KEY + getSubId() + "=" + clirSetting); 3184 if (clirSetting >= 0) { 3185 mCi.setCLIR(clirSetting, null); 3186 } else { 3187 // if there is no preference set, ensure the CLIR is updated to the default value in 3188 // order to ensure that CLIR values in the RIL are not carried over during SIM swap. 3189 mCi.setCLIR(CommandsInterface.CLIR_DEFAULT, null); 3190 } 3191 } 3192 3193 /** 3194 * Migrate CLIR setting with sudId mapping once if there's CLIR setting mapped with phoneId. 3195 */ migrateClirSettingIfNeeded(SharedPreferences sp)3196 private void migrateClirSettingIfNeeded(SharedPreferences sp) { 3197 // Get old CLIR setting mapped with phoneId 3198 int clirSetting = sp.getInt("clir_key" + getPhoneId(), -1); 3199 if (clirSetting >= 0) { 3200 // Migrate CLIR setting to new shared preference key with subId 3201 Rlog.i(LOG_TAG, "Migrate CLIR setting: value=" + clirSetting + ", clir_key" 3202 + getPhoneId() + " -> " + CLIR_KEY + getSubId()); 3203 SharedPreferences.Editor editor = sp.edit(); 3204 editor.putInt(CLIR_KEY + getSubId(), clirSetting); 3205 3206 // Remove old CLIR setting key 3207 editor.remove("clir_key" + getPhoneId()).commit(); 3208 } 3209 } 3210 handleRadioAvailable()3211 private void handleRadioAvailable() { 3212 mCi.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE)); 3213 mCi.getImei(obtainMessage(EVENT_GET_DEVICE_IMEI_DONE)); 3214 mCi.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE)); 3215 mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY)); 3216 mCi.areUiccApplicationsEnabled(obtainMessage(EVENT_GET_UICC_APPS_ENABLEMENT_DONE)); 3217 3218 handleNullCipherEnabledChange(); 3219 handleIdentifierDisclosureNotificationPreferenceChange(); 3220 handleNullCipherNotificationPreferenceChanged(); 3221 } 3222 handleRadioOn()3223 private void handleRadioOn() { 3224 /* Proactively query voice radio technologies */ 3225 mCi.getVoiceRadioTechnology(obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE)); 3226 3227 if (!isPhoneTypeGsm()) { 3228 mCdmaSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource(); 3229 } 3230 } 3231 handleRadioOffOrNotAvailable()3232 private void handleRadioOffOrNotAvailable() { 3233 if (isPhoneTypeGsm()) { 3234 // Some MMI requests (eg USSD) are not completed 3235 // within the course of a CommandsInterface request 3236 // If the radio shuts off or resets while one of these 3237 // is pending, we need to clean up. 3238 3239 for (int i = mPendingMMIs.size() - 1; i >= 0; i--) { 3240 if (((GsmMmiCode) mPendingMMIs.get(i)).isPendingUSSD()) { 3241 ((GsmMmiCode) mPendingMMIs.get(i)).onUssdFinishedError(); 3242 } 3243 } 3244 } 3245 mRadioOffOrNotAvailableRegistrants.notifyRegistrants(); 3246 } 3247 handleRadioPowerStateChange()3248 private void handleRadioPowerStateChange() { 3249 @RadioPowerState int newState = mCi.getRadioState(); 3250 Rlog.d(LOG_TAG, "handleRadioPowerStateChange, state= " + newState); 3251 mNotifier.notifyRadioPowerStateChanged(this, newState); 3252 TelephonyMetrics.getInstance().writeRadioState(mPhoneId, newState); 3253 } 3254 3255 @Override handleMessage(Message msg)3256 public void handleMessage(Message msg) { 3257 AsyncResult ar; 3258 Message onComplete; 3259 3260 switch (msg.what) { 3261 case EVENT_RADIO_AVAILABLE: { 3262 handleRadioAvailable(); 3263 } 3264 break; 3265 case EVENT_GET_DEVICE_IMEI_DONE : 3266 parseImeiInfo(msg); 3267 break; 3268 case EVENT_GET_DEVICE_IDENTITY_DONE:{ 3269 ar = (AsyncResult)msg.obj; 3270 3271 if (ar.exception != null) { 3272 break; 3273 } 3274 String[] respId = (String[])ar.result; 3275 if (TextUtils.isEmpty(mImei)) { 3276 mImei = respId[0]; 3277 mImeiSv = respId[1]; 3278 } 3279 mEsn = respId[2]; 3280 mMeid = respId[3]; 3281 // some modems return all 0's instead of null/empty string when MEID is unavailable 3282 if (!TextUtils.isEmpty(mMeid) && mMeid.matches("^0*$")) { 3283 logd("EVENT_GET_DEVICE_IDENTITY_DONE: set mMeid to null"); 3284 mMeid = null; 3285 } 3286 } 3287 break; 3288 3289 case EVENT_EMERGENCY_CALLBACK_MODE_ENTER:{ 3290 handleEnterEmergencyCallbackMode(msg); 3291 } 3292 break; 3293 3294 case EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE:{ 3295 handleExitEmergencyCallbackMode(msg); 3296 } 3297 break; 3298 3299 case EVENT_MODEM_RESET: { 3300 logd("Event EVENT_MODEM_RESET Received" + " isInEcm = " + isInEcm() 3301 + " isPhoneTypeGsm = " + isPhoneTypeGsm() + " mImsPhone = " + mImsPhone); 3302 if (isInEcm()) { 3303 if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { 3304 EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(); 3305 } else { 3306 if (isPhoneTypeGsm()) { 3307 if (mImsPhone != null) { 3308 mImsPhone.handleExitEmergencyCallbackMode(); 3309 } 3310 } else { 3311 handleExitEmergencyCallbackMode(msg); 3312 } 3313 } 3314 } 3315 } 3316 break; 3317 3318 case EVENT_RUIM_RECORDS_LOADED: 3319 logd("Event EVENT_RUIM_RECORDS_LOADED Received"); 3320 updateCurrentCarrierInProvider(); 3321 break; 3322 3323 case EVENT_RADIO_ON: 3324 logd("Event EVENT_RADIO_ON Received"); 3325 handleRadioOn(); 3326 break; 3327 3328 case EVENT_RIL_CONNECTED: 3329 ar = (AsyncResult) msg.obj; 3330 if (ar.exception == null && ar.result != null) { 3331 mRilVersion = (Integer) ar.result; 3332 } else { 3333 logd("Unexpected exception on EVENT_RIL_CONNECTED"); 3334 mRilVersion = -1; 3335 } 3336 break; 3337 3338 case EVENT_VOICE_RADIO_TECH_CHANGED: 3339 case EVENT_REQUEST_VOICE_RADIO_TECH_DONE: 3340 String what = (msg.what == EVENT_VOICE_RADIO_TECH_CHANGED) ? 3341 "EVENT_VOICE_RADIO_TECH_CHANGED" : "EVENT_REQUEST_VOICE_RADIO_TECH_DONE"; 3342 ar = (AsyncResult) msg.obj; 3343 if (ar.exception == null) { 3344 if ((ar.result != null) && (((int[]) ar.result).length != 0)) { 3345 int newVoiceTech = ((int[]) ar.result)[0]; 3346 logd(what + ": newVoiceTech=" + newVoiceTech); 3347 phoneObjectUpdater(newVoiceTech); 3348 } else { 3349 loge(what + ": has no tech!"); 3350 } 3351 } else { 3352 loge(what + ": exception=" + ar.exception); 3353 } 3354 break; 3355 3356 case EVENT_LINK_CAPACITY_CHANGED: 3357 ar = (AsyncResult) msg.obj; 3358 if (ar.exception == null && ar.result != null) { 3359 updateLinkCapacityEstimate((List<LinkCapacityEstimate>) ar.result); 3360 } else { 3361 logd("Unexpected exception on EVENT_LINK_CAPACITY_CHANGED"); 3362 } 3363 break; 3364 3365 case EVENT_UPDATE_PHONE_OBJECT: 3366 phoneObjectUpdater(msg.arg1); 3367 break; 3368 3369 case EVENT_CARRIER_CONFIG_CHANGED: 3370 // Only check for the voice radio tech if it not going to be updated by the voice 3371 // registration changes. 3372 if (!mContext.getResources().getBoolean( 3373 com.android.internal.R.bool 3374 .config_switch_phone_on_voice_reg_state_change)) { 3375 mCi.getVoiceRadioTechnology(obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE)); 3376 } 3377 3378 CarrierConfigManager configMgr = (CarrierConfigManager) 3379 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 3380 final PersistableBundle b = configMgr.getConfigForSubId(getSubId()); 3381 if (b != null) { 3382 updateBroadcastEmergencyCallStateChangesAfterCarrierConfigChanged(b); 3383 updateCdmaRoamingSettingsAfterCarrierConfigChanged(b); 3384 if (hasCalling()) { 3385 updateNrSettingsAfterCarrierConfigChanged(b); 3386 updateVoNrSettings(b); 3387 } 3388 updateSsOverCdmaSupported(b); 3389 updateCarrierN1ModeSupported(b); 3390 } else { 3391 loge("Failed to retrieve a carrier config bundle for subId=" + getSubId()); 3392 } 3393 loadAllowedNetworksFromSubscriptionDatabase(); 3394 // Obtain new radio capabilities from the modem, since some are SIM-dependent 3395 mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY)); 3396 break; 3397 3398 case EVENT_SET_ROAMING_PREFERENCE_DONE: 3399 logd("cdma_roaming_mode change is done"); 3400 break; 3401 3402 case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: 3403 logd("EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED"); 3404 mCdmaSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource(); 3405 break; 3406 3407 case EVENT_REGISTERED_TO_NETWORK: 3408 logd("Event EVENT_REGISTERED_TO_NETWORK Received"); 3409 if (isPhoneTypeGsm()) { 3410 syncClirSetting(); 3411 } 3412 break; 3413 3414 case EVENT_SIM_RECORDS_LOADED: 3415 updateCurrentCarrierInProvider(); 3416 3417 // Check if this is a different SIM than the previous one. If so unset the 3418 // voice mail number. 3419 String imsi = getVmSimImsi(); 3420 String imsiFromSIM = getSubscriberId(); 3421 if ((!isPhoneTypeGsm() || imsi != null) && imsiFromSIM != null 3422 && !imsiFromSIM.equals(imsi)) { 3423 storeVoiceMailNumber(null); 3424 setVmSimImsi(null); 3425 } 3426 3427 updateVoiceMail(); 3428 3429 mSimRecordsLoadedRegistrants.notifyRegistrants(); 3430 break; 3431 3432 case EVENT_GET_BASEBAND_VERSION_DONE: 3433 ar = (AsyncResult)msg.obj; 3434 3435 if (ar.exception != null) { 3436 break; 3437 } 3438 3439 if (DBG) logd("Baseband version: " + ar.result); 3440 /* Android property value is limited to 91 characters, but low layer 3441 could pass a larger version string. To avoid runtime exception, 3442 truncate the string baseband version string to 45 characters at most 3443 for this per sub property. Since the latter part of the version string 3444 is meaningful, truncated the version string from the beginning and 3445 keep the end of the version. 3446 */ 3447 String version = (String)ar.result; 3448 if (version != null) { 3449 int length = version.length(); 3450 final int MAX_VERSION_LEN = SystemProperties.PROP_VALUE_MAX/2; 3451 TelephonyManager.from(mContext).setBasebandVersionForPhone(getPhoneId(), 3452 length <= MAX_VERSION_LEN ? version 3453 : version.substring(length - MAX_VERSION_LEN, length)); 3454 } 3455 break; 3456 3457 case EVENT_USSD: 3458 ar = (AsyncResult)msg.obj; 3459 3460 String[] ussdResult = (String[]) ar.result; 3461 3462 if (ussdResult.length > 1) { 3463 try { 3464 onIncomingUSSD(Integer.parseInt(ussdResult[0]), ussdResult[1]); 3465 } catch (NumberFormatException e) { 3466 Rlog.w(LOG_TAG, "error parsing USSD"); 3467 } 3468 } 3469 break; 3470 3471 case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: { 3472 logd("Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received"); 3473 handleRadioOffOrNotAvailable(); 3474 break; 3475 } 3476 3477 case EVENT_RADIO_STATE_CHANGED: { 3478 logd("EVENT EVENT_RADIO_STATE_CHANGED"); 3479 handleRadioPowerStateChange(); 3480 break; 3481 } 3482 3483 case EVENT_SSN: 3484 logd("Event EVENT_SSN Received"); 3485 if (isPhoneTypeGsm()) { 3486 ar = (AsyncResult) msg.obj; 3487 SuppServiceNotification not = (SuppServiceNotification) ar.result; 3488 mSsnRegistrants.notifyRegistrants(ar); 3489 } 3490 break; 3491 3492 case EVENT_REGISTRATION_FAILED: 3493 logd("Event RegistrationFailed Received"); 3494 ar = (AsyncResult) msg.obj; 3495 RegistrationFailedEvent rfe = (RegistrationFailedEvent) ar.result; 3496 mNotifier.notifyRegistrationFailed(this, rfe.cellIdentity, rfe.chosenPlmn, 3497 rfe.domain, rfe.causeCode, rfe.additionalCauseCode); 3498 break; 3499 3500 case EVENT_BARRING_INFO_CHANGED: 3501 logd("Event BarringInfoChanged Received"); 3502 ar = (AsyncResult) msg.obj; 3503 BarringInfo barringInfo = (BarringInfo) ar.result; 3504 mNotifier.notifyBarringInfoChanged(this, barringInfo); 3505 break; 3506 3507 case EVENT_SET_CALL_FORWARD_DONE: 3508 ar = (AsyncResult)msg.obj; 3509 Cfu cfu = (Cfu) ar.userObj; 3510 if (ar.exception == null) { 3511 setVoiceCallForwardingFlag(1, msg.arg1 == 1, cfu.mSetCfNumber); 3512 } 3513 if (cfu.mOnComplete != null) { 3514 AsyncResult.forMessage(cfu.mOnComplete, ar.result, ar.exception); 3515 cfu.mOnComplete.sendToTarget(); 3516 } 3517 break; 3518 3519 case EVENT_SET_VM_NUMBER_DONE: 3520 ar = (AsyncResult)msg.obj; 3521 if (((isPhoneTypeGsm() || mSimRecords != null) 3522 && IccVmNotSupportedException.class.isInstance(ar.exception)) 3523 || (!isPhoneTypeGsm() && mSimRecords == null 3524 && IccException.class.isInstance(ar.exception))) { 3525 storeVoiceMailNumber(mVmNumber); 3526 ar.exception = null; 3527 } 3528 onComplete = (Message) ar.userObj; 3529 if (onComplete != null) { 3530 AsyncResult.forMessage(onComplete, ar.result, ar.exception); 3531 onComplete.sendToTarget(); 3532 } 3533 break; 3534 3535 3536 case EVENT_GET_CALL_FORWARD_DONE: 3537 ar = (AsyncResult)msg.obj; 3538 if (ar.exception == null) { 3539 handleCfuQueryResult((CallForwardInfo[])ar.result); 3540 } 3541 onComplete = (Message) ar.userObj; 3542 if (onComplete != null) { 3543 AsyncResult.forMessage(onComplete, ar.result, ar.exception); 3544 onComplete.sendToTarget(); 3545 } 3546 break; 3547 3548 case EVENT_SET_NETWORK_AUTOMATIC: 3549 // Automatic network selection from EF_CSP SIM record 3550 ar = (AsyncResult) msg.obj; 3551 if (mSST.mSS.getIsManualSelection()) { 3552 setNetworkSelectionModeAutomatic((Message) ar.result); 3553 logd("SET_NETWORK_SELECTION_AUTOMATIC: set to automatic"); 3554 } else { 3555 // prevent duplicate request which will push current PLMN to low priority 3556 logd("SET_NETWORK_SELECTION_AUTOMATIC: already automatic, ignore"); 3557 } 3558 break; 3559 3560 case EVENT_ICC_RECORD_EVENTS: 3561 ar = (AsyncResult)msg.obj; 3562 processIccRecordEvents((Integer)ar.result); 3563 break; 3564 3565 case EVENT_SET_CLIR_COMPLETE: 3566 ar = (AsyncResult)msg.obj; 3567 if (ar.exception == null) { 3568 saveClirSetting(msg.arg1); 3569 } 3570 onComplete = (Message) ar.userObj; 3571 if (onComplete != null) { 3572 AsyncResult.forMessage(onComplete, ar.result, ar.exception); 3573 onComplete.sendToTarget(); 3574 } 3575 break; 3576 3577 case EVENT_SS: 3578 ar = (AsyncResult)msg.obj; 3579 logd("Event EVENT_SS received"); 3580 if (isPhoneTypeGsm()) { 3581 // SS data is already being handled through MMI codes. 3582 // So, this result if processed as MMI response would help 3583 // in re-using the existing functionality. 3584 GsmMmiCode mmi = new GsmMmiCode(this, mUiccApplication.get()); 3585 mmi.processSsData(ar); 3586 } 3587 break; 3588 3589 case EVENT_GET_RADIO_CAPABILITY: 3590 ar = (AsyncResult) msg.obj; 3591 RadioCapability rc = (RadioCapability) ar.result; 3592 if (ar.exception != null) { 3593 Rlog.d(LOG_TAG, "get phone radio capability fail, no need to change " + 3594 "mRadioCapability"); 3595 } else { 3596 radioCapabilityUpdated(rc, false); 3597 } 3598 Rlog.d(LOG_TAG, "EVENT_GET_RADIO_CAPABILITY: phone rc: " + rc); 3599 break; 3600 case EVENT_VRS_OR_RAT_CHANGED: 3601 ar = (AsyncResult) msg.obj; 3602 Pair<Integer, Integer> vrsRatPair = (Pair<Integer, Integer>) ar.result; 3603 onVoiceRegStateOrRatChanged(vrsRatPair.first, vrsRatPair.second); 3604 break; 3605 3606 case EVENT_SET_CARRIER_DATA_ENABLED: 3607 ar = (AsyncResult) msg.obj; 3608 boolean enabled = (boolean) ar.result; 3609 getDataSettingsManager().setDataEnabled( 3610 TelephonyManager.DATA_ENABLED_REASON_CARRIER, enabled, 3611 mContext.getOpPackageName()); 3612 break; 3613 case EVENT_GET_AVAILABLE_NETWORKS_DONE: 3614 ar = (AsyncResult) msg.obj; 3615 if (ar.exception == null && ar.result != null && mSST != null) { 3616 List<OperatorInfo> operatorInfoList = (List<OperatorInfo>) ar.result; 3617 List<OperatorInfo> filteredInfoList = new ArrayList<>(); 3618 for (OperatorInfo operatorInfo : operatorInfoList) { 3619 if (OperatorInfo.State.CURRENT == operatorInfo.getState()) { 3620 filteredInfoList.add(new OperatorInfo( 3621 mSST.filterOperatorNameByPattern( 3622 operatorInfo.getOperatorAlphaLong()), 3623 mSST.filterOperatorNameByPattern( 3624 operatorInfo.getOperatorAlphaShort()), 3625 operatorInfo.getOperatorNumeric(), 3626 operatorInfo.getState() 3627 )); 3628 } else { 3629 filteredInfoList.add(operatorInfo); 3630 } 3631 } 3632 ar.result = filteredInfoList; 3633 } 3634 3635 onComplete = (Message) ar.userObj; 3636 if (onComplete != null) { 3637 AsyncResult.forMessage(onComplete, ar.result, ar.exception); 3638 onComplete.sendToTarget(); 3639 } 3640 break; 3641 case EVENT_GET_UICC_APPS_ENABLEMENT_DONE: 3642 case EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED: 3643 ar = (AsyncResult) msg.obj; 3644 if (ar == null) return; 3645 if (ar.exception != null) { 3646 logd("Received exception on event" + msg.what + " : " + ar.exception); 3647 return; 3648 } 3649 3650 mUiccApplicationsEnabled = (Boolean) ar.result; 3651 // Intentional falling through. 3652 case EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED: 3653 reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES); 3654 break; 3655 3656 case EVENT_REAPPLY_UICC_APPS_ENABLEMENT_DONE: { 3657 ar = (AsyncResult) msg.obj; 3658 if (ar == null || ar.exception == null) return; 3659 Pair<Boolean, Integer> userObject = (Pair) ar.userObj; 3660 if (userObject == null) return; 3661 boolean expectedValue = userObject.first; 3662 int retries = userObject.second; 3663 CommandException.Error error = ((CommandException) ar.exception).getCommandError(); 3664 loge("Error received when re-applying uicc application" 3665 + " setting to " + expectedValue + " on phone " + mPhoneId 3666 + " Error code: " + error + " retry count left: " + retries); 3667 if (retries > 0 && (error == GENERIC_FAILURE || error == SIM_BUSY)) { 3668 // Retry for certain errors, but not for others like RADIO_NOT_AVAILABLE or 3669 // SIM_ABSENT, as they will trigger it whey they become available. 3670 postDelayed(()->reapplyUiccAppsEnablementIfNeeded(retries - 1), 3671 REAPPLY_UICC_APPS_SETTING_RETRY_TIME_GAP_IN_MS); 3672 } 3673 break; 3674 } 3675 case EVENT_RESET_CARRIER_KEY_IMSI_ENCRYPTION: { 3676 resetCarrierKeysForImsiEncryption(); 3677 break; 3678 } 3679 case EVENT_SET_VONR_ENABLED_DONE: 3680 logd("EVENT_SET_VONR_ENABLED_DONE is done"); 3681 break; 3682 case EVENT_SUBSCRIPTIONS_CHANGED: 3683 logd("EVENT_SUBSCRIPTIONS_CHANGED"); 3684 updateUsageSetting(); 3685 updateNullCipherNotifier(); 3686 break; 3687 case EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE: 3688 logd("EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE"); 3689 ar = (AsyncResult) msg.obj; 3690 mIsNullCipherAndIntegritySupported = doesResultIndicateModemSupport(ar); 3691 break; 3692 3693 case EVENT_IMS_DEREGISTRATION_TRIGGERED: 3694 logd("EVENT_IMS_DEREGISTRATION_TRIGGERED"); 3695 ar = (AsyncResult) msg.obj; 3696 if (ar.exception == null) { 3697 mImsPhone.triggerImsDeregistration(((int[]) ar.result)[0]); 3698 } else { 3699 Rlog.e(LOG_TAG, "Unexpected unsol with exception", ar.exception); 3700 } 3701 break; 3702 3703 case EVENT_TRIGGER_NOTIFY_ANBR: 3704 logd("EVENT_TRIGGER_NOTIFY_ANBR"); 3705 ar = (AsyncResult) msg.obj; 3706 if (ar.exception == null) { 3707 if (mImsPhone != null) { 3708 mImsPhone.triggerNotifyAnbr(((int[]) ar.result)[0], ((int[]) ar.result)[1], 3709 ((int[]) ar.result)[2]); 3710 } 3711 } 3712 break; 3713 3714 case EVENT_GET_N1_MODE_ENABLED_DONE: 3715 logd("EVENT_GET_N1_MODE_ENABLED_DONE"); 3716 ar = (AsyncResult) msg.obj; 3717 if (ar == null || ar.exception != null 3718 || ar.result == null || !(ar.result instanceof Boolean)) { 3719 Rlog.e(LOG_TAG, "Failed to Retrieve N1 Mode", ar.exception); 3720 if (ar != null && ar.userObj instanceof Message) { 3721 // original requester's message is stashed in the userObj 3722 final Message rsp = (Message) ar.userObj; 3723 AsyncResult.forMessage(rsp, null, ar.exception); 3724 rsp.sendToTarget(); 3725 } 3726 break; 3727 } 3728 3729 mModemN1Mode = (Boolean) ar.result; 3730 maybeUpdateModemN1Mode((Message) ar.userObj); 3731 break; 3732 3733 case EVENT_SET_N1_MODE_ENABLED_DONE: 3734 logd("EVENT_SET_N1_MODE_ENABLED_DONE"); 3735 ar = (AsyncResult) msg.obj; 3736 if (ar == null || ar.exception != null) { 3737 Rlog.e(LOG_TAG, "Failed to Set N1 Mode", ar.exception); 3738 // Set failed, so we have no idea at this point. 3739 mModemN1Mode = null; 3740 } 3741 if (ar != null && ar.userObj instanceof Message) { 3742 // original requester's message is stashed in the userObj 3743 final Message rsp = (Message) ar.userObj; 3744 AsyncResult.forMessage(rsp, null, ar.exception); 3745 rsp.sendToTarget(); 3746 } 3747 break; 3748 3749 case EVENT_IMEI_MAPPING_CHANGED: 3750 logd("EVENT_GET_DEVICE_IMEI_CHANGE_DONE phoneId = " + getPhoneId()); 3751 parseImeiInfo(msg); 3752 break; 3753 3754 case EVENT_CELL_IDENTIFIER_DISCLOSURE: 3755 logd("EVENT_CELL_IDENTIFIER_DISCLOSURE phoneId = " + getPhoneId()); 3756 3757 ar = (AsyncResult) msg.obj; 3758 if (ar == null || ar.result == null || ar.exception != null) { 3759 Rlog.e( 3760 LOG_TAG, 3761 "Failed to process cellular identifier disclosure", 3762 ar.exception); 3763 break; 3764 } 3765 3766 CellularIdentifierDisclosure disclosure = (CellularIdentifierDisclosure) ar.result; 3767 if (mIdentifierDisclosureNotifier != null 3768 && disclosure != null) { 3769 mIdentifierDisclosureNotifier.addDisclosure(mContext, getSubId(), disclosure); 3770 } 3771 if (mFeatureFlags.cellularIdentifierDisclosureIndications() 3772 && mIdentifierDisclosureNotifier != null 3773 && disclosure != null) { 3774 logd("EVENT_CELL_IDENTIFIER_DISCLOSURE for non-Safety Center listeners " 3775 + "phoneId = " + getPhoneId()); 3776 mNotifier.notifyCellularIdentifierDisclosedChanged(this, disclosure); 3777 } 3778 break; 3779 3780 case EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE: 3781 logd("EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE"); 3782 ar = (AsyncResult) msg.obj; 3783 mIsIdentifierDisclosureTransparencySupported = doesResultIndicateModemSupport(ar); 3784 break; 3785 3786 case EVENT_SECURITY_ALGORITHM_UPDATE: 3787 logd("EVENT_SECURITY_ALGORITHM_UPDATE phoneId = " + getPhoneId()); 3788 3789 ar = (AsyncResult) msg.obj; 3790 SecurityAlgorithmUpdate update = (SecurityAlgorithmUpdate) ar.result; 3791 3792 if (mNullCipherNotifier != null) { 3793 mNullCipherNotifier.onSecurityAlgorithmUpdate(mContext, getPhoneId(), 3794 getSubId(), update); 3795 } 3796 if (mFeatureFlags.securityAlgorithmsUpdateIndications() 3797 && mNullCipherNotifier != null) { 3798 logd("EVENT_SECURITY_ALGORITHM_UPDATE for non-Safety Center listeners " 3799 + "phoneId = " + getPhoneId()); 3800 mNotifier.notifySecurityAlgorithmsChanged(this, update); 3801 } 3802 break; 3803 3804 case EVENT_SET_SECURITY_ALGORITHMS_UPDATED_ENABLED_DONE: 3805 logd("EVENT_SET_SECURITY_ALGORITHMS_UPDATED_ENABLED_DONE"); 3806 ar = (AsyncResult) msg.obj; 3807 mIsNullCipherNotificationSupported = doesResultIndicateModemSupport(ar); 3808 break; 3809 3810 default: 3811 super.handleMessage(msg); 3812 } 3813 } 3814 doesResultIndicateModemSupport(AsyncResult ar)3815 private boolean doesResultIndicateModemSupport(AsyncResult ar) { 3816 // We can only say that the modem supports a call without ambiguity if there 3817 // is no exception set on the response. Testing for REQUEST_NOT_SUPPORTED, is 3818 // insufficient because the modem or the RIL could still return exceptions for temporary 3819 // failures even when the feature is unsupported. 3820 return (ar == null || ar.exception == null); 3821 } 3822 parseImeiInfo(Message msg)3823 private void parseImeiInfo(Message msg) { 3824 AsyncResult ar = (AsyncResult)msg.obj; 3825 if (ar.exception != null || ar.result == null) { 3826 loge("parseImeiInfo :: Exception received : " + ar.exception); 3827 return; 3828 } 3829 ImeiInfo imeiInfo = (ImeiInfo) ar.result; 3830 if (!TextUtils.isEmpty(imeiInfo.imei)) { 3831 mImeiType = imeiInfo.type; 3832 mImei = imeiInfo.imei; 3833 mImeiSv = imeiInfo.svn; 3834 } else { 3835 loge("parseImeiInfo :: IMEI value is empty"); 3836 } 3837 } 3838 3839 /** 3840 * Check if a different SIM is inserted at this slot from the last time. Storing last subId 3841 * in SharedPreference for now to detect SIM change. 3842 * 3843 * @return {@code true} if current slot mapping changed; {@code false} otherwise. 3844 */ currentSlotSubIdChanged()3845 private boolean currentSlotSubIdChanged() { 3846 SharedPreferences sp = 3847 PreferenceManager.getDefaultSharedPreferences(mContext); 3848 int storedSubId = sp.getInt(CURR_SUBID + mPhoneId, -1); 3849 boolean changed = storedSubId != getSubId(); 3850 if (changed) { 3851 // Update stored subId 3852 SharedPreferences.Editor editor = sp.edit(); 3853 editor.putInt(CURR_SUBID + mPhoneId, getSubId()); 3854 editor.apply(); 3855 } 3856 Rlog.d(LOG_TAG, "currentSlotSubIdChanged: changed=" + changed); 3857 return changed; 3858 } 3859 getUiccCardApplication()3860 public UiccCardApplication getUiccCardApplication() { 3861 if (isPhoneTypeGsm()) { 3862 return mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_3GPP); 3863 } else { 3864 return mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_3GPP2); 3865 } 3866 } 3867 3868 // todo: check if ICC availability needs to be handled here. mSimRecords should not be needed 3869 // now because APIs can be called directly on UiccProfile, and that should handle the requests 3870 // correctly based on supported apps, voice RAT, etc. 3871 @Override onUpdateIccAvailability()3872 protected void onUpdateIccAvailability() { 3873 if (mUiccController == null ) { 3874 return; 3875 } 3876 3877 UiccCardApplication newUiccApplication = null; 3878 3879 // Update mIsimUiccRecords 3880 if (isPhoneTypeGsm() || isPhoneTypeCdmaLte()) { 3881 newUiccApplication = 3882 mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_IMS); 3883 IsimUiccRecords newIsimUiccRecords = null; 3884 3885 if (newUiccApplication != null) { 3886 newIsimUiccRecords = (IsimUiccRecords) newUiccApplication.getIccRecords(); 3887 if (DBG) logd("New ISIM application found"); 3888 } 3889 mIsimUiccRecords = newIsimUiccRecords; 3890 } 3891 3892 // Update mSimRecords 3893 if (mSimRecords != null) { 3894 mSimRecords.unregisterForRecordsLoaded(this); 3895 } 3896 if (isPhoneTypeCdmaLte() || isPhoneTypeCdma()) { 3897 newUiccApplication = mUiccController.getUiccCardApplication(mPhoneId, 3898 UiccController.APP_FAM_3GPP); 3899 SIMRecords newSimRecords = null; 3900 if (newUiccApplication != null) { 3901 newSimRecords = (SIMRecords) newUiccApplication.getIccRecords(); 3902 } 3903 mSimRecords = newSimRecords; 3904 if (mSimRecords != null) { 3905 mSimRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); 3906 } 3907 } else { 3908 mSimRecords = null; 3909 } 3910 3911 // Update mIccRecords, mUiccApplication, mIccPhoneBookIntManager 3912 newUiccApplication = getUiccCardApplication(); 3913 if (!isPhoneTypeGsm() && newUiccApplication == null) { 3914 logd("can't find 3GPP2 application; trying APP_FAM_3GPP"); 3915 newUiccApplication = mUiccController.getUiccCardApplication(mPhoneId, 3916 UiccController.APP_FAM_3GPP); 3917 } 3918 3919 UiccCardApplication app = mUiccApplication.get(); 3920 if (app != newUiccApplication) { 3921 if (app != null) { 3922 if (DBG) logd("Removing stale icc objects."); 3923 if (mIccRecords.get() != null) { 3924 unregisterForIccRecordEvents(); 3925 mIccPhoneBookIntManager.updateIccRecords(null); 3926 } 3927 mIccRecords.set(null); 3928 mUiccApplication.set(null); 3929 } 3930 if (newUiccApplication != null) { 3931 if (DBG) { 3932 logd("New Uicc application found. type = " + newUiccApplication.getType()); 3933 } 3934 final IccRecords iccRecords = newUiccApplication.getIccRecords(); 3935 mUiccApplication.set(newUiccApplication); 3936 mIccRecords.set(iccRecords); 3937 registerForIccRecordEvents(); 3938 mIccPhoneBookIntManager.updateIccRecords(iccRecords); 3939 if (iccRecords != null) { 3940 final String simOperatorNumeric = iccRecords.getOperatorNumeric(); 3941 if (DBG) { 3942 logd("New simOperatorNumeric = " + simOperatorNumeric); 3943 } 3944 if (!TextUtils.isEmpty(simOperatorNumeric)) { 3945 TelephonyManager.from(mContext).setSimOperatorNumericForPhone(mPhoneId, 3946 simOperatorNumeric); 3947 } 3948 } 3949 updateCurrentCarrierInProvider(); 3950 } 3951 } 3952 3953 reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES); 3954 } 3955 processIccRecordEvents(int eventCode)3956 private void processIccRecordEvents(int eventCode) { 3957 switch (eventCode) { 3958 case IccRecords.EVENT_CFI: 3959 logi("processIccRecordEvents: EVENT_CFI"); 3960 notifyCallForwardingIndicator(); 3961 break; 3962 } 3963 } 3964 3965 /** 3966 * Sets the "current" field in the telephony provider according to the SIM's operator 3967 * 3968 * @return true for success; false otherwise. 3969 */ 3970 @Override updateCurrentCarrierInProvider()3971 public boolean updateCurrentCarrierInProvider() { 3972 long currentDds = SubscriptionManager.getDefaultDataSubscriptionId(); 3973 String operatorNumeric = getOperatorNumeric(); 3974 3975 logd("updateCurrentCarrierInProvider: mSubId = " + getSubId() 3976 + " currentDds = " + currentDds + " operatorNumeric = " + operatorNumeric); 3977 3978 if (!TextUtils.isEmpty(operatorNumeric) && (getSubId() == currentDds)) { 3979 try { 3980 Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); 3981 ContentValues map = new ContentValues(); 3982 map.put(Telephony.Carriers.NUMERIC, operatorNumeric); 3983 mContext.getContentResolver().insert(uri, map); 3984 return true; 3985 } catch (SQLException e) { 3986 Rlog.e(LOG_TAG, "Can't store current operator", e); 3987 } 3988 } 3989 return false; 3990 } 3991 3992 //CDMA 3993 /** 3994 * Sets the "current" field in the telephony provider according to the 3995 * build-time operator numeric property 3996 * 3997 * @return true for success; false otherwise. 3998 */ updateCurrentCarrierInProvider(String operatorNumeric)3999 private boolean updateCurrentCarrierInProvider(String operatorNumeric) { 4000 if (isPhoneTypeCdma() 4001 || (isPhoneTypeCdmaLte() && mUiccController.getUiccCardApplication(mPhoneId, 4002 UiccController.APP_FAM_3GPP) == null)) { 4003 logd("CDMAPhone: updateCurrentCarrierInProvider called"); 4004 if (!TextUtils.isEmpty(operatorNumeric)) { 4005 try { 4006 Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); 4007 ContentValues map = new ContentValues(); 4008 map.put(Telephony.Carriers.NUMERIC, operatorNumeric); 4009 logd("updateCurrentCarrierInProvider from system: numeric=" + operatorNumeric); 4010 getContext().getContentResolver().insert(uri, map); 4011 4012 // Updates MCC MNC device configuration information 4013 logd("update mccmnc=" + operatorNumeric); 4014 MccTable.updateMccMncConfiguration(mContext, operatorNumeric); 4015 4016 return true; 4017 } catch (SQLException e) { 4018 Rlog.e(LOG_TAG, "Can't store current operator", e); 4019 } 4020 } 4021 return false; 4022 } else { // isPhoneTypeCdmaLte() 4023 if (DBG) logd("updateCurrentCarrierInProvider not updated X retVal=" + true); 4024 return true; 4025 } 4026 } 4027 handleCfuQueryResult(CallForwardInfo[] infos)4028 private void handleCfuQueryResult(CallForwardInfo[] infos) { 4029 if (infos == null || infos.length == 0) { 4030 // Assume the default is not active 4031 // Set unconditional CFF in SIM to false 4032 setVoiceCallForwardingFlag(1, false, null); 4033 } else { 4034 for (int i = 0, s = infos.length; i < s; i++) { 4035 if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) { 4036 setVoiceCallForwardingFlag(1, (infos[i].status == 1), 4037 infos[i].number); 4038 // should only have the one 4039 break; 4040 } 4041 } 4042 } 4043 } 4044 4045 /** 4046 * Retrieves the IccPhoneBookInterfaceManager of the GsmCdmaPhone 4047 */ 4048 @Override getIccPhoneBookInterfaceManager()4049 public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){ 4050 return mIccPhoneBookIntManager; 4051 } 4052 4053 /** 4054 * Activate or deactivate cell broadcast SMS. 4055 * 4056 * @param activate 0 = activate, 1 = deactivate 4057 * @param response Callback message is empty on completion 4058 */ 4059 @Override activateCellBroadcastSms(int activate, Message response)4060 public void activateCellBroadcastSms(int activate, Message response) { 4061 loge("[GsmCdmaPhone] activateCellBroadcastSms() is obsolete; use SmsManager"); 4062 response.sendToTarget(); 4063 } 4064 4065 /** 4066 * Query the current configuration of cdma cell broadcast SMS. 4067 * 4068 * @param response Callback message is empty on completion 4069 */ 4070 @Override getCellBroadcastSmsConfig(Message response)4071 public void getCellBroadcastSmsConfig(Message response) { 4072 loge("[GsmCdmaPhone] getCellBroadcastSmsConfig() is obsolete; use SmsManager"); 4073 response.sendToTarget(); 4074 } 4075 4076 /** 4077 * Configure cdma cell broadcast SMS. 4078 * 4079 * @param response Callback message is empty on completion 4080 */ 4081 @Override setCellBroadcastSmsConfig(int[] configValuesArray, Message response)4082 public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) { 4083 loge("[GsmCdmaPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager"); 4084 response.sendToTarget(); 4085 } 4086 4087 /** 4088 * Returns true if OTA Service Provisioning needs to be performed. 4089 */ 4090 @Override needsOtaServiceProvisioning()4091 public boolean needsOtaServiceProvisioning() { 4092 if (isPhoneTypeGsm()) { 4093 return false; 4094 } else { 4095 return mSST.getOtasp() != TelephonyManager.OTASP_NOT_NEEDED; 4096 } 4097 } 4098 4099 @Override isCspPlmnEnabled()4100 public boolean isCspPlmnEnabled() { 4101 IccRecords r = mIccRecords.get(); 4102 return (r != null) ? r.isCspPlmnEnabled() : false; 4103 } 4104 4105 /** 4106 * Whether manual select is now allowed and we should set 4107 * to auto network select mode. 4108 */ shouldForceAutoNetworkSelect()4109 public boolean shouldForceAutoNetworkSelect() { 4110 4111 int networkTypeBitmask = RadioAccessFamily.getRafFromNetworkType( 4112 RILConstants.PREFERRED_NETWORK_MODE); 4113 int subId = getSubId(); 4114 4115 // If it's invalid subId, we shouldn't force to auto network select mode. 4116 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 4117 return false; 4118 } 4119 4120 networkTypeBitmask = (int) getAllowedNetworkTypes( 4121 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER); 4122 4123 logd("shouldForceAutoNetworkSelect in mode = " + networkTypeBitmask); 4124 /* 4125 * For multimode targets in global mode manual network 4126 * selection is disallowed. So we should force auto select mode. 4127 */ 4128 if (isManualSelProhibitedInGlobalMode() 4129 && ((networkTypeBitmask == RadioAccessFamily.getRafFromNetworkType( 4130 TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA)) 4131 || (networkTypeBitmask == RadioAccessFamily.getRafFromNetworkType( 4132 TelephonyManager.NETWORK_MODE_GLOBAL)))) { 4133 logd("Should force auto network select mode = " + networkTypeBitmask); 4134 return true; 4135 } else { 4136 logd("Should not force auto network select mode = " + networkTypeBitmask); 4137 } 4138 4139 /* 4140 * Single mode phone with - GSM network modes/global mode 4141 * LTE only for 3GPP 4142 * LTE centric + 3GPP Legacy 4143 * Note: the actual enabling/disabling manual selection for these 4144 * cases will be controlled by csp 4145 */ 4146 return false; 4147 } 4148 4149 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isManualSelProhibitedInGlobalMode()4150 private boolean isManualSelProhibitedInGlobalMode() { 4151 boolean isProhibited = false; 4152 final String configString = getContext().getResources().getString(com.android.internal 4153 .R.string.prohibit_manual_network_selection_in_gobal_mode); 4154 4155 if (!TextUtils.isEmpty(configString)) { 4156 String[] configArray = configString.split(";"); 4157 4158 if (configArray != null && 4159 ((configArray.length == 1 && configArray[0].equalsIgnoreCase("true")) || 4160 (configArray.length == 2 && !TextUtils.isEmpty(configArray[1]) && 4161 configArray[0].equalsIgnoreCase("true") && 4162 isMatchGid(configArray[1])))) { 4163 isProhibited = true; 4164 } 4165 } 4166 logd("isManualNetSelAllowedInGlobal in current carrier is " + isProhibited); 4167 return isProhibited; 4168 } 4169 registerForIccRecordEvents()4170 private void registerForIccRecordEvents() { 4171 IccRecords r = mIccRecords.get(); 4172 if (r == null) { 4173 return; 4174 } 4175 if (isPhoneTypeGsm()) { 4176 r.registerForNetworkSelectionModeAutomatic( 4177 this, EVENT_SET_NETWORK_AUTOMATIC, null); 4178 r.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null); 4179 r.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); 4180 } else { 4181 r.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null); 4182 if (isPhoneTypeCdmaLte()) { 4183 // notify simRecordsLoaded registrants for cdmaLte phone 4184 r.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); 4185 } 4186 } 4187 } 4188 unregisterForIccRecordEvents()4189 private void unregisterForIccRecordEvents() { 4190 IccRecords r = mIccRecords.get(); 4191 if (r == null) { 4192 return; 4193 } 4194 r.unregisterForNetworkSelectionModeAutomatic(this); 4195 r.unregisterForRecordsEvents(this); 4196 r.unregisterForRecordsLoaded(this); 4197 } 4198 4199 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 4200 @Override exitEmergencyCallbackMode()4201 public void exitEmergencyCallbackMode() { 4202 if (DBG) { 4203 Rlog.d(LOG_TAG, "exitEmergencyCallbackMode: mImsPhone=" + mImsPhone 4204 + " isPhoneTypeGsm=" + isPhoneTypeGsm()); 4205 } 4206 if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { 4207 EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(); 4208 return; 4209 } 4210 if (mImsPhone != null && mImsPhone.isInImsEcm()) { 4211 mImsPhone.exitEmergencyCallbackMode(); 4212 } else { 4213 if (mWakeLock.isHeld()) { 4214 mWakeLock.release(); 4215 } 4216 Message msg = null; 4217 if (mIsTestingEmergencyCallbackMode) { 4218 // prevent duplicate exit messages from happening due to this message being handled 4219 // as well as an UNSOL when the modem exits ECbM. Instead, only register for this 4220 // message callback when this is a test and we will not be receiving the UNSOL from 4221 // the modem. 4222 msg = obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE); 4223 } 4224 mCi.exitEmergencyCallbackMode(msg); 4225 } 4226 } 4227 4228 //CDMA handleEnterEmergencyCallbackMode(Message msg)4229 private void handleEnterEmergencyCallbackMode(Message msg) { 4230 if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { 4231 Rlog.d(LOG_TAG, "DomainSelection enabled: ignore ECBM enter event."); 4232 return; 4233 } 4234 if (DBG) { 4235 Rlog.d(LOG_TAG, "handleEnterEmergencyCallbackMode, isInEcm()=" 4236 + isInEcm()); 4237 } 4238 // if phone is not in Ecm mode, and it's changed to Ecm mode 4239 if (!isInEcm()) { 4240 setIsInEcm(true); 4241 4242 // notify change 4243 sendEmergencyCallbackModeChange(); 4244 4245 // Post this runnable so we will automatically exit 4246 // if no one invokes exitEmergencyCallbackMode() directly. 4247 long delayInMillis = TelephonyProperties.ecm_exit_timer() 4248 .orElse(DEFAULT_ECM_EXIT_TIMER_VALUE); 4249 postDelayed(mExitEcmRunnable, delayInMillis); 4250 // We don't want to go to sleep while in Ecm 4251 mWakeLock.acquire(); 4252 } 4253 } 4254 4255 //CDMA handleExitEmergencyCallbackMode(Message msg)4256 private void handleExitEmergencyCallbackMode(Message msg) { 4257 if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { 4258 Rlog.d(LOG_TAG, "DomainSelection enabled: ignore ECBM exit event."); 4259 return; 4260 } 4261 AsyncResult ar = (AsyncResult)msg.obj; 4262 if (DBG) { 4263 Rlog.d(LOG_TAG, "handleExitEmergencyCallbackMode,ar.exception , isInEcm=" 4264 + ar.exception + isInEcm()); 4265 } 4266 // Remove pending exit Ecm runnable, if any 4267 removeCallbacks(mExitEcmRunnable); 4268 4269 if (mEcmExitRespRegistrant != null) { 4270 mEcmExitRespRegistrant.notifyRegistrant(ar); 4271 } 4272 // if exiting is successful or we are testing and the modem responded with an error upon 4273 // exit, which may occur in some IRadio implementations. 4274 if (ar.exception == null || mIsTestingEmergencyCallbackMode) { 4275 if (isInEcm()) { 4276 setIsInEcm(false); 4277 } 4278 4279 // release wakeLock 4280 if (mWakeLock.isHeld()) { 4281 mWakeLock.release(); 4282 } 4283 4284 // send an Intent 4285 sendEmergencyCallbackModeChange(); 4286 notifyEmergencyCallRegistrants(false); 4287 } 4288 mIsTestingEmergencyCallbackMode = false; 4289 } 4290 4291 //CDMA notifyEmergencyCallRegistrants(boolean started)4292 public void notifyEmergencyCallRegistrants(boolean started) { 4293 mEmergencyCallToggledRegistrants.notifyResult(started ? 1 : 0); 4294 } 4295 4296 //CDMA 4297 /** 4298 * Handle to cancel or restart Ecm timer in emergency call back mode 4299 * if action is CANCEL_ECM_TIMER, cancel Ecm timer and notify apps the timer is canceled; 4300 * otherwise, restart Ecm timer and notify apps the timer is restarted. 4301 */ handleTimerInEmergencyCallbackMode(int action)4302 public void handleTimerInEmergencyCallbackMode(int action) { 4303 if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) return; 4304 switch(action) { 4305 case CANCEL_ECM_TIMER: 4306 removeCallbacks(mExitEcmRunnable); 4307 mEcmTimerResetRegistrants.notifyResult(Boolean.TRUE); 4308 setEcmCanceledForEmergency(true /*isCanceled*/); 4309 break; 4310 case RESTART_ECM_TIMER: 4311 long delayInMillis = TelephonyProperties.ecm_exit_timer() 4312 .orElse(DEFAULT_ECM_EXIT_TIMER_VALUE); 4313 postDelayed(mExitEcmRunnable, delayInMillis); 4314 mEcmTimerResetRegistrants.notifyResult(Boolean.FALSE); 4315 setEcmCanceledForEmergency(false /*isCanceled*/); 4316 break; 4317 default: 4318 Rlog.e(LOG_TAG, "handleTimerInEmergencyCallbackMode, unsupported action " + action); 4319 } 4320 } 4321 4322 //CDMA 4323 private static final String IS683A_FEATURE_CODE = "*228"; 4324 private static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4; 4325 private static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2; 4326 private static final int IS683A_SYS_SEL_CODE_OFFSET = 4; 4327 4328 private static final int IS683_CONST_800MHZ_A_BAND = 0; 4329 private static final int IS683_CONST_800MHZ_B_BAND = 1; 4330 private static final int IS683_CONST_1900MHZ_A_BLOCK = 2; 4331 private static final int IS683_CONST_1900MHZ_B_BLOCK = 3; 4332 private static final int IS683_CONST_1900MHZ_C_BLOCK = 4; 4333 private static final int IS683_CONST_1900MHZ_D_BLOCK = 5; 4334 private static final int IS683_CONST_1900MHZ_E_BLOCK = 6; 4335 private static final int IS683_CONST_1900MHZ_F_BLOCK = 7; 4336 private static final int INVALID_SYSTEM_SELECTION_CODE = -1; 4337 4338 // Define the pattern/format for carrier specified OTASP number schema. 4339 // It separates by comma and/or whitespace. 4340 private static Pattern pOtaSpNumSchema = Pattern.compile("[,\\s]+"); 4341 4342 //CDMA isIs683OtaSpDialStr(String dialStr)4343 private static boolean isIs683OtaSpDialStr(String dialStr) { 4344 int sysSelCodeInt; 4345 boolean isOtaspDialString = false; 4346 int dialStrLen = dialStr.length(); 4347 4348 if (dialStrLen == IS683A_FEATURE_CODE_NUM_DIGITS) { 4349 if (dialStr.equals(IS683A_FEATURE_CODE)) { 4350 isOtaspDialString = true; 4351 } 4352 } else { 4353 sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr); 4354 switch (sysSelCodeInt) { 4355 case IS683_CONST_800MHZ_A_BAND: 4356 case IS683_CONST_800MHZ_B_BAND: 4357 case IS683_CONST_1900MHZ_A_BLOCK: 4358 case IS683_CONST_1900MHZ_B_BLOCK: 4359 case IS683_CONST_1900MHZ_C_BLOCK: 4360 case IS683_CONST_1900MHZ_D_BLOCK: 4361 case IS683_CONST_1900MHZ_E_BLOCK: 4362 case IS683_CONST_1900MHZ_F_BLOCK: 4363 isOtaspDialString = true; 4364 break; 4365 default: 4366 break; 4367 } 4368 } 4369 return isOtaspDialString; 4370 } 4371 4372 //CDMA 4373 /** 4374 * This function extracts the system selection code from the dial string. 4375 */ extractSelCodeFromOtaSpNum(String dialStr)4376 private static int extractSelCodeFromOtaSpNum(String dialStr) { 4377 int dialStrLen = dialStr.length(); 4378 int sysSelCodeInt = INVALID_SYSTEM_SELECTION_CODE; 4379 4380 if ((dialStr.regionMatches(0, IS683A_FEATURE_CODE, 4381 0, IS683A_FEATURE_CODE_NUM_DIGITS)) && 4382 (dialStrLen >= (IS683A_FEATURE_CODE_NUM_DIGITS + 4383 IS683A_SYS_SEL_CODE_NUM_DIGITS))) { 4384 // Since we checked the condition above, the system selection code 4385 // extracted from dialStr will not cause any exception 4386 sysSelCodeInt = Integer.parseInt ( 4387 dialStr.substring (IS683A_FEATURE_CODE_NUM_DIGITS, 4388 IS683A_FEATURE_CODE_NUM_DIGITS + IS683A_SYS_SEL_CODE_NUM_DIGITS)); 4389 } 4390 if (DBG) Rlog.d(LOG_TAG, "extractSelCodeFromOtaSpNum " + sysSelCodeInt); 4391 return sysSelCodeInt; 4392 } 4393 4394 //CDMA 4395 /** 4396 * This function checks if the system selection code extracted from 4397 * the dial string "sysSelCodeInt' is the system selection code specified 4398 * in the carrier ota sp number schema "sch". 4399 */ checkOtaSpNumBasedOnSysSelCode(int sysSelCodeInt, String sch[])4400 private static boolean checkOtaSpNumBasedOnSysSelCode(int sysSelCodeInt, String sch[]) { 4401 boolean isOtaSpNum = false; 4402 try { 4403 // Get how many number of system selection code ranges 4404 int selRc = Integer.parseInt(sch[1]); 4405 for (int i = 0; i < selRc; i++) { 4406 if (!TextUtils.isEmpty(sch[i*2+2]) && !TextUtils.isEmpty(sch[i*2+3])) { 4407 int selMin = Integer.parseInt(sch[i*2+2]); 4408 int selMax = Integer.parseInt(sch[i*2+3]); 4409 // Check if the selection code extracted from the dial string falls 4410 // within any of the range pairs specified in the schema. 4411 if ((sysSelCodeInt >= selMin) && (sysSelCodeInt <= selMax)) { 4412 isOtaSpNum = true; 4413 break; 4414 } 4415 } 4416 } 4417 } catch (NumberFormatException ex) { 4418 // If the carrier ota sp number schema is not correct, we still allow dial 4419 // and only log the error: 4420 Rlog.e(LOG_TAG, "checkOtaSpNumBasedOnSysSelCode, error", ex); 4421 } 4422 return isOtaSpNum; 4423 } 4424 4425 //CDMA 4426 /** 4427 * The following function checks if a dial string is a carrier specified 4428 * OTASP number or not by checking against the OTASP number schema stored 4429 * in PROPERTY_OTASP_NUM_SCHEMA. 4430 * 4431 * Currently, there are 2 schemas for carriers to specify the OTASP number: 4432 * 1) Use system selection code: 4433 * The schema is: 4434 * SELC,the # of code pairs,min1,max1,min2,max2,... 4435 * e.g "SELC,3,10,20,30,40,60,70" indicates that there are 3 pairs of 4436 * selection codes, and they are {10,20}, {30,40} and {60,70} respectively. 4437 * 4438 * 2) Use feature code: 4439 * The schema is: 4440 * "FC,length of feature code,feature code". 4441 * e.g "FC,2,*2" indicates that the length of the feature code is 2, 4442 * and the code itself is "*2". 4443 */ isCarrierOtaSpNum(String dialStr)4444 private boolean isCarrierOtaSpNum(String dialStr) { 4445 boolean isOtaSpNum = false; 4446 int sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr); 4447 if (sysSelCodeInt == INVALID_SYSTEM_SELECTION_CODE) { 4448 return isOtaSpNum; 4449 } 4450 // mCarrierOtaSpNumSchema is retrieved from PROPERTY_OTASP_NUM_SCHEMA: 4451 if (!TextUtils.isEmpty(mCarrierOtaSpNumSchema)) { 4452 Matcher m = pOtaSpNumSchema.matcher(mCarrierOtaSpNumSchema); 4453 if (DBG) { 4454 Rlog.d(LOG_TAG, "isCarrierOtaSpNum,schema" + mCarrierOtaSpNumSchema); 4455 } 4456 4457 if (m.find()) { 4458 String sch[] = pOtaSpNumSchema.split(mCarrierOtaSpNumSchema); 4459 // If carrier uses system selection code mechanism 4460 if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("SELC")) { 4461 if (sysSelCodeInt!=INVALID_SYSTEM_SELECTION_CODE) { 4462 isOtaSpNum=checkOtaSpNumBasedOnSysSelCode(sysSelCodeInt,sch); 4463 } else { 4464 if (DBG) { 4465 Rlog.d(LOG_TAG, "isCarrierOtaSpNum,sysSelCodeInt is invalid"); 4466 } 4467 } 4468 } else if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("FC")) { 4469 int fcLen = Integer.parseInt(sch[1]); 4470 String fc = sch[2]; 4471 if (dialStr.regionMatches(0,fc,0,fcLen)) { 4472 isOtaSpNum = true; 4473 } else { 4474 if (DBG) Rlog.d(LOG_TAG, "isCarrierOtaSpNum,not otasp number"); 4475 } 4476 } else { 4477 if (DBG) { 4478 Rlog.d(LOG_TAG, "isCarrierOtaSpNum,ota schema not supported" + sch[0]); 4479 } 4480 } 4481 } else { 4482 if (DBG) { 4483 Rlog.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern not right" + 4484 mCarrierOtaSpNumSchema); 4485 } 4486 } 4487 } else { 4488 if (DBG) Rlog.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern empty"); 4489 } 4490 return isOtaSpNum; 4491 } 4492 4493 /** 4494 * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier 4495 * OTASP dial string. 4496 * 4497 * @param dialStr the number to look up. 4498 * @return true if the number is in IS-683A OTASP dial string or carrier OTASP dial string 4499 */ 4500 @Override isOtaSpNumber(String dialStr)4501 public boolean isOtaSpNumber(String dialStr) { 4502 if (isPhoneTypeGsm()) { 4503 return super.isOtaSpNumber(dialStr); 4504 } else { 4505 boolean isOtaSpNum = false; 4506 String dialableStr = PhoneNumberUtils.extractNetworkPortionAlt(dialStr); 4507 if (dialableStr != null) { 4508 isOtaSpNum = isIs683OtaSpDialStr(dialableStr); 4509 if (isOtaSpNum == false) { 4510 isOtaSpNum = isCarrierOtaSpNum(dialableStr); 4511 } 4512 } 4513 if (DBG) Rlog.d(LOG_TAG, "isOtaSpNumber " + isOtaSpNum); 4514 return isOtaSpNum; 4515 } 4516 } 4517 4518 @Override getOtasp()4519 public int getOtasp() { 4520 return mSST.getOtasp(); 4521 } 4522 4523 @Override getCdmaEriIconIndex()4524 public int getCdmaEriIconIndex() { 4525 if (isPhoneTypeGsm()) { 4526 return super.getCdmaEriIconIndex(); 4527 } else { 4528 return getServiceState().getCdmaEriIconIndex(); 4529 } 4530 } 4531 4532 /** 4533 * Returns the CDMA ERI icon mode, 4534 * 0 - ON 4535 * 1 - FLASHING 4536 */ 4537 @Override getCdmaEriIconMode()4538 public int getCdmaEriIconMode() { 4539 if (isPhoneTypeGsm()) { 4540 return super.getCdmaEriIconMode(); 4541 } else { 4542 return getServiceState().getCdmaEriIconMode(); 4543 } 4544 } 4545 4546 /** 4547 * Returns the CDMA ERI text, 4548 */ 4549 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 4550 @Override getCdmaEriText()4551 public String getCdmaEriText() { 4552 if (isPhoneTypeGsm()) { 4553 return super.getCdmaEriText(); 4554 } else { 4555 int roamInd = getServiceState().getCdmaRoamingIndicator(); 4556 int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator(); 4557 return mSST.getCdmaEriText(roamInd, defRoamInd); 4558 } 4559 } 4560 4561 // Return true if either CSIM or RUIM app is present 4562 @Override isCdmaSubscriptionAppPresent()4563 public boolean isCdmaSubscriptionAppPresent() { 4564 UiccCardApplication cdmaApplication = 4565 mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_3GPP2); 4566 return cdmaApplication != null && (cdmaApplication.getType() == AppType.APPTYPE_CSIM || 4567 cdmaApplication.getType() == AppType.APPTYPE_RUIM); 4568 } 4569 phoneObjectUpdater(int newVoiceRadioTech)4570 protected void phoneObjectUpdater(int newVoiceRadioTech) { 4571 logd("phoneObjectUpdater: newVoiceRadioTech=" + newVoiceRadioTech); 4572 if (mFeatureFlags.phoneTypeCleanup()) { 4573 logd("phoneObjectUpdater: no-op as CDMA cleanup flag is set"); 4574 return; 4575 } 4576 4577 // Check for a voice over LTE/NR replacement 4578 if (ServiceState.isPsOnlyTech(newVoiceRadioTech) 4579 || (newVoiceRadioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN)) { 4580 CarrierConfigManager configMgr = (CarrierConfigManager) 4581 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 4582 PersistableBundle b = configMgr.getConfigForSubId(getSubId()); 4583 if (b != null) { 4584 int volteReplacementRat = 4585 b.getInt(CarrierConfigManager.KEY_VOLTE_REPLACEMENT_RAT_INT); 4586 logd("phoneObjectUpdater: volteReplacementRat=" + volteReplacementRat); 4587 if (volteReplacementRat != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN && 4588 //In cdma case, replace rat only if csim or ruim app present 4589 (ServiceState.isGsm(volteReplacementRat) || 4590 isCdmaSubscriptionAppPresent())) { 4591 newVoiceRadioTech = volteReplacementRat; 4592 } 4593 } else { 4594 loge("phoneObjectUpdater: didn't get volteReplacementRat from carrier config"); 4595 } 4596 } 4597 4598 if(mRilVersion == 6 && getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE) { 4599 /* 4600 * On v6 RIL, when LTE_ON_CDMA is TRUE, always create CDMALTEPhone 4601 * irrespective of the voice radio tech reported. 4602 */ 4603 if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 4604 logd("phoneObjectUpdater: LTE ON CDMA property is set. Use CDMA Phone" + 4605 " newVoiceRadioTech=" + newVoiceRadioTech + 4606 " mActivePhone=" + getPhoneName()); 4607 return; 4608 } else { 4609 logd("phoneObjectUpdater: LTE ON CDMA property is set. Switch to CDMALTEPhone" + 4610 " newVoiceRadioTech=" + newVoiceRadioTech + 4611 " mActivePhone=" + getPhoneName()); 4612 newVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT; 4613 } 4614 } else { 4615 4616 // If the device is shutting down, then there is no need to switch to the new phone 4617 // which might send unnecessary attach request to the modem. 4618 if (isShuttingDown()) { 4619 logd("Device is shutting down. No need to switch phone now."); 4620 return; 4621 } 4622 4623 boolean matchCdma = ServiceState.isCdma(newVoiceRadioTech); 4624 boolean matchGsm = ServiceState.isGsm(newVoiceRadioTech); 4625 if ((matchCdma && getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) || 4626 (matchGsm && getPhoneType() == PhoneConstants.PHONE_TYPE_GSM)) { 4627 // Nothing changed. Keep phone as it is. 4628 logd("phoneObjectUpdater: No change ignore," + 4629 " newVoiceRadioTech=" + newVoiceRadioTech + 4630 " mActivePhone=" + getPhoneName()); 4631 return; 4632 } 4633 if (!matchCdma && !matchGsm) { 4634 loge("phoneObjectUpdater: newVoiceRadioTech=" + newVoiceRadioTech + 4635 " doesn't match either CDMA or GSM - error! No phone change"); 4636 return; 4637 } 4638 } 4639 4640 if (newVoiceRadioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) { 4641 // We need some voice phone object to be active always, so never 4642 // delete the phone without anything to replace it with! 4643 logd("phoneObjectUpdater: Unknown rat ignore, " 4644 + " newVoiceRadioTech=Unknown. mActivePhone=" + getPhoneName()); 4645 return; 4646 } 4647 4648 boolean oldPowerState = false; // old power state to off 4649 if (mResetModemOnRadioTechnologyChange) { 4650 if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) { 4651 oldPowerState = true; 4652 logd("phoneObjectUpdater: Setting Radio Power to Off"); 4653 mCi.setRadioPower(false, null); 4654 } 4655 } 4656 4657 switchVoiceRadioTech(newVoiceRadioTech); 4658 4659 if (mResetModemOnRadioTechnologyChange && oldPowerState) { // restore power state 4660 logd("phoneObjectUpdater: Resetting Radio"); 4661 mCi.setRadioPower(oldPowerState, null); 4662 } 4663 4664 // update voice radio tech in UiccProfile 4665 UiccProfile uiccProfile = getUiccProfile(); 4666 if (uiccProfile != null) { 4667 uiccProfile.setVoiceRadioTech(newVoiceRadioTech); 4668 } 4669 4670 // Send an Intent to the PhoneApp that we had a radio technology change 4671 Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); 4672 intent.putExtra(PhoneConstants.PHONE_NAME_KEY, getPhoneName()); 4673 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhoneId); 4674 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 4675 } 4676 switchVoiceRadioTech(int newVoiceRadioTech)4677 private void switchVoiceRadioTech(int newVoiceRadioTech) { 4678 4679 String outgoingPhoneName = getPhoneName(); 4680 4681 logd("Switching Voice Phone : " + outgoingPhoneName + " >>> " 4682 + (ServiceState.isGsm(newVoiceRadioTech) ? "GSM" : "CDMA")); 4683 4684 if (ServiceState.isCdma(newVoiceRadioTech)) { 4685 UiccCardApplication cdmaApplication = 4686 mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_3GPP2); 4687 if (cdmaApplication != null && cdmaApplication.getType() == AppType.APPTYPE_RUIM) { 4688 switchPhoneType(PhoneConstants.PHONE_TYPE_CDMA); 4689 } else { 4690 switchPhoneType(PhoneConstants.PHONE_TYPE_CDMA_LTE); 4691 } 4692 } else if (ServiceState.isGsm(newVoiceRadioTech)) { 4693 switchPhoneType(PhoneConstants.PHONE_TYPE_GSM); 4694 } else { 4695 loge("deleteAndCreatePhone: newVoiceRadioTech=" + newVoiceRadioTech + 4696 " is not CDMA or GSM (error) - aborting!"); 4697 } 4698 } 4699 4700 @Override setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran)4701 public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) { 4702 mCi.setLinkCapacityReportingCriteria(REPORTING_HYSTERESIS_MILLIS, REPORTING_HYSTERESIS_KBPS, 4703 REPORTING_HYSTERESIS_KBPS, dlThresholds, ulThresholds, ran, null); 4704 } 4705 4706 @Override getIccSmsInterfaceManager()4707 public IccSmsInterfaceManager getIccSmsInterfaceManager(){ 4708 return mIccSmsInterfaceManager; 4709 } 4710 4711 @Override updatePhoneObject(int voiceRadioTech)4712 public void updatePhoneObject(int voiceRadioTech) { 4713 logd("updatePhoneObject: radioTechnology=" + voiceRadioTech); 4714 sendMessage(obtainMessage(EVENT_UPDATE_PHONE_OBJECT, voiceRadioTech, 0, null)); 4715 } 4716 4717 @Override setImsRegistrationState(boolean registered)4718 public void setImsRegistrationState(boolean registered) { 4719 mSST.setImsRegistrationState(registered); 4720 mCallWaitingController.setImsRegistrationState(registered); 4721 } 4722 4723 @Override getIccRecordsLoaded()4724 public boolean getIccRecordsLoaded() { 4725 UiccProfile uiccProfile = getUiccProfile(); 4726 return uiccProfile != null && uiccProfile.getIccRecordsLoaded(); 4727 } 4728 4729 @Override getIccCard()4730 public IccCard getIccCard() { 4731 // This function doesn't return null for backwards compatability purposes. 4732 // To differentiate between cases where SIM is absent vs. unknown we return a placeholder 4733 // IccCard with the sim state set. 4734 IccCard card = getUiccProfile(); 4735 if (card != null) { 4736 return card; 4737 } else { 4738 UiccSlot slot = mUiccController.getUiccSlotForPhone(mPhoneId); 4739 if (slot == null || slot.isStateUnknown()) { 4740 return new IccCard(IccCardConstants.State.UNKNOWN); 4741 } else { 4742 return new IccCard(IccCardConstants.State.ABSENT); 4743 } 4744 } 4745 } 4746 getUiccProfile()4747 private UiccProfile getUiccProfile() { 4748 return UiccController.getInstance().getUiccProfileForPhone(mPhoneId); 4749 } 4750 4751 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)4752 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4753 pw.println("GsmCdmaPhone extends:"); 4754 super.dump(fd, pw, args); 4755 pw.println(" mPrecisePhoneType=" + mPrecisePhoneType); 4756 pw.println(" mCT=" + mCT); 4757 pw.println(" mSST=" + mSST); 4758 pw.println(" mPendingMMIs=" + mPendingMMIs); 4759 pw.println(" mIccPhoneBookIntManager=" + mIccPhoneBookIntManager); 4760 pw.println(" mImei=" + pii(mImei)); 4761 pw.println(" mImeiSv=" + pii(mImeiSv)); 4762 pw.println(" mVmNumber=" + pii(mVmNumber)); 4763 pw.println(" mCdmaSSM=" + mCdmaSSM); 4764 pw.println(" mCdmaSubscriptionSource=" + mCdmaSubscriptionSource); 4765 pw.println(" mWakeLock=" + mWakeLock); 4766 pw.println(" isInEcm()=" + isInEcm()); 4767 pw.println(" mEsn=" + pii(mEsn)); 4768 pw.println(" mMeid=" + pii(mMeid)); 4769 pw.println(" mCarrierOtaSpNumSchema=" + mCarrierOtaSpNumSchema); 4770 if (!isPhoneTypeGsm()) { 4771 pw.println(" getCdmaEriIconIndex()=" + getCdmaEriIconIndex()); 4772 pw.println(" getCdmaEriIconMode()=" + getCdmaEriIconMode()); 4773 pw.println(" getCdmaEriText()=" + getCdmaEriText()); 4774 pw.println(" isMinInfoReady()=" + isMinInfoReady()); 4775 } 4776 pw.println(" isCspPlmnEnabled()=" + isCspPlmnEnabled()); 4777 pw.println(" mManualNetworkSelectionPlmn=" + mManualNetworkSelectionPlmn); 4778 pw.println( 4779 " mTelecomVoiceServiceStateOverride=" + mTelecomVoiceServiceStateOverride + "(" 4780 + ServiceState.rilServiceStateToString(mTelecomVoiceServiceStateOverride) 4781 + ")"); 4782 pw.println(" mUiccApplicationsEnabled=" + mUiccApplicationsEnabled); 4783 pw.flush(); 4784 try { 4785 mCallWaitingController.dump(pw); 4786 } catch (Exception e) { 4787 e.printStackTrace(); 4788 } 4789 pw.flush(); 4790 try { 4791 mCellBroadcastConfigTracker.dump(fd, pw, args); 4792 } catch (Exception e) { 4793 e.printStackTrace(); 4794 } 4795 pw.flush(); 4796 } 4797 4798 @Override setOperatorBrandOverride(String brand)4799 public boolean setOperatorBrandOverride(String brand) { 4800 if (mUiccController == null) { 4801 return false; 4802 } 4803 4804 UiccPort port = mUiccController.getUiccPort(getPhoneId()); 4805 if (port == null) { 4806 return false; 4807 } 4808 4809 boolean status = port.setOperatorBrandOverride(brand); 4810 4811 // Refresh. 4812 if (status) { 4813 TelephonyManager.from(mContext).setSimOperatorNameForPhone( 4814 getPhoneId(), mSST.getServiceProviderName()); 4815 // TODO: check if pollState is need when set operator brand override. 4816 mSST.pollState(); 4817 } 4818 return status; 4819 } 4820 4821 /** 4822 * This allows a short number to be remapped to a test emergency number for testing how the 4823 * frameworks handles Emergency Callback Mode without actually calling an emergency number. 4824 * 4825 * This is not a full test and is not a substitute for testing real emergency 4826 * numbers but can be useful. 4827 * 4828 * To use this feature, first set a test emergency number using 4829 * adb shell cmd phone emergency-number-test-mode -a 1-555-555-1212 4830 * 4831 * and then set the system property ril.test.emergencynumber to a pair of 4832 * numbers separated by a colon. If the first number matches the number parameter 4833 * this routine returns the second number. Example: 4834 * 4835 * ril.test.emergencynumber=411:1-555-555-1212 4836 * 4837 * To test Dial 411 take call then hang up on MO device to enter ECM. 4838 * 4839 * @param dialString to test if it should be remapped 4840 * @return the same number or the remapped number. 4841 */ checkForTestEmergencyNumber(String dialString)4842 private String checkForTestEmergencyNumber(String dialString) { 4843 String testEn = SystemProperties.get("ril.test.emergencynumber"); 4844 if (!TextUtils.isEmpty(testEn)) { 4845 String[] values = testEn.split(":"); 4846 logd("checkForTestEmergencyNumber: values.length=" + values.length); 4847 if (values.length == 2) { 4848 if (values[0].equals(PhoneNumberUtils.stripSeparators(dialString))) { 4849 logd("checkForTestEmergencyNumber: remap " + dialString + " to " + values[1]); 4850 dialString = values[1]; 4851 } 4852 } 4853 } 4854 return dialString; 4855 } 4856 4857 @Override 4858 @NonNull getOperatorNumeric()4859 public String getOperatorNumeric() { 4860 String operatorNumeric = null; 4861 if (isPhoneTypeGsm()) { 4862 IccRecords r = mIccRecords.get(); 4863 if (r != null) { 4864 operatorNumeric = r.getOperatorNumeric(); 4865 } 4866 } else { //isPhoneTypeCdmaLte() 4867 IccRecords curIccRecords = null; 4868 if (mCdmaSubscriptionSource == CDMA_SUBSCRIPTION_NV) { 4869 operatorNumeric = SystemProperties.get("ro.cdma.home.operator.numeric"); 4870 } else if (mCdmaSubscriptionSource == CDMA_SUBSCRIPTION_RUIM_SIM) { 4871 UiccCardApplication uiccCardApplication = mUiccApplication.get(); 4872 if (uiccCardApplication != null 4873 && uiccCardApplication.getType() == AppType.APPTYPE_RUIM) { 4874 logd("Legacy RUIM app present"); 4875 curIccRecords = mIccRecords.get(); 4876 } else { 4877 // Use sim-records for SimApp, USimApp, CSimApp and ISimApp. 4878 curIccRecords = mSimRecords; 4879 } 4880 if (curIccRecords != null && curIccRecords == mSimRecords) { 4881 operatorNumeric = curIccRecords.getOperatorNumeric(); 4882 } else { 4883 curIccRecords = mIccRecords.get(); 4884 if (curIccRecords != null && (curIccRecords instanceof RuimRecords)) { 4885 RuimRecords csim = (RuimRecords) curIccRecords; 4886 operatorNumeric = csim.getRUIMOperatorNumeric(); 4887 } 4888 } 4889 } 4890 if (operatorNumeric == null) { 4891 loge("getOperatorNumeric: Cannot retrieve operatorNumeric:" 4892 + " mCdmaSubscriptionSource = " + mCdmaSubscriptionSource + 4893 " mIccRecords = " + ((curIccRecords != null) ? 4894 curIccRecords.getRecordsLoaded() : null)); 4895 } 4896 4897 logd("getOperatorNumeric: mCdmaSubscriptionSource = " + mCdmaSubscriptionSource 4898 + " operatorNumeric = " + operatorNumeric); 4899 4900 } 4901 return TextUtils.emptyIfNull(operatorNumeric); 4902 } 4903 4904 /** 4905 * @return The country ISO for the subscription associated with this phone. 4906 */ getCountryIso()4907 public String getCountryIso() { 4908 int subId = getSubId(); 4909 SubscriptionInfo subInfo = SubscriptionManager.from(getContext()) 4910 .getActiveSubscriptionInfo(subId); 4911 if (subInfo == null || TextUtils.isEmpty(subInfo.getCountryIso())) { 4912 return null; 4913 } 4914 return subInfo.getCountryIso().toUpperCase(Locale.ROOT); 4915 } 4916 notifyEcbmTimerReset(Boolean flag)4917 public void notifyEcbmTimerReset(Boolean flag) { 4918 mEcmTimerResetRegistrants.notifyResult(flag); 4919 } 4920 4921 private static final int[] VOICE_PS_CALL_RADIO_TECHNOLOGY = { 4922 ServiceState.RIL_RADIO_TECHNOLOGY_LTE, 4923 ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA, 4924 ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, 4925 ServiceState.RIL_RADIO_TECHNOLOGY_NR 4926 }; 4927 4928 /** 4929 * Calculates current RIL voice radio technology for CS calls. 4930 * 4931 * This function should only be used in {@link com.android.internal.telephony.GsmCdmaConnection} 4932 * to indicate current CS call radio technology. 4933 * 4934 * @return the RIL voice radio technology used for CS calls, 4935 * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. 4936 */ getCsCallRadioTech()4937 public @RilRadioTechnology int getCsCallRadioTech() { 4938 int calcVrat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; 4939 if (mSST != null) { 4940 calcVrat = getCsCallRadioTech(mSST.mSS.getState(), 4941 mSST.mSS.getRilVoiceRadioTechnology()); 4942 } 4943 4944 return calcVrat; 4945 } 4946 4947 /** 4948 * Calculates current RIL voice radio technology for CS calls based on current voice 4949 * registration state and technology. 4950 * 4951 * Mark current RIL voice radio technology as unknow when any of below condtion is met: 4952 * 1) Current RIL voice registration state is not in-service. 4953 * 2) Current RIL voice radio technology is PS call technology, which means CSFB will 4954 * happen later after call connection is established. 4955 * It is inappropriate to notify upper layer the PS call technology while current call 4956 * is CS call, so before CSFB happens, mark voice radio technology as unknow. 4957 * After CSFB happens, {@link #onVoiceRegStateOrRatChanged} will update voice call radio 4958 * technology with correct value. 4959 * 4960 * @param vrs the voice registration state 4961 * @param vrat the RIL voice radio technology 4962 * 4963 * @return the RIL voice radio technology used for CS calls, 4964 * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. 4965 */ getCsCallRadioTech(int vrs, int vrat)4966 private @RilRadioTechnology int getCsCallRadioTech(int vrs, int vrat) { 4967 logd("getCsCallRadioTech, current vrs=" + vrs + ", vrat=" + vrat); 4968 int calcVrat = vrat; 4969 if (vrs != ServiceState.STATE_IN_SERVICE 4970 || ArrayUtils.contains(VOICE_PS_CALL_RADIO_TECHNOLOGY, vrat)) { 4971 calcVrat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; 4972 } 4973 4974 logd("getCsCallRadioTech, result calcVrat=" + calcVrat); 4975 return calcVrat; 4976 } 4977 4978 /** 4979 * Handler of RIL Voice Radio Technology changed event. 4980 */ onVoiceRegStateOrRatChanged(int vrs, int vrat)4981 private void onVoiceRegStateOrRatChanged(int vrs, int vrat) { 4982 if (!hasCalling()) return; 4983 logd("onVoiceRegStateOrRatChanged"); 4984 mCT.dispatchCsCallRadioTech(getCsCallRadioTech(vrs, vrat)); 4985 } 4986 4987 /** 4988 * Registration point for Ecm timer reset 4989 * 4990 * @param h handler to notify 4991 * @param what User-defined message code 4992 * @param obj placed in Message.obj 4993 */ 4994 @Override registerForEcmTimerReset(Handler h, int what, Object obj)4995 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 4996 mEcmTimerResetRegistrants.addUnique(h, what, obj); 4997 } 4998 4999 @Override unregisterForEcmTimerReset(Handler h)5000 public void unregisterForEcmTimerReset(Handler h) { 5001 mEcmTimerResetRegistrants.remove(h); 5002 } 5003 5004 @Override registerForVolteSilentRedial(Handler h, int what, Object obj)5005 public void registerForVolteSilentRedial(Handler h, int what, Object obj) { 5006 mVolteSilentRedialRegistrants.addUnique(h, what, obj); 5007 } 5008 5009 @Override unregisterForVolteSilentRedial(Handler h)5010 public void unregisterForVolteSilentRedial(Handler h) { 5011 mVolteSilentRedialRegistrants.remove(h); 5012 } 5013 notifyVolteSilentRedial(String dialString, int causeCode)5014 public void notifyVolteSilentRedial(String dialString, int causeCode) { 5015 logd("notifyVolteSilentRedial: dialString=" + dialString + " causeCode=" + causeCode); 5016 AsyncResult ar = new AsyncResult(null, 5017 new SilentRedialParam(dialString, causeCode, mDialArgs), null); 5018 mVolteSilentRedialRegistrants.notifyRegistrants(ar); 5019 } 5020 5021 /** {@inheritDoc} */ 5022 @Override registerForEmergencyDomainSelected( @onNull Handler h, int what, @Nullable Object obj)5023 public void registerForEmergencyDomainSelected( 5024 @NonNull Handler h, int what, @Nullable Object obj) { 5025 mEmergencyDomainSelectedRegistrants.addUnique(h, what, obj); 5026 } 5027 5028 /** {@inheritDoc} */ 5029 @Override unregisterForEmergencyDomainSelected(@onNull Handler h)5030 public void unregisterForEmergencyDomainSelected(@NonNull Handler h) { 5031 mEmergencyDomainSelectedRegistrants.remove(h); 5032 } 5033 5034 /** {@inheritDoc} */ 5035 @Override notifyEmergencyDomainSelected(@ransportType int transportType)5036 public void notifyEmergencyDomainSelected(@TransportType int transportType) { 5037 logd("notifyEmergencyDomainSelected transportType=" + transportType); 5038 mEmergencyDomainSelectedRegistrants.notifyRegistrants( 5039 new AsyncResult(null, transportType, null)); 5040 } 5041 5042 /** 5043 * Sets the SIM voice message waiting indicator records. 5044 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 5045 * @param countWaiting The number of messages waiting, if known. Use 5046 * -1 to indicate that an unknown number of 5047 * messages are waiting 5048 */ 5049 @Override setVoiceMessageWaiting(int line, int countWaiting)5050 public void setVoiceMessageWaiting(int line, int countWaiting) { 5051 if (isPhoneTypeGsm()) { 5052 IccRecords r = mIccRecords.get(); 5053 if (r != null) { 5054 r.setVoiceMessageWaiting(line, countWaiting); 5055 } else { 5056 logd("SIM Records not found, MWI not updated"); 5057 } 5058 } else { 5059 setVoiceMessageCount(countWaiting); 5060 } 5061 } 5062 makeEmptyCallForward()5063 private CallForwardInfo[] makeEmptyCallForward() { 5064 CallForwardInfo infos[] = new CallForwardInfo[1]; 5065 5066 infos[0] = new CallForwardInfo(); 5067 infos[0].status = CommandsInterface.SS_STATUS_UNKNOWN; 5068 infos[0].reason = 0; 5069 infos[0].serviceClass = CommandsInterface.SERVICE_CLASS_VOICE; 5070 infos[0].toa = PhoneNumberUtils.TOA_Unknown; 5071 infos[0].number = ""; 5072 infos[0].timeSeconds = 0; 5073 5074 return infos; 5075 } 5076 subscriptionIdToPhoneAccountHandle(final int subId)5077 private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) { 5078 final TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class); 5079 final TelephonyManager telephonyManager = TelephonyManager.from(mContext); 5080 final Iterator<PhoneAccountHandle> phoneAccounts = 5081 telecomManager.getCallCapablePhoneAccounts(true).listIterator(); 5082 5083 while (phoneAccounts.hasNext()) { 5084 final PhoneAccountHandle phoneAccountHandle = phoneAccounts.next(); 5085 final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle); 5086 if (subId == telephonyManager.getSubIdForPhoneAccount(phoneAccount)) { 5087 return phoneAccountHandle; 5088 } 5089 } 5090 5091 return null; 5092 } 5093 5094 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) logd(String s)5095 private void logd(String s) { 5096 Rlog.d(LOG_TAG, "[" + mPhoneId + "] " + s); 5097 } 5098 logi(String s)5099 private void logi(String s) { 5100 Rlog.i(LOG_TAG, "[" + mPhoneId + "] " + s); 5101 } 5102 5103 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) loge(String s)5104 private void loge(String s) { 5105 Rlog.e(LOG_TAG, "[" + mPhoneId + "] " + s); 5106 } 5107 pii(String s)5108 private static String pii(String s) { 5109 return Rlog.pii(LOG_TAG, s); 5110 } 5111 5112 @Override isUtEnabled()5113 public boolean isUtEnabled() { 5114 Phone imsPhone = mImsPhone; 5115 if (imsPhone != null) { 5116 return imsPhone.isUtEnabled(); 5117 } else { 5118 logd("isUtEnabled: called for GsmCdma"); 5119 return false; 5120 } 5121 } 5122 getDtmfToneDelayKey()5123 public String getDtmfToneDelayKey() { 5124 return isPhoneTypeGsm() ? 5125 CarrierConfigManager.KEY_GSM_DTMF_TONE_DELAY_INT : 5126 CarrierConfigManager.KEY_CDMA_DTMF_TONE_DELAY_INT; 5127 } 5128 5129 @VisibleForTesting getWakeLock()5130 public PowerManager.WakeLock getWakeLock() { 5131 return mWakeLock; 5132 } 5133 getLteOnCdmaMode()5134 public int getLteOnCdmaMode() { 5135 if (mFeatureFlags.phoneTypeCleanup()) return PhoneConstants.LTE_ON_CDMA_FALSE; 5136 int currentConfig = TelephonyProperties.lte_on_cdma_device() 5137 .orElse(PhoneConstants.LTE_ON_CDMA_FALSE); 5138 int lteOnCdmaModeDynamicValue = currentConfig; 5139 5140 UiccCardApplication cdmaApplication = 5141 mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_3GPP2); 5142 if (cdmaApplication != null && cdmaApplication.getType() == AppType.APPTYPE_RUIM) { 5143 //Legacy RUIM cards don't support LTE. 5144 lteOnCdmaModeDynamicValue = RILConstants.LTE_ON_CDMA_FALSE; 5145 5146 //Override only if static configuration is TRUE. 5147 if (currentConfig == RILConstants.LTE_ON_CDMA_TRUE) { 5148 return lteOnCdmaModeDynamicValue; 5149 } 5150 } 5151 return currentConfig; 5152 } 5153 updateTtyMode(int ttyMode)5154 private void updateTtyMode(int ttyMode) { 5155 logi(String.format("updateTtyMode ttyMode=%d", ttyMode)); 5156 setTTYMode(telecomModeToPhoneMode(ttyMode), null); 5157 } updateUiTtyMode(int ttyMode)5158 private void updateUiTtyMode(int ttyMode) { 5159 logi(String.format("updateUiTtyMode ttyMode=%d", ttyMode)); 5160 setUiTTYMode(telecomModeToPhoneMode(ttyMode), null); 5161 } 5162 5163 /** 5164 * Given a telecom TTY mode, convert to a Telephony mode equivalent. 5165 * @param telecomMode Telecom TTY mode. 5166 * @return Telephony phone TTY mode. 5167 */ telecomModeToPhoneMode(int telecomMode)5168 private static int telecomModeToPhoneMode(int telecomMode) { 5169 switch (telecomMode) { 5170 // AT command only has 0 and 1, so mapping VCO 5171 // and HCO to FULL 5172 case TelecomManager.TTY_MODE_FULL: 5173 case TelecomManager.TTY_MODE_VCO: 5174 case TelecomManager.TTY_MODE_HCO: 5175 return Phone.TTY_MODE_FULL; 5176 default: 5177 return Phone.TTY_MODE_OFF; 5178 } 5179 } 5180 5181 /** 5182 * Load the current TTY mode in GsmCdmaPhone based on Telecom and UI settings. 5183 */ loadTtyMode()5184 private void loadTtyMode() { 5185 if (!hasCalling()) return; 5186 5187 int ttyMode = TelecomManager.TTY_MODE_OFF; 5188 TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class); 5189 if (telecomManager != null) { 5190 ttyMode = telecomManager.getCurrentTtyMode(); 5191 } 5192 updateTtyMode(ttyMode); 5193 //Get preferred TTY mode from settings as UI Tty mode is always user preferred Tty mode. 5194 ttyMode = Settings.Secure.getInt(mContext.getContentResolver(), 5195 Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF); 5196 updateUiTtyMode(ttyMode); 5197 } 5198 reapplyUiccAppsEnablementIfNeeded(int retries)5199 private void reapplyUiccAppsEnablementIfNeeded(int retries) { 5200 UiccSlot slot = mUiccController.getUiccSlotForPhone(mPhoneId); 5201 5202 // If no card is present or we don't have mUiccApplicationsEnabled yet, do nothing. 5203 if (slot == null || slot.getCardState() != IccCardStatus.CardState.CARDSTATE_PRESENT 5204 || mUiccApplicationsEnabled == null) { 5205 loge("reapplyUiccAppsEnablementIfNeeded: slot state=" 5206 + (slot != null ? slot.getCardState() : null)); 5207 return; 5208 } 5209 5210 // Due to timing issue, sometimes UiccPort is coming null, so don't use UiccPort object 5211 // to retrieve the iccId here. Instead, depend on the UiccSlot API. 5212 String iccId = slot.getIccId(slot.getPortIndexFromPhoneId(mPhoneId)); 5213 if (iccId == null) { 5214 loge("reapplyUiccAppsEnablementIfNeeded iccId is null, phoneId: " + mPhoneId 5215 + " portIndex: " + slot.getPortIndexFromPhoneId(mPhoneId)); 5216 return; 5217 } 5218 5219 SubscriptionInfo info = mSubscriptionManagerService 5220 .getAllSubInfoList(mContext.getOpPackageName(), mContext.getAttributionTag()) 5221 .stream() 5222 .filter(subInfo -> subInfo.getIccId().equals(IccUtils.stripTrailingFs(iccId))) 5223 .findFirst() 5224 .orElse(null); 5225 5226 logd("reapplyUiccAppsEnablementIfNeeded: retries=" + retries + ", subInfo=" + info); 5227 5228 // If info is null, it could be a new subscription. By default we enable it. 5229 boolean expectedValue = info == null || info.areUiccApplicationsEnabled(); 5230 5231 // If for any reason current state is different from configured state, re-apply the 5232 // configured state. 5233 if (expectedValue != mUiccApplicationsEnabled) { 5234 mCi.enableUiccApplications(expectedValue, Message.obtain( 5235 this, EVENT_REAPPLY_UICC_APPS_ENABLEMENT_DONE, 5236 new Pair<>(expectedValue, retries))); 5237 } 5238 } 5239 5240 // Enable or disable uicc applications. 5241 @Override enableUiccApplications(boolean enable, Message onCompleteMessage)5242 public void enableUiccApplications(boolean enable, Message onCompleteMessage) { 5243 // First check if card is present. Otherwise mUiccApplicationsDisabled doesn't make 5244 // any sense. 5245 UiccSlot slot = mUiccController.getUiccSlotForPhone(mPhoneId); 5246 if (slot == null || slot.getCardState() != IccCardStatus.CardState.CARDSTATE_PRESENT) { 5247 if (onCompleteMessage != null) { 5248 AsyncResult.forMessage(onCompleteMessage, null, 5249 new IllegalStateException("No SIM card is present")); 5250 onCompleteMessage.sendToTarget(); 5251 } 5252 return; 5253 } 5254 5255 mCi.enableUiccApplications(enable, onCompleteMessage); 5256 } 5257 5258 /** 5259 * Whether disabling a physical subscription is supported or not. 5260 */ 5261 @Override canDisablePhysicalSubscription()5262 public boolean canDisablePhysicalSubscription() { 5263 return mCi.canToggleUiccApplicationsEnablement(); 5264 } 5265 5266 @Override getEquivalentHomePlmns()5267 public @NonNull List<String> getEquivalentHomePlmns() { 5268 if (isPhoneTypeGsm()) { 5269 IccRecords r = mIccRecords.get(); 5270 if (r != null && r.getEhplmns() != null) { 5271 return Arrays.asList(r.getEhplmns()); 5272 } 5273 } else if (isPhoneTypeCdma()) { 5274 loge("EHPLMN is not available in CDMA"); 5275 } 5276 return Collections.emptyList(); 5277 } 5278 5279 /** 5280 * @return Currently bound data service package names. 5281 */ getDataServicePackages()5282 public @NonNull List<String> getDataServicePackages() { 5283 return getDataNetworkController().getDataServicePackages(); 5284 } 5285 updateBroadcastEmergencyCallStateChangesAfterCarrierConfigChanged( @onNull PersistableBundle config)5286 private void updateBroadcastEmergencyCallStateChangesAfterCarrierConfigChanged( 5287 @NonNull PersistableBundle config) { 5288 // get broadcastEmergencyCallStateChanges 5289 boolean broadcastEmergencyCallStateChanges = config.getBoolean( 5290 CarrierConfigManager.KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL); 5291 logd("broadcastEmergencyCallStateChanges = " + broadcastEmergencyCallStateChanges); 5292 setBroadcastEmergencyCallStateChanges(broadcastEmergencyCallStateChanges); 5293 } 5294 updateNrSettingsAfterCarrierConfigChanged(@onNull PersistableBundle config)5295 private void updateNrSettingsAfterCarrierConfigChanged(@NonNull PersistableBundle config) { 5296 int[] nrAvailabilities = config.getIntArray( 5297 CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY); 5298 mIsCarrierNrSupported = !ArrayUtils.isEmpty(nrAvailabilities); 5299 } 5300 updateVoNrSettings(@onNull PersistableBundle config)5301 private void updateVoNrSettings(@NonNull PersistableBundle config) { 5302 if (getIccCard().getState() != IccCardConstants.State.LOADED) { 5303 return; 5304 } 5305 5306 boolean mIsVonrEnabledByCarrier = 5307 config.getBoolean(CarrierConfigManager.KEY_VONR_ENABLED_BOOL); 5308 boolean mDefaultVonr = 5309 config.getBoolean(CarrierConfigManager.KEY_VONR_ON_BY_DEFAULT_BOOL); 5310 5311 int setting = -1; 5312 SubscriptionInfoInternal subInfo = mSubscriptionManagerService 5313 .getSubscriptionInfoInternal(getSubId()); 5314 if (subInfo != null) { 5315 setting = subInfo.getNrAdvancedCallingEnabled(); 5316 } 5317 5318 logd("VoNR setting from telephony.db:" 5319 + setting 5320 + " ,vonr_enabled_bool:" 5321 + mIsVonrEnabledByCarrier 5322 + " ,vonr_on_by_default_bool:" 5323 + mDefaultVonr); 5324 5325 boolean enbleVonr = mIsVonrEnabledByCarrier 5326 && (setting == 1 || (setting == -1 && mDefaultVonr)); 5327 mCi.setVoNrEnabled(enbleVonr, obtainMessage(EVENT_SET_VONR_ENABLED_DONE), null); 5328 } 5329 updateCdmaRoamingSettingsAfterCarrierConfigChanged( @onNull PersistableBundle config)5330 private void updateCdmaRoamingSettingsAfterCarrierConfigChanged( 5331 @NonNull PersistableBundle config) { 5332 // Changing the cdma roaming settings based carrier config. 5333 int config_cdma_roaming_mode = config.getInt( 5334 CarrierConfigManager.KEY_CDMA_ROAMING_MODE_INT); 5335 int current_cdma_roaming_mode = 5336 Settings.Global.getInt(getContext().getContentResolver(), 5337 Settings.Global.CDMA_ROAMING_MODE, 5338 TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT); 5339 switch (config_cdma_roaming_mode) { 5340 // Carrier's cdma_roaming_mode will overwrite the user's previous settings 5341 // Keep the user's previous setting in global variable which will be used 5342 // when carrier's setting is turn off. 5343 case TelephonyManager.CDMA_ROAMING_MODE_HOME: 5344 case TelephonyManager.CDMA_ROAMING_MODE_AFFILIATED: 5345 case TelephonyManager.CDMA_ROAMING_MODE_ANY: 5346 logd("cdma_roaming_mode is going to changed to " 5347 + config_cdma_roaming_mode); 5348 setCdmaRoamingPreference(config_cdma_roaming_mode, 5349 obtainMessage(EVENT_SET_ROAMING_PREFERENCE_DONE)); 5350 break; 5351 5352 // When carrier's setting is turn off, change the cdma_roaming_mode to the 5353 // previous user's setting 5354 case TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT: 5355 if (current_cdma_roaming_mode != config_cdma_roaming_mode) { 5356 logd("cdma_roaming_mode is going to changed to " 5357 + current_cdma_roaming_mode); 5358 setCdmaRoamingPreference(current_cdma_roaming_mode, 5359 obtainMessage(EVENT_SET_ROAMING_PREFERENCE_DONE)); 5360 } 5361 break; 5362 default: 5363 loge("Invalid cdma_roaming_mode settings: " + config_cdma_roaming_mode); 5364 } 5365 } 5366 5367 /** 5368 * Determines if IMS is enabled for call. 5369 * 5370 * @return {@code true} if IMS calling is enabled. 5371 */ isImsUseEnabled()5372 public boolean isImsUseEnabled() { 5373 ImsManager imsManager = mImsManagerFactory.create(mContext, mPhoneId); 5374 boolean imsUseEnabled = ((imsManager.isVolteEnabledByPlatform() 5375 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()) 5376 || (imsManager.isWfcEnabledByPlatform() && imsManager.isWfcEnabledByUser()) 5377 && imsManager.isNonTtyOrTtyOnVolteEnabled()); 5378 return imsUseEnabled; 5379 } 5380 5381 @Override getInboundSmsHandler(boolean is3gpp2)5382 public InboundSmsHandler getInboundSmsHandler(boolean is3gpp2) { 5383 return mIccSmsInterfaceManager.getInboundSmsHandler(is3gpp2); 5384 } 5385 5386 /** 5387 * Return current cell broadcast ranges. 5388 */ getCellBroadcastIdRanges()5389 public List<CellBroadcastIdRange> getCellBroadcastIdRanges() { 5390 return mCellBroadcastConfigTracker.getCellBroadcastIdRanges(); 5391 } 5392 5393 /** 5394 * Set reception of cell broadcast messages with the list of the given ranges. 5395 */ 5396 @Override setCellBroadcastIdRanges( @onNull List<CellBroadcastIdRange> ranges, Consumer<Integer> callback)5397 public void setCellBroadcastIdRanges( 5398 @NonNull List<CellBroadcastIdRange> ranges, Consumer<Integer> callback) { 5399 mCellBroadcastConfigTracker.setCellBroadcastIdRanges(ranges, callback); 5400 } 5401 5402 /** 5403 * The following function checks if supplementary service request is blocked due to FDN. 5404 * @param requestType request type associated with the supplementary service 5405 * @param serviceType supplementary service type 5406 * @return {@code true} if request is blocked due to FDN. 5407 */ isRequestBlockedByFDN(SsData.RequestType requestType, SsData.ServiceType serviceType)5408 private boolean isRequestBlockedByFDN(SsData.RequestType requestType, 5409 SsData.ServiceType serviceType) { 5410 ArrayList<String> controlStrings = GsmMmiCode.getControlStrings(requestType, serviceType); 5411 return FdnUtils.isSuppServiceRequestBlockedByFdn(mPhoneId, controlStrings, getCountryIso()); 5412 } 5413 5414 @Override handleNullCipherEnabledChange()5415 public void handleNullCipherEnabledChange() { 5416 if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CELLULAR_SECURITY, 5417 TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE, true)) { 5418 logi("Not handling null cipher update. Feature disabled by DeviceConfig."); 5419 return; 5420 } 5421 mCi.setNullCipherAndIntegrityEnabled( 5422 getNullCipherAndIntegrityEnabledPreference(), 5423 obtainMessage(EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE)); 5424 } 5425 5426 @Override handleIdentifierDisclosureNotificationPreferenceChange()5427 public void handleIdentifierDisclosureNotificationPreferenceChange() { 5428 boolean prefEnabled = getIdentifierDisclosureNotificationsPreferenceEnabled(); 5429 5430 // The notifier is tied to handling unsolicited updates from the modem, not the 5431 // enable/disable API, so we only toggle the enable state if the unsol events feature 5432 // flag is enabled. 5433 if (prefEnabled) { 5434 mIdentifierDisclosureNotifier.enable(mContext); 5435 } else { 5436 mIdentifierDisclosureNotifier.disable(mContext); 5437 } 5438 5439 mCi.setCellularIdentifierTransparencyEnabled(prefEnabled, 5440 obtainMessage(EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE)); 5441 } 5442 5443 @Override handleNullCipherNotificationPreferenceChanged()5444 public void handleNullCipherNotificationPreferenceChanged() { 5445 boolean prefEnabled = getNullCipherNotificationsPreferenceEnabled(); 5446 5447 // The notifier is tied to handling unsolicited updates from the modem, not the 5448 // enable/disable API. 5449 if (prefEnabled) { 5450 mNullCipherNotifier.enable(mContext); 5451 } else { 5452 mNullCipherNotifier.disable(mContext); 5453 } 5454 5455 mCi.setSecurityAlgorithmsUpdatedEnabled(prefEnabled, 5456 obtainMessage(EVENT_SET_SECURITY_ALGORITHMS_UPDATED_ENABLED_DONE)); 5457 } 5458 5459 /** 5460 * Update the phoneId -> subId mapping of the null cipher notifier. 5461 */ 5462 @VisibleForTesting updateNullCipherNotifier()5463 public void updateNullCipherNotifier() { 5464 SubscriptionInfoInternal subInfo = mSubscriptionManagerService 5465 .getSubscriptionInfoInternal(getSubId()); 5466 boolean active = false; 5467 if (subInfo != null) { 5468 active = subInfo.isActive(); 5469 } 5470 mNullCipherNotifier.setSubscriptionMapping(mContext, getPhoneId(), 5471 active ? subInfo.getSubscriptionId() : -1); 5472 } 5473 5474 @Override isNullCipherAndIntegritySupported()5475 public boolean isNullCipherAndIntegritySupported() { 5476 return mIsNullCipherAndIntegritySupported; 5477 } 5478 5479 @Override isIdentifierDisclosureTransparencySupported()5480 public boolean isIdentifierDisclosureTransparencySupported() { 5481 return mIsIdentifierDisclosureTransparencySupported; 5482 } 5483 5484 @Override isNullCipherNotificationSupported()5485 public boolean isNullCipherNotificationSupported() { 5486 return mIsNullCipherNotificationSupported; 5487 } 5488 5489 @Override refreshSafetySources(String refreshBroadcastId)5490 public void refreshSafetySources(String refreshBroadcastId) { 5491 post(() -> mSafetySource.refresh(mContext, refreshBroadcastId)); 5492 } 5493 5494 /** 5495 * @return The sms dispatchers controller 5496 */ 5497 @Override 5498 @Nullable getSmsDispatchersController()5499 public SmsDispatchersController getSmsDispatchersController() { 5500 return mIccSmsInterfaceManager.mDispatchersController; 5501 } 5502 } 5503