From 13647d752f526ed15f3ad9bf4653e920b4ddd394 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 2 Jul 2020 02:27:34 +0800 Subject: [PATCH] Fix SystemUI mapping SIM state error issue KeyguardUpdateMonitor#SimData#simState is updated from telephony broadcast whose action is Intent#ACTION_SIM_STATE_CHANGED, but the sim state mapping is inconsistent with telephony design. Below are the telephony design of broadcast extra(SIM state and reason) mapping matrix for action Intent#ACTION_SIM_STATE_CHANGED: 1. SIM card state unknown: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_UNKNOWN b) Intent#EXTRA_SIM_LOCKED_REASON: always null 2. SIM absent: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_ABSENT b) Intent#EXTRA_SIM_LOCKED_REASON: always null 3. SIM IO error three consecutive times: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_CARD_IO_ERROR b) Intent#EXTRA_SIM_LOCKED_REASON: Intent#SIM_STATE_CARD_IO_ERROR 4. SIM card is present but not usable due to carrier restrictions: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_CARD_RESTRICTED b) Intent#EXTRA_SIM_LOCKED_REASON: Intent#SIM_STATE_CARD_RESTRICTED 5. SIM locked: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_LOCKED b) Intent#EXTRA_SIM_LOCKED_REASON: - locked on PIN1: Intent#SIM_LOCKED_ON_PIN - locked on PUK1: Intent#SIM_LOCKED_ON_PUK - locked on network personalization: Intent#SIM_LOCKED_NETWORK - permanently disabled due to puk fails: Intent#SIM_ABSENT_ON_PERM_DISABLED 6. SIM applications are not ready: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_NOT_READY b) Intent#EXTRA_SIM_LOCKED_REASON: always null 7. SIM IMSI is ready in property, but currently it is never broadcasted: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_IMSI b) Intent#EXTRA_SIM_LOCKED_REASON: always null 8. SIM all applications are ready: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_READY b) Intent#EXTRA_SIM_LOCKED_REASON: always null 9. SIM all ICC records, including IMSI, are loaded: a) Intent#EXTRA_SIM_STATE: Intent#SIM_STATE_LOADED b) Intent#EXTRA_SIM_LOCKED_REASON: always null Based on above, this patch fixes below points: 1. Upate KeyguardUpdateMonitor#SimData#fromIntent sim state, which follows telephony design. 2. Update CarrierTextManager#getStatusForIccState a) network locked mapping: TelephonyManager#SIM_STATE_NETWORK_LOCKED to CarrierTextManager#StatusMode#NetworkLocked. b) adds missed state CarrierTextManager#StatusMode#SimRestricted. 3. Add related automated unit tests to verify code logic Bug: 265564214 Bug: 265440217 Test: Build and manual test on device. Test: atest CarrierTextManagerTest KeyguardUpdateMonitorTest Change-Id: I76eff7a66f2dac6f87072501dc6654e48c105e02 Signed-off-by: Wei Huang Signed-off-by: Honggang Luo Signed-off-by: Chao Yuan --- .../android/keyguard/CarrierTextManager.java | 23 +-- .../keyguard/KeyguardUpdateMonitor.java | 72 +++++++--- .../keyguard/CarrierTextManagerTest.java | 60 ++++++++ .../keyguard/KeyguardUpdateMonitorTest.java | 131 ++++++++++++++++++ 4 files changed, 255 insertions(+), 31 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java index a724514f6ec90..b52ee01bfa612 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java @@ -148,7 +148,8 @@ public class CarrierTextManager { /** * The status of this lock screen. Primarily used for widgets on LockScreen. */ - private enum StatusMode { + @VisibleForTesting + protected enum StatusMode { Normal, // Normal case (sim card present, it's not locked) NetworkLocked, // SIM card is 'network locked'. SimMissing, // SIM card is missing. @@ -158,6 +159,7 @@ public class CarrierTextManager { SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM. SimIoError, // SIM card is faulty + SimRestricted, // SIM Card restricted, present but not usable due to carrier restrictions. SimUnknown // SIM card is unknown } @@ -493,6 +495,7 @@ public class CarrierTextManager { getContext().getText(R.string.keyguard_sim_error_message_short), text); break; + case SimRestricted: // fall through case SimUnknown: carrierText = null; break; @@ -535,19 +538,19 @@ public class CarrierTextManager { /** * Determine the current status of the lock screen given the SIM state and other stuff. */ - private CarrierTextManager.StatusMode getStatusForIccState(int simState) { - final boolean missingAndNotProvisioned = - !mKeyguardUpdateMonitor.isDeviceProvisioned() - && (simState == TelephonyManager.SIM_STATE_ABSENT - || simState == TelephonyManager.SIM_STATE_PERM_DISABLED); + @VisibleForTesting + protected CarrierTextManager.StatusMode getStatusForIccState(int simState) { + if (!mKeyguardUpdateMonitor.isDeviceProvisioned() + && (simState == TelephonyManager.SIM_STATE_ABSENT + || simState == TelephonyManager.SIM_STATE_PERM_DISABLED)) { + return CarrierTextManager.StatusMode.SimMissingLocked; + } - // Assume we're NETWORK_LOCKED if not provisioned - simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState; switch (simState) { case TelephonyManager.SIM_STATE_ABSENT: return CarrierTextManager.StatusMode.SimMissing; case TelephonyManager.SIM_STATE_NETWORK_LOCKED: - return CarrierTextManager.StatusMode.SimMissingLocked; + return CarrierTextManager.StatusMode.NetworkLocked; case TelephonyManager.SIM_STATE_NOT_READY: return CarrierTextManager.StatusMode.SimNotReady; case TelephonyManager.SIM_STATE_PIN_REQUIRED: @@ -562,6 +565,8 @@ public class CarrierTextManager { return CarrierTextManager.StatusMode.SimUnknown; case TelephonyManager.SIM_STATE_CARD_IO_ERROR: return CarrierTextManager.StatusMode.SimIoError; + case TelephonyManager.SIM_STATE_CARD_RESTRICTED: + return CarrierTextManager.StatusMode.SimRestricted; } return CarrierTextManager.StatusMode.SimUnknown; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index c7e817e5781a2..ae061c0324292 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -2045,11 +2045,47 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final HashMap mIsUnlockWithFingerprintPossible = new HashMap<>(); /** - * When we receive a - * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast, + * When we receive a {@link android.content.Intent#ACTION_SIM_STATE_CHANGED} broadcast, * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange}, * we need a single object to pass to the handler. This class helps decode * the intent and provide a {@link SimData} result. + * + * Below is the Sim state mapping matrixs: + * +---+-----------------------------------------------------+----------------------------+ + * | |Telephony FWK broadcast with action |SystemUI mapping SIM state | + * | |android.content.Intent#ACTION_SIM_STATE_CHANGED |refer to android.telephony. | + * |NO.+-------------------------+---------------------------+TelephonyManager#getSimState| + * | |EXTRA_SIM_STATE |EXTRA_SIM_LOCKED_REASON | | + * | |(Intent#XXX) |(Intent#XXX) |TelephonyManager#SimState | + * +===+=====================================================+============================+ + * |1 |SIM_STATE_UNKNOWN |always null |SIM_STATE_UNKNOWN | + * +---+-------------------------+---------------------------+----------------------------+ + * |2 |SIM_STATE_ABSENT |always null |SIM_STATE_ABSENT | + * +---+-------------------------+---------------------------+----------------------------+ + * |3 |SIM_STATE_CARD_IO_ERROR |SIM_STATE_CARD_IO_ERROR |SIM_STATE_CARD_IO_ERROR | + * +---+-------------------------+---------------------------+----------------------------+ + * |4 |SIM_STATE_CARD_RESTRICTED|SIM_STATE_CARD_RESTRICTED |SIM_STATE_CARD_RESTRICTED | + * +---+-------------------------+---------------------------+----------------------------+ + * |5 |SIM_STATE_LOCKED |SIM_LOCKED_ON_PIN |SIM_STATE_PIN_REQUIRED | + * +---+-------------------------+---------------------------+----------------------------+ + * |6 |SIM_STATE_LOCKED |SIM_LOCKED_ON_PUK |SIM_STATE_PUK_REQUIRED | + * +---+-------------------------+---------------------------+----------------------------+ + * |7 |SIM_STATE_LOCKED |SIM_LOCKED_NETWORK |SIM_STATE_NETWORK_LOCKED | + * +---+-------------------------+---------------------------+----------------------------+ + * |8 |SIM_STATE_LOCKED |SIM_ABSENT_ON_PERM_DISABLED|SIM_STATE_PERM_DISABLED | + * +---+-------------------------+---------------------------+----------------------------+ + * |9 |SIM_STATE_NOT_READY |always null |SIM_STATE_NOT_READY | + * +---+-------------------------+---------------------------+----------------------------+ + * |10 |SIM_STATE_IMSI |always null |SIM_STATE_READY | + * +---+-------------------------+---------------------------+----------------------------+ + * |11 |SIM_STATE_READY |always null |SIM_STATE_READY | + * +---+-------------------------+---------------------------+----------------------------+ + * |12 |SIM_STATE_LOADED |always null |SIM_STATE_READY | + * +---+-------------------------+---------------------------+----------------------------+ + * + * Note that, it seems #10 imsi ready case(i.e. SIM_STATE_IMSI) is never triggered from + * Android Pie(telephony FWK doesn't trigger this broadcast any more), but it is still + * OK keep this mapping logic. */ private static class SimData { public int simState; @@ -2063,26 +2099,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } static SimData fromIntent(Intent intent) { - int state; if (!Intent.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) { throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED"); } + int state = TelephonyManager.SIM_STATE_UNKNOWN; String stateExtra = intent.getStringExtra(Intent.EXTRA_SIM_STATE); int slotId = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0); int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.INVALID_SUBSCRIPTION_ID); if (Intent.SIM_STATE_ABSENT.equals(stateExtra)) { - final String absentReason = intent - .getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON); - - if (Intent.SIM_ABSENT_ON_PERM_DISABLED.equals( - absentReason)) { - state = TelephonyManager.SIM_STATE_PERM_DISABLED; - } else { - state = TelephonyManager.SIM_STATE_ABSENT; - } - } else if (Intent.SIM_STATE_READY.equals(stateExtra)) { - state = TelephonyManager.SIM_STATE_READY; + state = TelephonyManager.SIM_STATE_ABSENT; } else if (Intent.SIM_STATE_LOCKED.equals(stateExtra)) { final String lockedReason = intent .getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON); @@ -2090,22 +2116,24 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab state = TelephonyManager.SIM_STATE_PIN_REQUIRED; } else if (Intent.SIM_LOCKED_ON_PUK.equals(lockedReason)) { state = TelephonyManager.SIM_STATE_PUK_REQUIRED; + } else if (Intent.SIM_LOCKED_NETWORK.equals(lockedReason)) { + state = TelephonyManager.SIM_STATE_NETWORK_LOCKED; } else if (Intent.SIM_ABSENT_ON_PERM_DISABLED.equals(lockedReason)) { state = TelephonyManager.SIM_STATE_PERM_DISABLED; - } else { - state = TelephonyManager.SIM_STATE_UNKNOWN; } - } else if (Intent.SIM_LOCKED_NETWORK.equals(stateExtra)) { - state = TelephonyManager.SIM_STATE_NETWORK_LOCKED; } else if (Intent.SIM_STATE_CARD_IO_ERROR.equals(stateExtra)) { state = TelephonyManager.SIM_STATE_CARD_IO_ERROR; - } else if (Intent.SIM_STATE_LOADED.equals(stateExtra) + } else if (Intent.SIM_STATE_CARD_RESTRICTED.equals(stateExtra)) { + state = TelephonyManager.SIM_STATE_CARD_RESTRICTED; + } else if (Intent.SIM_STATE_NOT_READY.equals(stateExtra)) { + state = TelephonyManager.SIM_STATE_NOT_READY; + } else if (Intent.SIM_STATE_READY.equals(stateExtra) + || Intent.SIM_STATE_LOADED.equals(stateExtra) || Intent.SIM_STATE_IMSI.equals(stateExtra)) { - // This is required because telephony doesn't return to "READY" after + // Mapping SIM_STATE_LOADED and SIM_STATE_IMSI to SIM_STATE_READY is required + // because telephony doesn't return to "READY" after // these state transitions. See bug 7197471. state = TelephonyManager.SIM_STATE_READY; - } else { - state = TelephonyManager.SIM_STATE_UNKNOWN; } return new SimData(state, slotId, subId); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java index 48a8d1bc90d70..e7d420bcb32bc 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java @@ -561,6 +561,66 @@ public class CarrierTextManagerTest extends SysuiTestCase { captor.getValue().carrierText); } + @Test + public void testGetStatusForIccState() { + when(mKeyguardUpdateMonitor.isDeviceProvisioned()).thenReturn(false); + assertEquals(CarrierTextManager.StatusMode.SimMissingLocked, + mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_ABSENT)); + assertEquals(CarrierTextManager.StatusMode.NetworkLocked, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_NETWORK_LOCKED)); + assertEquals(CarrierTextManager.StatusMode.SimNotReady, + mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_NOT_READY)); + assertEquals(CarrierTextManager.StatusMode.SimLocked, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_PIN_REQUIRED)); + assertEquals(CarrierTextManager.StatusMode.SimPukLocked, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_PUK_REQUIRED)); + assertEquals(CarrierTextManager.StatusMode.Normal, + mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_READY)); + assertEquals(CarrierTextManager.StatusMode.SimMissingLocked, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_PERM_DISABLED)); + assertEquals(CarrierTextManager.StatusMode.SimUnknown, + mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_UNKNOWN)); + assertEquals(CarrierTextManager.StatusMode.SimIoError, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_CARD_IO_ERROR)); + assertEquals(CarrierTextManager.StatusMode.SimRestricted, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_CARD_RESTRICTED)); + + when(mKeyguardUpdateMonitor.isDeviceProvisioned()).thenReturn(true); + assertEquals(CarrierTextManager.StatusMode.SimMissing, + mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_ABSENT)); + assertEquals(CarrierTextManager.StatusMode.NetworkLocked, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_NETWORK_LOCKED)); + assertEquals(CarrierTextManager.StatusMode.SimNotReady, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_NOT_READY)); + assertEquals(CarrierTextManager.StatusMode.SimLocked, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_PIN_REQUIRED)); + assertEquals(CarrierTextManager.StatusMode.SimPukLocked, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_PUK_REQUIRED)); + assertEquals(CarrierTextManager.StatusMode.Normal, + mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_READY)); + assertEquals(CarrierTextManager.StatusMode.SimPermDisabled, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_PERM_DISABLED)); + assertEquals(CarrierTextManager.StatusMode.SimUnknown, + mCarrierTextManager.getStatusForIccState(TelephonyManager.SIM_STATE_UNKNOWN)); + assertEquals(CarrierTextManager.StatusMode.SimIoError, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_CARD_IO_ERROR)); + assertEquals(CarrierTextManager.StatusMode.SimRestricted, + mCarrierTextManager.getStatusForIccState( + TelephonyManager.SIM_STATE_CARD_RESTRICTED)); + } + private Context getContextSpyForStickyBroadcast(Intent returnVal) { Context contextSpy = spy(mContext); doReturn(returnVal).when(contextSpy).registerReceiver(eq(null), any(IntentFilter.class)); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index de306d6694763..1e675f8e45407 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -167,6 +167,7 @@ import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -671,6 +672,130 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { verify(mTestCallback, times(2)).onRefreshCarrierInfo(); } + @Test + public void testHandleSimStateChange_Unknown() { + Intent intent = new Intent(Intent.ACTION_SIM_STATE_CHANGED); + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_UNKNOWN); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, false)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_UNKNOWN, + mKeyguardUpdateMonitor.getCachedSimState()); + } + + @Test + public void testHandleSimStateChange_Absent() { + Intent intent = new Intent(Intent.ACTION_SIM_STATE_CHANGED); + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_ABSENT); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, false)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_ABSENT, + mKeyguardUpdateMonitor.getCachedSimState()); + } + + @Test + public void testHandleSimStateChange_CardIOError() { + Intent intent = new Intent(Intent.ACTION_SIM_STATE_CHANGED); + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_CARD_IO_ERROR); + intent.putExtra(Intent.EXTRA_SIM_LOCKED_REASON, Intent.SIM_STATE_CARD_IO_ERROR); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, false)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_CARD_IO_ERROR, + mKeyguardUpdateMonitor.getCachedSimState()); + } + + @Test + public void testHandleSimStateChange_CardRestricted() { + Intent intent = new Intent(Intent.ACTION_SIM_STATE_CHANGED); + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_CARD_RESTRICTED); + intent.putExtra(Intent.EXTRA_SIM_LOCKED_REASON, Intent.SIM_STATE_CARD_RESTRICTED); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, false)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_CARD_RESTRICTED, + mKeyguardUpdateMonitor.getCachedSimState()); + } + + @Test + public void testHandleSimStateChange_Locked() { + Intent intent = new Intent(Intent.ACTION_SIM_STATE_CHANGED); + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_LOCKED); + + // locked on PIN1 + intent.putExtra(Intent.EXTRA_SIM_LOCKED_REASON, Intent.SIM_LOCKED_ON_PIN); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, true)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_PIN_REQUIRED, + mKeyguardUpdateMonitor.getCachedSimState()); + + // locked on PUK1 + intent.putExtra(Intent.EXTRA_SIM_LOCKED_REASON, Intent.SIM_LOCKED_ON_PUK); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, true)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_PUK_REQUIRED, + mKeyguardUpdateMonitor.getCachedSimState()); + + // locked on network personalization + intent.putExtra(Intent.EXTRA_SIM_LOCKED_REASON, Intent.SIM_LOCKED_NETWORK); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, true)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_NETWORK_LOCKED, + mKeyguardUpdateMonitor.getCachedSimState()); + + // permanently disabled due to puk fails + intent.putExtra(Intent.EXTRA_SIM_LOCKED_REASON, Intent.SIM_ABSENT_ON_PERM_DISABLED); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, true)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_PERM_DISABLED, + mKeyguardUpdateMonitor.getCachedSimState()); + } + + @Test + public void testHandleSimStateChange_NotReady() { + Intent intent = new Intent(Intent.ACTION_SIM_STATE_CHANGED); + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_NOT_READY); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, false)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_NOT_READY, + mKeyguardUpdateMonitor.getCachedSimState()); + } + + @Test + public void testHandleSimStateChange_Ready() { + Intent intent = new Intent(Intent.ACTION_SIM_STATE_CHANGED); + + // ICC IMSI is ready in property + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_IMSI); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, false)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_READY, + mKeyguardUpdateMonitor.getCachedSimState()); + + // ICC is ready to access + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_READY); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, false)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_READY, + mKeyguardUpdateMonitor.getCachedSimState()); + + // all ICC records, including IMSI, are loaded + intent.putExtra(Intent.EXTRA_SIM_STATE, Intent.SIM_STATE_LOADED); + mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), + putPhoneInfo(intent, null, true)); + mTestableLooper.processAllMessages(); + Assert.assertEquals(TelephonyManager.SIM_STATE_READY, + mKeyguardUpdateMonitor.getCachedSimState()); + } + @Test public void testTriesToAuthenticateFingerprint_whenKeyguard() { mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); @@ -3122,6 +3247,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private class TestableKeyguardUpdateMonitor extends KeyguardUpdateMonitor { AtomicBoolean mSimStateChanged = new AtomicBoolean(false); + AtomicInteger mCachedSimState = new AtomicInteger(-1); protected TestableKeyguardUpdateMonitor(Context context) { super(context, mUserTracker, @@ -3144,9 +3270,14 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { return mSimStateChanged.getAndSet(false); } + public int getCachedSimState() { + return mCachedSimState.getAndSet(-1); + } + @Override protected void handleSimStateChange(int subId, int slotId, int state) { mSimStateChanged.set(true); + mCachedSimState.set(state); super.handleSimStateChange(subId, slotId, state); }