Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c49e735 authored by Beverly Tai's avatar Beverly Tai Committed by Automerger Merge Worker
Browse files

Merge "Fix SystemUI mapping SIM state error issue" into udc-dev am: 6fd60cc2

parents fed98400 6fd60cc2
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -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()
    @VisibleForTesting
    protected CarrierTextManager.StatusMode getStatusForIccState(int simState) {
        if (!mKeyguardUpdateMonitor.isDeviceProvisioned()
                && (simState == TelephonyManager.SIM_STATE_ABSENT
                        || simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
                        || 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;
    }
+50 −22
Original line number Diff line number Diff line
@@ -2045,11 +2045,47 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private final HashMap<Integer, Boolean> 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;
            } 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);
        }
+60 −0
Original line number Diff line number Diff line
@@ -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));
+131 −0
Original line number Diff line number Diff line
@@ -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);
        }