diff options
author | Jordan Liu <jminjie@google.com> | 2019-04-25 11:39:30 -0700 |
---|---|---|
committer | Jordan Liu <jminjie@google.com> | 2019-05-01 11:01:30 -0700 |
commit | c4c994c718be11dd140fbae2fb1271efbae2f66c (patch) | |
tree | 514ecc591aadd2da3fe45860eba50dd8975d626d | |
parent | 1cca36825c3958556c7c8c85722df4d30d7b9702 (diff) | |
download | telephony-c4c994c718be11dd140fbae2fb1271efbae2f66c.tar.gz |
Make absent and inactive SIM still update subs
When we get a slot status update with an absent SIM in an inactive slot,
we still update the subscriptions, we just don't broadcast the SIM state
change.
Bug: 130749300
Test: manual and atest UiccSlotTest
Change-Id: I83d36af27fa5eaed8f84a4f7378e69a366a48b53
Merged-In: I83d36af27fa5eaed8f84a4f7378e69a366a48b53
5 files changed, 100 insertions, 34 deletions
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java index 5adfb06f62..e9f65d4860 100644 --- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java @@ -175,12 +175,16 @@ public class SubscriptionInfoUpdater extends Handler { mCurrentlyActiveUserId); } - public void updateInternalIccState(String simStatus, String reason, int slotId) { + /** + * Update subscriptions when given a new ICC state. + */ + public void updateInternalIccState(String simStatus, String reason, int slotId, + boolean absentAndInactive) { logd("updateInternalIccState to simStatus " + simStatus + " reason " + reason + " slotId " + slotId); int message = internalIccStateToMessage(simStatus); if (message != EVENT_INVALID) { - sendMessage(obtainMessage(message, slotId, -1, reason)); + sendMessage(obtainMessage(message, slotId, absentAndInactive ? 1 : 0, reason)); } } @@ -236,7 +240,7 @@ public class SubscriptionInfoUpdater extends Handler { break; case EVENT_SIM_ABSENT: - handleSimAbsent(msg.arg1); + handleSimAbsent(msg.arg1, msg.arg2); break; case EVENT_SIM_LOCKED: @@ -540,17 +544,21 @@ public class SubscriptionInfoUpdater extends Handler { } } - private void handleSimAbsent(int slotId) { + private void handleSimAbsent(int slotId, int absentAndInactive) { if (mIccId[slotId] != null && !mIccId[slotId].equals(ICCID_STRING_FOR_NO_SIM)) { - logd("SIM" + (slotId + 1) + " hot plug out"); + logd("SIM" + (slotId + 1) + " hot plug out, absentAndInactive=" + absentAndInactive); } mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; updateSubscriptionInfoByIccId(slotId); - broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); - broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); - broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); - updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); - updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); + // Do not broadcast if the SIM is absent and inactive, because the logical slotId here is + // no longer correct + if (absentAndInactive == 0) { + broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); + broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); + broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); + updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); + updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); + } } private void handleSimError(int slotId) { diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java index 26e3111836..bc79a77385 100644 --- a/src/java/com/android/internal/telephony/uicc/UiccController.java +++ b/src/java/com/android/internal/telephony/uicc/UiccController.java @@ -569,6 +569,13 @@ public class UiccController extends Handler { static void updateInternalIccState(Context context, IccCardConstants.State state, String reason, int phoneId) { + updateInternalIccState(context, state, reason, phoneId, false); + } + + // absentAndInactive is a special case when we need to update subscriptions but don't want to + // broadcast a state change + static void updateInternalIccState(Context context, IccCardConstants.State state, String reason, + int phoneId, boolean absentAndInactive) { TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE); telephonyManager.setSimStateForPhone(phoneId, state.toString()); @@ -576,7 +583,7 @@ public class UiccController extends Handler { SubscriptionInfoUpdater subInfoUpdator = PhoneFactory.getSubscriptionInfoUpdater(); if (subInfoUpdator != null) { subInfoUpdator.updateInternalIccState(getIccStateIntentString(state), - reason, phoneId); + reason, phoneId, absentAndInactive); } else { Rlog.e(LOG_TAG, "subInfoUpdate is null."); } diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java index 30e499941c..d16c0f1108 100644 --- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java +++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java @@ -152,8 +152,10 @@ public class UiccSlot extends Handler { if (mActive) { mActive = false; mLastRadioState = TelephonyManager.RADIO_POWER_UNAVAILABLE; + UiccController.updateInternalIccState( + mContext, IccCardConstants.State.ABSENT, null, mPhoneId, + true /* special notification for absent card in an inactive slot */); mPhoneId = INVALID_PHONE_ID; - if (mUiccCard != null) mUiccCard.dispose(); nullifyUiccCard(true /* sim state is unknown */); } } else { @@ -188,9 +190,6 @@ public class UiccSlot extends Handler { mContext, IccCardConstants.State.ABSENT, null, mPhoneId); // no card present in the slot now; dispose card and make mUiccCard null - if (mUiccCard != null) { - mUiccCard.dispose(); - } nullifyUiccCard(false /* sim state is not unknown */); mLastRadioState = radioState; } @@ -199,6 +198,9 @@ public class UiccSlot extends Handler { // unknown states. To mitigate this, we will us mStateIsUnknown to keep track. The sim is only // unknown if we haven't heard from the radio or if the radio has become unavailable. private void nullifyUiccCard(boolean stateUnknown) { + if (mUiccCard != null) { + mUiccCard.dispose(); + } mStateIsUnknown = stateUnknown; mUiccCard = null; } @@ -393,9 +395,6 @@ public class UiccSlot extends Handler { * Processes radio state unavailable event */ public void onRadioStateUnavailable() { - if (mUiccCard != null) { - mUiccCard.dispose(); - } nullifyUiccCard(true /* sim state is unknown */); if (mPhoneId != INVALID_PHONE_ID) { diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java index e6f9d2809c..0af5a27920 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java @@ -178,7 +178,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController) .getActiveSubIdList(/*visibleOnly*/false); mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1, false); waitForMs(100); verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); @@ -192,9 +192,32 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @Test @SmallTest + public void testSimAbsentAndInactive() throws Exception { + doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) + .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); + doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController) + .getActiveSubIdList(/*visibleOnly*/false); + mUpdater.updateInternalIccState( + IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1, true); + + waitForMs(100); + verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); + + // Verify that in the special absent and inactive case, we update subscriptions without + // broadcasting SIM state change + CarrierConfigManager mConfigManager = (CarrierConfigManager) + mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); + verify(mConfigManager, times(0)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), + eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT)); + verify(mContext, times(0)).sendBroadcast(any(), anyString()); + verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); + } + + @Test + @SmallTest public void testSimUnknown() throws Exception { mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, FAKE_SUB_ID_1, false); waitForMs(100); verify(mSubscriptionContent, times(0)).put(anyString(), any()); @@ -210,7 +233,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testSimError() throws Exception { mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1, false); waitForMs(100); verify(mSubscriptionContent, times(0)).put(anyString(), any()); @@ -226,7 +249,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testWrongSimState() throws Exception { mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_IMSI, null, 2); + IccCardConstants.INTENT_VALUE_ICC_IMSI, null, 2, false); waitForMs(100); verify(mSubscriptionContent, times(0)).put(anyString(), any()); @@ -248,7 +271,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); waitForMs(100); @@ -313,7 +336,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); waitForMs(300); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); @@ -339,7 +362,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1, false); waitForMs(100); @@ -387,7 +410,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); waitForMs(100); @@ -402,7 +425,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_2); + IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_2, false); waitForMs(100); @@ -424,7 +447,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { new String[]{"89012604200000000000"}); mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1, false); waitForMs(100); @@ -565,7 +588,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { // Mock sending a sim loaded for SIM 1 mUpdater.updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_LOADED, "TESTING", FAKE_SUB_ID_1); + IccCardConstants.INTENT_VALUE_ICC_LOADED, "TESTING", FAKE_SUB_ID_1, false); waitForMs(100); diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java index 6838583420..b3a296d0d7 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java @@ -154,7 +154,7 @@ public class UiccSlotTest extends TelephonyTest { assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState()); assertEquals(iss.iccid, mUiccSlot.getIccId()); verify(mSubInfoRecordUpdater).updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId); + IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId, false); // update slot to active mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */); @@ -242,13 +242,42 @@ public class UiccSlotTest extends TelephonyTest { mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT; mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex); verify(mSubInfoRecordUpdater).updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId); + IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId, false); assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState()); assertNull(mUiccSlot.getUiccCard()); } @Test @SmallTest + public void testUpdateAbsentStateInactiveSlotStatus() { + IccSlotStatus activeIss = new IccSlotStatus(); + activeIss.logicalSlotIndex = 0; + activeIss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE; + activeIss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT; + activeIss.iccid = "fake-iccid"; + IccSlotStatus inactiveIss = new IccSlotStatus(); + inactiveIss.logicalSlotIndex = 0; + inactiveIss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE; + inactiveIss.cardState = IccCardStatus.CardState.CARDSTATE_ABSENT; + inactiveIss.iccid = "fake-iccid"; + + // update slot to inactive with absent card + mUiccSlot.update(null, activeIss, 0 /* slotIndex */); + mUiccSlot.update(null, inactiveIss, 0 /* slotIndex */); + + // assert on updated values + assertFalse(mUiccSlot.isActive()); + assertNull(mUiccSlot.getUiccCard()); + assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState()); + + // assert that we tried to update subscriptions + verify(mSubInfoRecordUpdater).updateInternalIccState( + IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, activeIss.logicalSlotIndex, true); + } + + + @Test + @SmallTest public void testUiccSlotCreateAndDispose() { int phoneId = 0; int slotIndex = 0; @@ -266,7 +295,7 @@ public class UiccSlotTest extends TelephonyTest { mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT; mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex); verify(mSubInfoRecordUpdater).updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId); + IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId, false); verify(mUiccProfile).dispose(); assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState()); assertNull(mUiccSlot.getUiccCard()); @@ -291,7 +320,7 @@ public class UiccSlotTest extends TelephonyTest { // Verify that UNKNOWN state is sent to SubscriptionInfoUpdater in this case. verify(mSubInfoRecordUpdater).updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, phoneId); + IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, phoneId, false); assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState()); assertNull(mUiccSlot.getUiccCard()); @@ -301,7 +330,7 @@ public class UiccSlotTest extends TelephonyTest { // Verify that ABSENT state is sent to SubscriptionInfoUpdater in this case. verify(mSubInfoRecordUpdater).updateInternalIccState( - IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId); + IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId, false); assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState()); assertNull(mUiccSlot.getUiccCard()); } |