aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/android/internal/telephony/uicc
diff options
context:
space:
mode:
authorJack Yu <jackyu@google.com>2023-01-08 18:49:16 -0800
committerJack Yu <jackyu@google.com>2023-03-24 11:27:21 -0700
commit0db34569868aadf62826349c12d498311c5cbd5f (patch)
tree8e527ae9094ec9cb8c08fa1425c3a0d4d04b2de8 /src/java/com/android/internal/telephony/uicc
parent53820ce734f76d85e0fa6f41769a1e09d925527e (diff)
downloadtelephony-0db34569868aadf62826349c12d498311c5cbd5f.tar.gz
Moved SIM state broadcast back to UiccController
Moved the SIM related stuffs back to UiccController. SubscriptionManagerService will mainly handle subscription related stuffs. The same SIM state broadcast is ported from SubscriptionInfoUpdater. This CL is exactly same as the reverted ag/20770404 except 1. Removed the lock in getInstance. The instance is just a reference and should not be updated after created. 2. Seperate the old code with the feature flag with more conservative approach. 3. Update the SIM state with handler. Bug: 239607619 Test: Manual Merged-In: Ifb085003087aa1e270925c755fc6e819f0871dc0 Change-Id: Ifb085003087aa1e270925c755fc6e819f0871dc0
Diffstat (limited to 'src/java/com/android/internal/telephony/uicc')
-rw-r--r--src/java/com/android/internal/telephony/uicc/UiccController.java336
-rw-r--r--src/java/com/android/internal/telephony/uicc/UiccProfile.java9
-rw-r--r--src/java/com/android/internal/telephony/uicc/UiccSlot.java31
3 files changed, 360 insertions, 16 deletions
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 70cfce00b6..94d5d3bef8 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -21,6 +21,8 @@ import static android.telephony.TelephonyManager.UNSUPPORTED_CARD_ID;
import static java.util.Arrays.copyOf;
+import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.BroadcastOptions;
import android.compat.annotation.UnsupportedAppUsage;
@@ -38,8 +40,10 @@ import android.preference.PreferenceManager;
import android.sysprop.TelephonyProperties;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.SimState;
import android.telephony.UiccCardInfo;
import android.telephony.UiccPortInfo;
import android.telephony.UiccSlotMapping;
@@ -49,14 +53,20 @@ import android.util.LocalLog;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.CarrierServiceBindHelper;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.IntentBroadcaster;
import com.android.internal.telephony.PhoneConfigurationManager;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.RadioConfig;
import com.android.internal.telephony.SubscriptionInfoUpdater;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.uicc.euicc.EuiccCard;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.telephony.Rlog;
@@ -140,6 +150,9 @@ public class UiccController extends Handler {
private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 10;
// NOTE: any new EVENT_* values must be added to eventToString.
+ @NonNull
+ private final TelephonyManager mTelephonyManager;
+
// this needs to be here, because on bootup we dont know which index maps to which UiccSlot
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private CommandsInterface[] mCis;
@@ -151,11 +164,25 @@ public class UiccController extends Handler {
// This maps the externally exposed card ID (int) to the internal card ID string (ICCID/EID).
// The array index is the card ID (int).
// This mapping exists to expose card-based functionality without exposing the EID, which is
- // considered sensetive information.
+ // considered sensitive information.
// mCardStrings is populated using values from the IccSlotStatus and IccCardStatus. For
// HAL < 1.2, these do not contain the EID or the ICCID, so mCardStrings will be empty
private ArrayList<String> mCardStrings;
+ /**
+ * SIM card state.
+ */
+ @NonNull
+ @SimState
+ private final int[] mSimCardState;
+
+ /**
+ * SIM application state.
+ */
+ @NonNull
+ @SimState
+ private final int[] mSimApplicationState;
+
// This is the card ID of the default eUICC. It starts as UNINITIALIZED_CARD_ID.
// When we load the EID (either with slot status or from the EuiccCard), we set it to the eUICC
// with the lowest slot index.
@@ -205,6 +232,9 @@ public class UiccController extends Handler {
protected RegistrantList mIccChangedRegistrants = new RegistrantList();
+ @NonNull
+ private final CarrierServiceBindHelper mCarrierServiceBindHelper;
+
private UiccStateChangedLauncher mLauncher;
private RadioConfig mRadioConfig;
@@ -243,8 +273,13 @@ public class UiccController extends Handler {
numPhysicalSlots = mCis.length;
}
+ mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+
mUiccSlots = new UiccSlot[numPhysicalSlots];
mPhoneIdToSlotId = new int[mCis.length];
+ int supportedModemCount = mTelephonyManager.getSupportedModemCount();
+ mSimCardState = new int[supportedModemCount];
+ mSimApplicationState = new int[supportedModemCount];
Arrays.fill(mPhoneIdToSlotId, INVALID_SLOT_ID);
if (VDBG) logPhoneIdToSlotIdMapping();
mRadioConfig = RadioConfig.getInstance();
@@ -260,6 +295,8 @@ public class UiccController extends Handler {
mCardStrings = loadCardStrings();
mDefaultEuiccCardId = UNINITIALIZED_CARD_ID;
+ mCarrierServiceBindHelper = new CarrierServiceBindHelper(mContext);
+
mEuiccSlots = mContext.getResources()
.getIntArray(com.android.internal.R.array.non_removable_euicc_slots);
mHasBuiltInEuicc = hasBuiltInEuicc();
@@ -300,13 +337,11 @@ public class UiccController extends Handler {
@UnsupportedAppUsage
public static UiccController getInstance() {
- synchronized (mLock) {
- if (mInstance == null) {
- throw new RuntimeException(
- "UiccController.getInstance can't be called before make()");
- }
- return mInstance;
+ if (mInstance == null) {
+ throw new RuntimeException(
+ "UiccController.getInstance can't be called before make()");
}
+ return mInstance;
}
@UnsupportedAppUsage
@@ -739,6 +774,293 @@ public class UiccController extends Handler {
}
}
+ /**
+ * Update SIM state for the inactive eSIM port.
+ *
+ * @param phoneId Previously active phone id.
+ * @param iccId ICCID of the SIM.
+ */
+ public void updateSimStateForInactivePort(int phoneId, String iccId) {
+ post(() -> {
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ // Mark SIM state as ABSENT on previously phoneId.
+ mTelephonyManager.setSimStateForPhone(phoneId,
+ IccCardConstants.State.ABSENT.toString());
+ }
+
+ SubscriptionManagerService.getInstance().updateSimStateForInactivePort(phoneId);
+ });
+ }
+
+ /**
+ * Broadcast the legacy SIM state changed event.
+ *
+ * @param phoneId The phone id.
+ * @param state The legacy SIM state.
+ * @param reason The reason of SIM state change.
+ */
+ private void broadcastSimStateChanged(int phoneId, @NonNull String state,
+ @Nullable String reason) {
+ // Note: This intent is way deprecated and is only being kept around because there's no
+ // graceful way to deprecate a sticky broadcast that has a lot of listeners.
+ // DO NOT add any new extras to this broadcast -- it is not protected by any permissions.
+ Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
+ intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, state);
+ intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
+ SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
+ Rlog.d(LOG_TAG, "Broadcasting intent ACTION_SIM_STATE_CHANGED " + state + " reason "
+ + reason + " for phone: " + phoneId);
+ IntentBroadcaster.getInstance().broadcastStickyIntent(mContext, intent, phoneId);
+ }
+
+ /**
+ * Broadcast SIM card state changed event.
+ *
+ * @param phoneId The phone id.
+ * @param state The SIM card state.
+ */
+ private void broadcastSimCardStateChanged(int phoneId, @SimState int state) {
+ if (state != mSimCardState[phoneId]) {
+ mSimCardState[phoneId] = state;
+ Intent intent = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, state);
+ SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
+ // TODO(b/130664115) we manually populate this intent with the slotId. In the future we
+ // should do a review of whether to make this public
+ UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
+ int slotId = UiccController.getInstance().getSlotIdFromPhoneId(phoneId);
+ intent.putExtra(PhoneConstants.SLOT_KEY, slotId);
+ if (slot != null) {
+ intent.putExtra(PhoneConstants.PORT_KEY, slot.getPortIndexFromPhoneId(phoneId));
+ }
+ Rlog.d(LOG_TAG, "Broadcasting intent ACTION_SIM_CARD_STATE_CHANGED "
+ + TelephonyManager.simStateToString(state) + " for phone: " + phoneId
+ + " slot: " + slotId + " port: " + slot.getPortIndexFromPhoneId(phoneId));
+ mContext.sendBroadcast(intent, Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+ TelephonyMetrics.getInstance().updateSimState(phoneId, state);
+ }
+ }
+
+ /**
+ * Broadcast SIM application state changed event.
+ *
+ * @param phoneId The phone id.
+ * @param state The SIM application state.
+ */
+ private void broadcastSimApplicationStateChanged(int phoneId, @SimState int state) {
+ // Broadcast if the state has changed, except if old state was UNKNOWN and new is NOT_READY,
+ // because that's the initial state and a broadcast should be sent only on a transition
+ // after SIM is PRESENT. The only exception is eSIM boot profile, where NOT_READY is the
+ // terminal state.
+ boolean isUnknownToNotReady =
+ (mSimApplicationState[phoneId] == TelephonyManager.SIM_STATE_UNKNOWN
+ && state == TelephonyManager.SIM_STATE_NOT_READY);
+ IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
+ boolean emptyProfile = iccCard != null && iccCard.isEmptyProfile();
+ if (state != mSimApplicationState[phoneId] && (!isUnknownToNotReady || emptyProfile)) {
+ mSimApplicationState[phoneId] = state;
+ Intent intent = new Intent(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, state);
+ SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
+ // TODO(b/130664115) we populate this intent with the actual slotId. In the future we
+ // should do a review of whether to make this public
+ UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
+ int slotId = UiccController.getInstance().getSlotIdFromPhoneId(phoneId);
+ intent.putExtra(PhoneConstants.SLOT_KEY, slotId);
+ if (slot != null) {
+ intent.putExtra(PhoneConstants.PORT_KEY, slot.getPortIndexFromPhoneId(phoneId));
+ }
+ Rlog.d(LOG_TAG, "Broadcasting intent ACTION_SIM_APPLICATION_STATE_CHANGED "
+ + TelephonyManager.simStateToString(state)
+ + " for phone: " + phoneId + " slot: " + slotId + "port: "
+ + slot.getPortIndexFromPhoneId(phoneId));
+ mContext.sendBroadcast(intent, Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+ TelephonyMetrics.getInstance().updateSimState(phoneId, state);
+ }
+ }
+
+ /**
+ * Get SIM state from SIM lock reason.
+ *
+ * @param lockedReason The SIM lock reason.
+ *
+ * @return The SIM state.
+ */
+ @SimState
+ private static int getSimStateFromLockedReason(String lockedReason) {
+ switch (lockedReason) {
+ case IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN:
+ return TelephonyManager.SIM_STATE_PIN_REQUIRED;
+ case IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK:
+ return TelephonyManager.SIM_STATE_PUK_REQUIRED;
+ case IccCardConstants.INTENT_VALUE_LOCKED_NETWORK:
+ return TelephonyManager.SIM_STATE_NETWORK_LOCKED;
+ case IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED:
+ return TelephonyManager.SIM_STATE_PERM_DISABLED;
+ default:
+ Rlog.e(LOG_TAG, "Unexpected SIM locked reason " + lockedReason);
+ return TelephonyManager.SIM_STATE_UNKNOWN;
+ }
+ }
+
+ /**
+ * Broadcast SIM state events.
+ *
+ * @param phoneId The phone id.
+ * @param simState The SIM state.
+ * @param reason SIM state changed reason.
+ */
+ private void broadcastSimStateEvents(int phoneId, IccCardConstants.State simState,
+ @Nullable String reason) {
+ String legacyStringSimState = getIccStateIntentString(simState);
+ int cardState = TelephonyManager.SIM_STATE_UNKNOWN;
+ int applicationState = TelephonyManager.SIM_STATE_UNKNOWN;
+
+ switch (simState) {
+ case ABSENT:
+ cardState = TelephonyManager.SIM_STATE_ABSENT;
+ break;
+ case PIN_REQUIRED:
+ case PUK_REQUIRED:
+ case NETWORK_LOCKED:
+ case PERM_DISABLED:
+ cardState = TelephonyManager.SIM_STATE_PRESENT;
+ applicationState = getSimStateFromLockedReason(reason);
+ break;
+ case READY:
+ case NOT_READY:
+ // Both READY and NOT_READY have the same card state and application state.
+ cardState = TelephonyManager.SIM_STATE_PRESENT;
+ applicationState = TelephonyManager.SIM_STATE_NOT_READY;
+ break;
+ case CARD_IO_ERROR:
+ cardState = TelephonyManager.SIM_STATE_CARD_IO_ERROR;
+ applicationState = TelephonyManager.SIM_STATE_NOT_READY;
+ break;
+ case CARD_RESTRICTED:
+ cardState = TelephonyManager.SIM_STATE_CARD_RESTRICTED;
+ applicationState = TelephonyManager.SIM_STATE_NOT_READY;
+ break;
+ case LOADED:
+ cardState = TelephonyManager.SIM_STATE_PRESENT;
+ applicationState = TelephonyManager.SIM_STATE_LOADED;
+ break;
+ case UNKNOWN:
+ default:
+ break;
+ }
+
+ broadcastSimStateChanged(phoneId, legacyStringSimState, reason);
+ broadcastSimCardStateChanged(phoneId, cardState);
+ broadcastSimApplicationStateChanged(phoneId, applicationState);
+ }
+
+ /**
+ * Update carrier service.
+ *
+ * @param phoneId The phone id.
+ * @param simState The SIM state.
+ */
+ private void updateCarrierServices(int phoneId, @NonNull String simState) {
+ CarrierConfigManager configManager = mContext.getSystemService(CarrierConfigManager.class);
+ if (configManager != null) {
+ configManager.updateConfigForPhoneId(phoneId, simState);
+ }
+ mCarrierServiceBindHelper.updateForPhoneId(phoneId, simState);
+ }
+
+ /**
+ * Check if the SIM application is enabled on the card or not.
+ *
+ * @param phoneId The phone id.
+ * @return {@code true} if the application is enabled.
+ */
+ private boolean areUiccAppsEnabledOnCard(int phoneId) {
+ // When uicc apps are disabled(supported in IRadio 1.5), we will still get IccId from
+ // cardStatus (since IRadio 1.2). Amd upon cardStatus change we'll receive another
+ // handleSimNotReady so this will be evaluated again.
+ UiccSlot slot = getUiccSlotForPhone(phoneId);
+ if (slot == null) return false;
+ UiccPort port = getUiccPort(phoneId);
+ String iccId = (port == null) ? null : port.getIccId();
+ if (iccId == null) {
+ return false;
+ }
+ SubscriptionInfo info = SubscriptionManagerService.getInstance()
+ .getAllSubInfoList(mContext.getOpPackageName(), mContext.getAttributionTag())
+ .stream().filter(subInfo -> subInfo.getIccId().equals(
+ IccUtils.stripTrailingFs(iccId)))
+ .findFirst().orElse(null);
+ return info != null && info.areUiccApplicationsEnabled();
+ }
+
+ /**
+ * Update the SIM state.
+ *
+ * @param phoneId Phone id.
+ * @param state SIM state (legacy).
+ * @param reason The reason for SIM state update.
+ */
+ public void updateSimState(int phoneId, @NonNull IccCardConstants.State state,
+ @Nullable String reason) {
+ post(() -> {
+ log("updateSimState: phoneId=" + phoneId + ", state=" + state + ", reason="
+ + reason);
+ if (!SubscriptionManager.isValidPhoneId(phoneId)) {
+ Rlog.e(LOG_TAG, "updateInternalIccState: Invalid phone id " + phoneId);
+ return;
+ }
+
+ mTelephonyManager.setSimStateForPhone(phoneId, state.toString());
+
+ String legacySimState = getIccStateIntentString(state);
+ int simState = state.ordinal();
+ SubscriptionManagerService.getInstance().updateSimState(phoneId, simState,
+ this::post,
+ () -> {
+ // The following are executed after subscription update completed in
+ // subscription manager service.
+
+ broadcastSimStateEvents(phoneId, state, reason);
+
+ UiccProfile uiccProfile = getUiccProfileForPhone(phoneId);
+
+ if (simState == TelephonyManager.SIM_STATE_READY) {
+ // SIM_STATE_READY is not a final state.
+ return;
+ }
+
+ if (simState == TelephonyManager.SIM_STATE_NOT_READY
+ && (uiccProfile != null && !uiccProfile.isEmptyProfile())
+ && areUiccAppsEnabledOnCard(phoneId)) {
+ // STATE_NOT_READY is not a final state for when both
+ // 1) It's not an empty profile, and
+ // 2) Its uicc applications are set to enabled.
+ //
+ // At this phase, we consider STATE_NOT_READY not a final state, so
+ // return for now.
+ log("updateSimState: SIM_STATE_NOT_READY is not a final "
+ + "state.");
+ return;
+ }
+
+ // At this point, the SIM state must be a final state (meaning we won't
+ // get more SIM state updates). So resolve the carrier id and update the
+ // carrier services.
+ log("updateSimState: resolve carrier id and update carrier "
+ + "services.");
+ PhoneFactory.getPhone(phoneId).resolveSubscriptionCarrierId(
+ legacySimState);
+ updateCarrierServices(phoneId, legacySimState);
+ }
+ );
+ });
+ }
+
private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) {
if (ar.exception != null) {
Rlog.e(LOG_TAG,"Error getting ICC status. "
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index b1d8dc2335..746a3606d6 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -801,8 +801,13 @@ public class UiccProfile extends IccCard {
}
log("setExternalState: set mPhoneId=" + mPhoneId + " mExternalState=" + mExternalState);
- UiccController.updateInternalIccState(mContext, mExternalState,
- getIccStateReason(mExternalState), mPhoneId);
+ if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
+ UiccController.getInstance().updateSimState(mPhoneId, mExternalState,
+ getIccStateReason(mExternalState));
+ } else {
+ UiccController.updateInternalIccState(mContext, mExternalState,
+ getIccStateReason(mExternalState), mPhoneId);
+ }
}
}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index 9b5b315b56..2490efa344 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -187,9 +187,15 @@ public class UiccSlot extends Handler {
if (!iss.mSimPortInfos[i].mPortActive) {
// TODO: (b/79432584) evaluate whether should broadcast card state change
// even if it's inactive.
- UiccController.updateInternalIccStateForInactivePort(mContext,
- mPortIdxToPhoneId.getOrDefault(i, INVALID_PHONE_ID),
- iss.mSimPortInfos[i].mIccId);
+ if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
+ UiccController.getInstance().updateSimStateForInactivePort(
+ mPortIdxToPhoneId.getOrDefault(i, INVALID_PHONE_ID),
+ iss.mSimPortInfos[i].mIccId);
+ } else {
+ UiccController.updateInternalIccStateForInactivePort(mContext,
+ mPortIdxToPhoneId.getOrDefault(i, INVALID_PHONE_ID),
+ iss.mSimPortInfos[i].mIccId);
+ }
mLastRadioState.put(i, TelephonyManager.RADIO_POWER_UNAVAILABLE);
if (mUiccCard != null) {
// Dispose the port
@@ -321,8 +327,14 @@ public class UiccSlot extends Handler {
if (DBG) log("update: notify card removed");
sendMessage(obtainMessage(EVENT_CARD_REMOVED, null));
}
- UiccController.updateInternalIccState(mContext, IccCardConstants.State.ABSENT,
- null, phoneId);
+
+ if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
+ UiccController.getInstance().updateSimState(phoneId, IccCardConstants.State.ABSENT,
+ null);
+ } else {
+ UiccController.updateInternalIccState(mContext, IccCardConstants.State.ABSENT,
+ null, phoneId);
+ }
// no card present in the slot now; dispose card and make mUiccCard null
nullifyUiccCard(false /* sim state is not unknown */);
mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE);
@@ -575,8 +587,13 @@ public class UiccSlot extends Handler {
nullifyUiccCard(true /* sim state is unknown */);
if (phoneId != INVALID_PHONE_ID) {
- UiccController.updateInternalIccState(
- mContext, IccCardConstants.State.UNKNOWN, null, phoneId);
+ if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
+ UiccController.getInstance().updateSimState(phoneId,
+ IccCardConstants.State.UNKNOWN, null);
+ } else {
+ UiccController.updateInternalIccState(
+ mContext, IccCardConstants.State.UNKNOWN, null, phoneId);
+ }
mLastRadioState.put(getPortIndexFromPhoneId(phoneId),
TelephonyManager.RADIO_POWER_UNAVAILABLE);
}