ClearBiometricRecognized when user switches
User unlock states should be cleared whenever user switches. Otherwise, it's possible for the following sequence of events 1) Unlock first user via biometrics 2) Do not dismiss keyguard, switch to second user 3) Switch back to first user - can unlock without authenticating Fixes: 151906507 Test: Repeat steps above, does not occur anymore Test: atest KeyguardUpdateMonitorTest Change-Id: I1d8e5867a18a680e85be8c335f09d4cb4209612e
This commit is contained in:
@@ -127,6 +127,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
|
||||
private static final boolean DEBUG_FACE = true;
|
||||
private static final boolean DEBUG_SPEW = false;
|
||||
private static final int LOW_BATTERY_THRESHOLD = 20;
|
||||
|
||||
private static final String ACTION_FACE_UNLOCK_STARTED
|
||||
@@ -324,7 +325,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
}
|
||||
};
|
||||
|
||||
private class BiometricAuthenticated {
|
||||
@VisibleForTesting
|
||||
static class BiometricAuthenticated {
|
||||
private final boolean mAuthenticated;
|
||||
private final boolean mIsStrongBiometric;
|
||||
|
||||
@@ -338,11 +340,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
|
||||
private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
|
||||
private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray();
|
||||
private SparseArray<BiometricAuthenticated> mUserFingerprintAuthenticated = new SparseArray<>();
|
||||
private SparseArray<BiometricAuthenticated> mUserFaceAuthenticated = new SparseArray<>();
|
||||
private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
|
||||
private Map<Integer, Intent> mSecondaryLockscreenRequirement = new HashMap<Integer, Intent>();
|
||||
|
||||
@VisibleForTesting
|
||||
SparseArray<BiometricAuthenticated> mUserFingerprintAuthenticated = new SparseArray<>();
|
||||
@VisibleForTesting
|
||||
SparseArray<BiometricAuthenticated> mUserFaceAuthenticated = new SparseArray<>();
|
||||
|
||||
private static int sCurrentUser;
|
||||
private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
|
||||
|
||||
@@ -1850,11 +1855,33 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
|
||||
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
|
||||
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
|
||||
return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
|
||||
final boolean shouldListen =
|
||||
(mBouncer || mAuthInterruptActive || awakeKeyguard
|
||||
|| shouldListenForFaceAssistant())
|
||||
&& !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
|
||||
&& !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
|
||||
&& strongAuthAllowsScanning && mIsPrimaryUser
|
||||
&& !mSecureCameraLaunched;
|
||||
|
||||
// Too chatty, but very useful when debugging issues.
|
||||
if (DEBUG_SPEW) {
|
||||
Log.v(TAG, "shouldListenForFace(" + user + ")=" + shouldListen + "... "
|
||||
+ ", mBouncer: " + mBouncer
|
||||
+ ", mAuthInterruptActive: " + mAuthInterruptActive
|
||||
+ ", awakeKeyguard: " + awakeKeyguard
|
||||
+ ", shouldListenForFaceAssistant: " + shouldListenForFaceAssistant()
|
||||
+ ", mSwitchingUser: " + mSwitchingUser
|
||||
+ ", isFaceDisabled(" + user + "): " + isFaceDisabled(user)
|
||||
+ ", becauseCannotSkipBouncer: " + becauseCannotSkipBouncer
|
||||
+ ", mKeyguardGoingAway: " + mKeyguardGoingAway
|
||||
+ ", mFaceSettingEnabledForUser(" + user + "): "
|
||||
+ mFaceSettingEnabledForUser.get(user)
|
||||
+ ", mLockIconPressed: " + mLockIconPressed
|
||||
+ ", strongAuthAllowsScanning: " + strongAuthAllowsScanning
|
||||
+ ", isPrimaryUser: " + mIsPrimaryUser
|
||||
+ ", mSecureCameraLaunched: " + mSecureCameraLaunched);
|
||||
}
|
||||
return shouldListen;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2049,8 +2076,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
/**
|
||||
* Handle {@link #MSG_USER_SWITCHING}
|
||||
*/
|
||||
private void handleUserSwitching(int userId, IRemoteCallback reply) {
|
||||
@VisibleForTesting
|
||||
void handleUserSwitching(int userId, IRemoteCallback reply) {
|
||||
Assert.isMainThread();
|
||||
clearBiometricRecognized();
|
||||
mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
|
||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||
|
||||
@@ -52,6 +52,7 @@ import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.ServiceState;
|
||||
@@ -63,6 +64,7 @@ import android.testing.TestableContext;
|
||||
import android.testing.TestableLooper;
|
||||
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor.BiometricAuthenticated;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
@@ -505,6 +507,24 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
assertThat(mKeyguardUpdateMonitor.getUserCanSkipBouncer(user)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBiometricsCleared_whenUserSwitches() throws Exception {
|
||||
final IRemoteCallback reply = new IRemoteCallback.Stub() {
|
||||
@Override
|
||||
public void sendResult(Bundle data) {} // do nothing
|
||||
};
|
||||
final BiometricAuthenticated dummyAuthentication =
|
||||
new BiometricAuthenticated(true /* authenticated */, true /* strong */);
|
||||
mKeyguardUpdateMonitor.mUserFaceAuthenticated.put(0 /* user */, dummyAuthentication);
|
||||
mKeyguardUpdateMonitor.mUserFingerprintAuthenticated.put(0 /* user */, dummyAuthentication);
|
||||
assertThat(mKeyguardUpdateMonitor.mUserFingerprintAuthenticated.size()).isEqualTo(1);
|
||||
assertThat(mKeyguardUpdateMonitor.mUserFaceAuthenticated.size()).isEqualTo(1);
|
||||
|
||||
mKeyguardUpdateMonitor.handleUserSwitching(10 /* user */, reply);
|
||||
assertThat(mKeyguardUpdateMonitor.mUserFingerprintAuthenticated.size()).isEqualTo(0);
|
||||
assertThat(mKeyguardUpdateMonitor.mUserFaceAuthenticated.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserCanSkipBouncer_whenTrust() {
|
||||
int user = KeyguardUpdateMonitor.getCurrentUser();
|
||||
|
||||
Reference in New Issue
Block a user