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