Merge "Fix SystemUI mapping SIM state error issue" into udc-dev

This commit is contained in:
Beverly Tai
2023-06-15 13:12:44 +00:00
committed by Android (Google) Code Review
4 changed files with 255 additions and 31 deletions

View File

@@ -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;
}

View File

@@ -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;
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);
}

View File

@@ -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));

View File

@@ -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);
}