Merge "Remove self-maintained timed lockout in MultiBiometricLockoutState" into udc-dev

This commit is contained in:
Hao Dong
2023-04-14 23:44:40 +00:00
committed by Android (Google) Code Review
12 changed files with 214 additions and 131 deletions

View File

@@ -37,13 +37,17 @@ class AuthResultCoordinator {
*/
static final int AUTHENTICATOR_DEFAULT = 0;
/**
* Indicated this authenticator has received a lockout.
* Indicated this authenticator has received a permanent lockout.
*/
static final int AUTHENTICATOR_LOCKED = 1 << 0;
static final int AUTHENTICATOR_PERMANENT_LOCKED = 1 << 0;
/**
* Indicates this authenticator has received a timed unlock.
*/
static final int AUTHENTICATOR_TIMED_LOCKED = 1 << 1;
/**
* Indicates this authenticator has received a successful unlock.
*/
static final int AUTHENTICATOR_UNLOCKED = 1 << 1;
static final int AUTHENTICATOR_UNLOCKED = 1 << 2;
private static final String TAG = "AuthResultCoordinator";
private final Map<Integer, Integer> mAuthenticatorState;
@@ -85,7 +89,14 @@ class AuthResultCoordinator {
* Adds a lock out of a given strength to the current operation list.
*/
void lockedOutFor(@Authenticators.Types int strength) {
updateState(strength, (old) -> AUTHENTICATOR_LOCKED | old);
updateState(strength, (old) -> AUTHENTICATOR_PERMANENT_LOCKED | old);
}
/**
* Adds a timed lock out of a given strength to the current operation list.
*/
void lockOutTimed(@Authenticators.Types int strength) {
updateState(strength, (old) -> AUTHENTICATOR_TIMED_LOCKED | old);
}
/**

View File

@@ -16,21 +16,19 @@
package com.android.server.biometrics.sensors;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_LOCKED;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_PERMANENT_LOCKED;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_TIMED_LOCKED;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_UNLOCKED;
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.os.SystemClock;
import android.util.Pair;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -45,9 +43,7 @@ public class AuthSessionCoordinator implements AuthSessionListener {
private final Set<Integer> mAuthOperations;
private final MultiBiometricLockoutState mMultiBiometricLockoutState;
private final List<Pair<Integer, Long>> mTimedLockouts;
private final RingBuffer mRingBuffer;
private final Clock mClock;
private int mUserId;
private boolean mIsAuthenticating;
@@ -63,8 +59,6 @@ public class AuthSessionCoordinator implements AuthSessionListener {
mAuthResultCoordinator = new AuthResultCoordinator();
mMultiBiometricLockoutState = new MultiBiometricLockoutState(clock);
mRingBuffer = new RingBuffer(100);
mTimedLockouts = new ArrayList<>();
mClock = clock;
}
/**
@@ -74,8 +68,6 @@ public class AuthSessionCoordinator implements AuthSessionListener {
mAuthOperations.clear();
mUserId = userId;
mIsAuthenticating = true;
mAuthOperations.clear();
mTimedLockouts.clear();
mAuthResultCoordinator = new AuthResultCoordinator();
mRingBuffer.addApiCall("internal : onAuthSessionStarted(" + userId + ")");
}
@@ -85,39 +77,30 @@ public class AuthSessionCoordinator implements AuthSessionListener {
*
* This can happen two ways.
* 1. Manually calling this API
* 2. If authStartedFor() was called, and all authentication attempts finish.
* 2. If authStartedFor() was called, and any authentication attempts finish.
*/
void endAuthSession() {
if (mIsAuthenticating) {
final long currentTime = mClock.millis();
for (Pair<Integer, Long> timedLockouts : mTimedLockouts) {
mMultiBiometricLockoutState.increaseLockoutTime(mUserId, timedLockouts.first,
timedLockouts.second + currentTime);
// User unlocks can also unlock timed lockout Authenticator.Types
final Map<Integer, Integer> result = mAuthResultCoordinator.getResult();
for (int authenticator : Arrays.asList(Authenticators.BIOMETRIC_CONVENIENCE,
Authenticators.BIOMETRIC_WEAK, Authenticators.BIOMETRIC_STRONG)) {
final Integer value = result.get(authenticator);
if ((value & AUTHENTICATOR_UNLOCKED) == AUTHENTICATOR_UNLOCKED) {
mMultiBiometricLockoutState.clearPermanentLockOut(mUserId, authenticator);
mMultiBiometricLockoutState.clearTimedLockout(mUserId, authenticator);
} else if ((value & AUTHENTICATOR_PERMANENT_LOCKED) == AUTHENTICATOR_PERMANENT_LOCKED) {
mMultiBiometricLockoutState.setPermanentLockOut(mUserId, authenticator);
} else if ((value & AUTHENTICATOR_TIMED_LOCKED) == AUTHENTICATOR_TIMED_LOCKED) {
mMultiBiometricLockoutState.setTimedLockout(mUserId, authenticator);
}
// User unlocks can also unlock timed lockout Authenticator.Types
final Map<Integer, Integer> result = mAuthResultCoordinator.getResult();
for (int authenticator : Arrays.asList(Authenticators.BIOMETRIC_CONVENIENCE,
Authenticators.BIOMETRIC_WEAK, Authenticators.BIOMETRIC_STRONG)) {
final Integer value = result.get(authenticator);
if ((value & AUTHENTICATOR_UNLOCKED) == AUTHENTICATOR_UNLOCKED) {
mMultiBiometricLockoutState.setAuthenticatorTo(mUserId, authenticator,
true /* canAuthenticate */);
mMultiBiometricLockoutState.clearLockoutTime(mUserId, authenticator);
} else if ((value & AUTHENTICATOR_LOCKED) == AUTHENTICATOR_LOCKED) {
mMultiBiometricLockoutState.setAuthenticatorTo(mUserId, authenticator,
false /* canAuthenticate */);
}
}
mRingBuffer.addApiCall("internal : onAuthSessionEnded(" + mUserId + ")");
clearSession();
}
mRingBuffer.addApiCall("internal : onAuthSessionEnded(" + mUserId + ")");
clearSession();
}
private void clearSession() {
mIsAuthenticating = false;
mTimedLockouts.clear();
mAuthOperations.clear();
}
@@ -171,7 +154,7 @@ public class AuthSessionCoordinator implements AuthSessionListener {
+ ", sensorId=" + sensorId + "time=" + time + ", requestId=" + requestId
+ ")";
mRingBuffer.addApiCall(lockedOutStr);
mTimedLockouts.add(new Pair<>(biometricStrength, time));
mAuthResultCoordinator.lockOutTimed(biometricStrength);
attemptToFinish(userId, sensorId, lockedOutStr);
}
@@ -202,9 +185,8 @@ public class AuthSessionCoordinator implements AuthSessionListener {
// Lockouts cannot be reset by non-strong biometrics
return;
}
mMultiBiometricLockoutState.setAuthenticatorTo(userId, biometricStrength,
true /*canAuthenticate */);
mMultiBiometricLockoutState.clearLockoutTime(userId, biometricStrength);
mMultiBiometricLockoutState.clearPermanentLockOut(userId, biometricStrength);
mMultiBiometricLockoutState.clearTimedLockout(userId, biometricStrength);
}
private void attemptToFinish(int userId, int sensorId, String description) {

View File

@@ -50,10 +50,11 @@ class MultiBiometricLockoutState {
private Map<Integer, AuthenticatorState> createUnlockedMap() {
Map<Integer, AuthenticatorState> lockOutMap = new HashMap<>();
lockOutMap.put(BIOMETRIC_STRONG,
new AuthenticatorState(BIOMETRIC_STRONG, false, 0, mClock));
lockOutMap.put(BIOMETRIC_WEAK, new AuthenticatorState(BIOMETRIC_WEAK, false, 0, mClock));
new AuthenticatorState(BIOMETRIC_STRONG, false, false));
lockOutMap.put(BIOMETRIC_WEAK,
new AuthenticatorState(BIOMETRIC_WEAK, false, false));
lockOutMap.put(BIOMETRIC_CONVENIENCE,
new AuthenticatorState(BIOMETRIC_CONVENIENCE, false, 0, mClock));
new AuthenticatorState(BIOMETRIC_CONVENIENCE, false, false));
return lockOutMap;
}
@@ -64,54 +65,71 @@ class MultiBiometricLockoutState {
return mCanUserAuthenticate.get(userId);
}
void setAuthenticatorTo(int userId, @Authenticators.Types int strength, boolean canAuth) {
void setPermanentLockOut(int userId, @Authenticators.Types int strength) {
final Map<Integer, AuthenticatorState> authMap = getAuthMapForUser(userId);
switch (strength) {
case Authenticators.BIOMETRIC_STRONG:
authMap.get(BIOMETRIC_STRONG).mPermanentlyLockedOut = !canAuth;
authMap.get(BIOMETRIC_STRONG).mPermanentlyLockedOut = true;
// fall through
case Authenticators.BIOMETRIC_WEAK:
authMap.get(BIOMETRIC_WEAK).mPermanentlyLockedOut = !canAuth;
authMap.get(BIOMETRIC_WEAK).mPermanentlyLockedOut = true;
// fall through
case Authenticators.BIOMETRIC_CONVENIENCE:
authMap.get(BIOMETRIC_CONVENIENCE).mPermanentlyLockedOut = !canAuth;
authMap.get(BIOMETRIC_CONVENIENCE).mPermanentlyLockedOut = true;
return;
default:
Slog.e(TAG, "increaseLockoutTime called for invalid strength : " + strength);
}
}
void increaseLockoutTime(int userId, @Authenticators.Types int strength, long duration) {
void clearPermanentLockOut(int userId, @Authenticators.Types int strength) {
final Map<Integer, AuthenticatorState> authMap = getAuthMapForUser(userId);
switch (strength) {
case Authenticators.BIOMETRIC_STRONG:
authMap.get(BIOMETRIC_STRONG).increaseLockoutTo(duration);
authMap.get(BIOMETRIC_STRONG).mPermanentlyLockedOut = false;
// fall through
case Authenticators.BIOMETRIC_WEAK:
authMap.get(BIOMETRIC_WEAK).increaseLockoutTo(duration);
authMap.get(BIOMETRIC_WEAK).mPermanentlyLockedOut = false;
// fall through
case Authenticators.BIOMETRIC_CONVENIENCE:
authMap.get(BIOMETRIC_CONVENIENCE).increaseLockoutTo(duration);
authMap.get(BIOMETRIC_CONVENIENCE).mPermanentlyLockedOut = false;
return;
default:
Slog.e(TAG, "increaseLockoutTime called for invalid strength : " + strength);
}
}
void clearLockoutTime(int userId, @Authenticators.Types int strength) {
void setTimedLockout(int userId, @Authenticators.Types int strength) {
final Map<Integer, AuthenticatorState> authMap = getAuthMapForUser(userId);
switch (strength) {
case Authenticators.BIOMETRIC_STRONG:
authMap.get(BIOMETRIC_STRONG).setTimedLockout(0);
authMap.get(BIOMETRIC_STRONG).mTimedLockout = true;
// fall through
case Authenticators.BIOMETRIC_WEAK:
authMap.get(BIOMETRIC_WEAK).setTimedLockout(0);
authMap.get(BIOMETRIC_WEAK).mTimedLockout = true;
// fall through
case Authenticators.BIOMETRIC_CONVENIENCE:
authMap.get(BIOMETRIC_CONVENIENCE).setTimedLockout(0);
authMap.get(BIOMETRIC_CONVENIENCE).mTimedLockout = true;
return;
default:
Slog.e(TAG, "clearLockoutTime called for invalid strength : " + strength);
Slog.e(TAG, "increaseLockoutTime called for invalid strength : " + strength);
}
}
void clearTimedLockout(int userId, @Authenticators.Types int strength) {
final Map<Integer, AuthenticatorState> authMap = getAuthMapForUser(userId);
switch (strength) {
case Authenticators.BIOMETRIC_STRONG:
authMap.get(BIOMETRIC_STRONG).mTimedLockout = false;
// fall through
case Authenticators.BIOMETRIC_WEAK:
authMap.get(BIOMETRIC_WEAK).mTimedLockout = false;
// fall through
case Authenticators.BIOMETRIC_CONVENIENCE:
authMap.get(BIOMETRIC_CONVENIENCE).mTimedLockout = false;
return;
default:
Slog.e(TAG, "increaseLockoutTime called for invalid strength : " + strength);
}
}
@@ -132,7 +150,7 @@ class MultiBiometricLockoutState {
final AuthenticatorState state = authMap.get(strength);
if (state.mPermanentlyLockedOut) {
return LockoutTracker.LOCKOUT_PERMANENT;
} else if (state.isTimedLockout()) {
} else if (state.mTimedLockout) {
return LockoutTracker.LOCKOUT_TIMED;
} else {
return LockoutTracker.LOCKOUT_NONE;
@@ -158,43 +176,21 @@ class MultiBiometricLockoutState {
private static class AuthenticatorState {
private Integer mAuthenticatorType;
private boolean mPermanentlyLockedOut;
private long mTimedLockout;
private Clock mClock;
private boolean mTimedLockout;
AuthenticatorState(Integer authenticatorId, boolean permanentlyLockedOut,
long timedLockout, Clock clock) {
boolean timedLockout) {
mAuthenticatorType = authenticatorId;
mPermanentlyLockedOut = permanentlyLockedOut;
mTimedLockout = timedLockout;
mClock = clock;
}
boolean canAuthenticate() {
return !mPermanentlyLockedOut && !isTimedLockout();
}
boolean isTimedLockout() {
return mClock.millis() - mTimedLockout < 0;
}
void setTimedLockout(long duration) {
mTimedLockout = duration;
}
/**
* Either increases the lockout to duration, or leaves it as it, whichever is longer.
*/
void increaseLockoutTo(long duration) {
mTimedLockout = Math.max(mTimedLockout, duration);
}
String toString(long currentTime) {
final String duration =
mTimedLockout - currentTime > 0 ? (mTimedLockout - currentTime) + "ms" : "none";
final String timedLockout = mTimedLockout ? "true" : "false";
final String permanentLockout = mPermanentlyLockedOut ? "true" : "false";
return String.format("(%s, permanentLockout=%s, timedLockoutRemaining=%s)",
return String.format("(%s, permanentLockout=%s, timedLockout=%s)",
BiometricManager.authenticatorToStr(mAuthenticatorType), permanentLockout,
duration);
timedLockout);
}
}
}

View File

@@ -28,6 +28,7 @@ import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
import com.android.server.biometrics.sensors.ErrorConsumer;
import com.android.server.biometrics.sensors.HalClientMonitor;
@@ -88,10 +89,9 @@ public class FaceResetLockoutClient extends HalClientMonitor<AidlSession> implem
void onLockoutCleared() {
resetLocalLockoutStateToNone(getSensorId(), getTargetUserId(), mLockoutCache,
mLockoutResetDispatcher);
mLockoutResetDispatcher, getBiometricContext().getAuthSessionCoordinator(),
mBiometricStrength, getRequestId());
mCallback.onClientFinished(this, true /* success */);
getBiometricContext().getAuthSessionCoordinator()
.resetLockoutFor(getTargetUserId(), mBiometricStrength, getRequestId());
}
public boolean interruptsPrecedingClients() {
@@ -108,7 +108,10 @@ public class FaceResetLockoutClient extends HalClientMonitor<AidlSession> implem
*/
static void resetLocalLockoutStateToNone(int sensorId, int userId,
@NonNull LockoutCache lockoutTracker,
@NonNull LockoutResetDispatcher lockoutResetDispatcher) {
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull AuthSessionCoordinator authSessionCoordinator,
@Authenticators.Types int biometricStrength, long requestId) {
authSessionCoordinator.resetLockoutFor(userId, biometricStrength, requestId);
lockoutTracker.setLockoutModeForUser(userId, LockoutTracker.LOCKOUT_NONE);
lockoutResetDispatcher.notifyLockoutResetCallbacks(sensorId);
}

View File

@@ -54,6 +54,7 @@ import com.android.server.biometrics.UserStateProto;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
@@ -127,6 +128,9 @@ public class Sensor {
private final LockoutCache mLockoutCache;
@NonNull
private final LockoutResetDispatcher mLockoutResetDispatcher;
@NonNull
private AuthSessionCoordinator mAuthSessionCoordinator;
@NonNull
private final Callback mCallback;
@@ -134,6 +138,7 @@ public class Sensor {
@NonNull UserAwareBiometricScheduler scheduler, int sensorId, int userId,
@NonNull LockoutCache lockoutTracker,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull AuthSessionCoordinator authSessionCoordinator,
@NonNull Callback callback) {
mContext = context;
mHandler = handler;
@@ -143,6 +148,7 @@ public class Sensor {
mUserId = userId;
mLockoutCache = lockoutTracker;
mLockoutResetDispatcher = lockoutResetDispatcher;
mAuthSessionCoordinator = authSessionCoordinator;
mCallback = callback;
}
@@ -346,8 +352,12 @@ public class Sensor {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof FaceResetLockoutClient)) {
Slog.d(mTag, "onLockoutCleared outside of resetLockout by HAL");
// Given that onLockoutCleared() can happen at any time, and is not necessarily
// coming from a specific client, set this to -1 to indicate it wasn't for a
// specific request.
FaceResetLockoutClient.resetLocalLockoutStateToNone(mSensorId, mUserId,
mLockoutCache, mLockoutResetDispatcher);
mLockoutCache, mLockoutResetDispatcher, mAuthSessionCoordinator,
Utils.getCurrentStrength(mSensorId), -1 /* requestId */);
} else {
Slog.d(mTag, "onLockoutCleared after resetLockout");
final FaceResetLockoutClient resetLockoutClient =
@@ -514,7 +524,8 @@ public class Sensor {
final HalSessionCallback resultController = new HalSessionCallback(mContext,
mHandler, mTag, mScheduler, sensorId, newUserId, mLockoutCache,
lockoutResetDispatcher, () -> {
lockoutResetDispatcher,
biometricContext.getAuthSessionCoordinator(), () -> {
Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE");
mCurrentSession = null;
});

View File

@@ -28,6 +28,7 @@ import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
import com.android.server.biometrics.sensors.ErrorConsumer;
import com.android.server.biometrics.sensors.HalClientMonitor;
@@ -92,10 +93,9 @@ class FingerprintResetLockoutClient extends HalClientMonitor<AidlSession> implem
void onLockoutCleared() {
resetLocalLockoutStateToNone(getSensorId(), getTargetUserId(), mLockoutCache,
mLockoutResetDispatcher);
mLockoutResetDispatcher, getBiometricContext().getAuthSessionCoordinator(),
mBiometricStrength, getRequestId());
mCallback.onClientFinished(this, true /* success */);
getBiometricContext().getAuthSessionCoordinator()
.resetLockoutFor(getTargetUserId(), mBiometricStrength, getRequestId());
}
/**
@@ -108,9 +108,12 @@ class FingerprintResetLockoutClient extends HalClientMonitor<AidlSession> implem
*/
static void resetLocalLockoutStateToNone(int sensorId, int userId,
@NonNull LockoutCache lockoutTracker,
@NonNull LockoutResetDispatcher lockoutResetDispatcher) {
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull AuthSessionCoordinator authSessionCoordinator,
@Authenticators.Types int biometricStrength, long requestId) {
lockoutTracker.setLockoutModeForUser(userId, LockoutTracker.LOCKOUT_NONE);
lockoutResetDispatcher.notifyLockoutResetCallbacks(sensorId);
authSessionCoordinator.resetLockoutFor(userId, biometricStrength, requestId);
}
@Override

View File

@@ -52,6 +52,7 @@ import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
@@ -131,12 +132,15 @@ public class Sensor {
@NonNull
private final LockoutResetDispatcher mLockoutResetDispatcher;
@NonNull
private AuthSessionCoordinator mAuthSessionCoordinator;
@NonNull
private final Callback mCallback;
HalSessionCallback(@NonNull Context context, @NonNull Handler handler, @NonNull String tag,
@NonNull UserAwareBiometricScheduler scheduler, int sensorId, int userId,
@NonNull LockoutCache lockoutTracker,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull AuthSessionCoordinator authSessionCoordinator,
@NonNull Callback callback) {
mContext = context;
mHandler = handler;
@@ -146,6 +150,7 @@ public class Sensor {
mUserId = userId;
mLockoutCache = lockoutTracker;
mLockoutResetDispatcher = lockoutResetDispatcher;
mAuthSessionCoordinator = authSessionCoordinator;
mCallback = callback;
}
@@ -327,8 +332,12 @@ public class Sensor {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof FingerprintResetLockoutClient)) {
Slog.d(mTag, "onLockoutCleared outside of resetLockout by HAL");
// Given that onLockoutCleared() can happen at any time, and is not necessarily
// coming from a specific client, set this to -1 to indicate it wasn't for a
// specific request.
FingerprintResetLockoutClient.resetLocalLockoutStateToNone(mSensorId, mUserId,
mLockoutCache, mLockoutResetDispatcher);
mLockoutCache, mLockoutResetDispatcher, mAuthSessionCoordinator,
Utils.getCurrentStrength(mSensorId), -1 /* requestId */);
} else {
Slog.d(mTag, "onLockoutCleared after resetLockout");
final FingerprintResetLockoutClient resetLockoutClient =
@@ -470,7 +479,8 @@ public class Sensor {
final HalSessionCallback resultController = new HalSessionCallback(mContext,
mHandler, mTag, mScheduler, sensorId, newUserId, mLockoutCache,
lockoutResetDispatcher, () -> {
lockoutResetDispatcher,
biometricContext.getAuthSessionCoordinator(), () -> {
Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE");
mCurrentSession = null;
});

View File

@@ -17,7 +17,8 @@
package com.android.server.biometrics.sensors;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_DEFAULT;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_LOCKED;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_PERMANENT_LOCKED;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_TIMED_LOCKED;
import static com.android.server.biometrics.sensors.AuthResultCoordinator.AUTHENTICATOR_UNLOCKED;
import static com.google.common.truth.Truth.assertThat;
@@ -76,7 +77,22 @@ public class AuthResultCoordinatorTest {
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
AUTHENTICATOR_DEFAULT);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
AUTHENTICATOR_LOCKED);
AUTHENTICATOR_PERMANENT_LOCKED);
}
@Test
public void testConvenientLockoutTimed() {
mAuthResultCoordinator.lockOutTimed(
BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE);
final Map<Integer, Integer> authMap = mAuthResultCoordinator.getResult();
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
AUTHENTICATOR_DEFAULT);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
AUTHENTICATOR_DEFAULT);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
AUTHENTICATOR_TIMED_LOCKED);
}
@Test
@@ -97,16 +113,31 @@ public class AuthResultCoordinatorTest {
@Test
public void testWeakLockout() {
mAuthResultCoordinator.lockedOutFor(
BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE);
BiometricManager.Authenticators.BIOMETRIC_WEAK);
Map<Integer, Integer> authMap = mAuthResultCoordinator.getResult();
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
AUTHENTICATOR_DEFAULT);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
AUTHENTICATOR_DEFAULT);
AUTHENTICATOR_PERMANENT_LOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
AUTHENTICATOR_LOCKED);
AUTHENTICATOR_PERMANENT_LOCKED);
}
@Test
public void testWeakLockoutTimed() {
mAuthResultCoordinator.lockOutTimed(
BiometricManager.Authenticators.BIOMETRIC_WEAK);
Map<Integer, Integer> authMap = mAuthResultCoordinator.getResult();
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
AUTHENTICATOR_DEFAULT);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
AUTHENTICATOR_TIMED_LOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
AUTHENTICATOR_TIMED_LOCKED);
}
@Test
@@ -132,13 +163,27 @@ public class AuthResultCoordinatorTest {
Map<Integer, Integer> authMap = mAuthResultCoordinator.getResult();
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
AUTHENTICATOR_LOCKED);
AUTHENTICATOR_PERMANENT_LOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
AUTHENTICATOR_LOCKED);
AUTHENTICATOR_PERMANENT_LOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
AUTHENTICATOR_LOCKED);
AUTHENTICATOR_PERMANENT_LOCKED);
}
@Test
public void testStrongLockoutTimed() {
mAuthResultCoordinator.lockOutTimed(
BiometricManager.Authenticators.BIOMETRIC_STRONG);
Map<Integer, Integer> authMap = mAuthResultCoordinator.getResult();
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
AUTHENTICATOR_TIMED_LOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
AUTHENTICATOR_TIMED_LOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
AUTHENTICATOR_TIMED_LOCKED);
}
@Test
public void testStrongUnlock() {
@@ -167,10 +212,30 @@ public class AuthResultCoordinatorTest {
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
AUTHENTICATOR_DEFAULT);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
AUTHENTICATOR_LOCKED);
AUTHENTICATOR_PERMANENT_LOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
AUTHENTICATOR_LOCKED);
AUTHENTICATOR_PERMANENT_LOCKED);
}
@Test
public void testLockoutAndAuth() {
mAuthResultCoordinator.lockedOutFor(
BiometricManager.Authenticators.BIOMETRIC_WEAK);
mAuthResultCoordinator.authenticatedFor(
BiometricManager.Authenticators.BIOMETRIC_STRONG);
final Map<Integer, Integer> authMap = mAuthResultCoordinator.getResult();
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)
& AUTHENTICATOR_UNLOCKED).isEqualTo(
AUTHENTICATOR_UNLOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)
& AUTHENTICATOR_UNLOCKED).isEqualTo(
AUTHENTICATOR_UNLOCKED);
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)
& AUTHENTICATOR_UNLOCKED).isEqualTo(
AUTHENTICATOR_UNLOCKED);
}
}

View File

@@ -154,7 +154,7 @@ public class AuthSessionCoordinatorTest {
LockoutTracker.LOCKOUT_NONE);
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
}
@@ -194,7 +194,7 @@ public class AuthSessionCoordinatorTest {
LockoutTracker.LOCKOUT_NONE);
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(

View File

@@ -49,7 +49,7 @@ public class MultiBiometricLockoutStateTest {
private Clock mClock;
private static void unlockAllBiometrics(MultiBiometricLockoutState lockoutState, int userId) {
lockoutState.setAuthenticatorTo(userId, BIOMETRIC_STRONG, true /* canAuthenticate */);
lockoutState.clearPermanentLockOut(userId, BIOMETRIC_STRONG);
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_WEAK)).isEqualTo(
@@ -59,7 +59,7 @@ public class MultiBiometricLockoutStateTest {
}
private static void lockoutAllBiometrics(MultiBiometricLockoutState lockoutState, int userId) {
lockoutState.setAuthenticatorTo(userId, BIOMETRIC_STRONG, false /* canAuthenticate */);
lockoutState.setPermanentLockOut(userId, BIOMETRIC_STRONG);
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_PERMANENT);
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_WEAK)).isEqualTo(
@@ -96,8 +96,7 @@ public class MultiBiometricLockoutStateTest {
@Test
public void testConvenienceLockout() {
unlockAllBiometrics();
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_CONVENIENCE,
false /* canAuthenticate */);
mLockoutState.setPermanentLockOut(PRIMARY_USER, BIOMETRIC_CONVENIENCE);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -110,7 +109,7 @@ public class MultiBiometricLockoutStateTest {
@Test
public void testWeakLockout() {
unlockAllBiometrics();
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_WEAK, false /* canAuthenticate */);
mLockoutState.setPermanentLockOut(PRIMARY_USER, BIOMETRIC_WEAK);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -123,8 +122,7 @@ public class MultiBiometricLockoutStateTest {
@Test
public void testStrongLockout() {
lockoutAllBiometrics();
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_STRONG,
false /* canAuthenticate */);
mLockoutState.setPermanentLockOut(PRIMARY_USER, BIOMETRIC_STRONG);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_PERMANENT);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -137,8 +135,7 @@ public class MultiBiometricLockoutStateTest {
@Test
public void testConvenienceUnlock() {
lockoutAllBiometrics();
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_CONVENIENCE,
true /* canAuthenticate */);
mLockoutState.clearPermanentLockOut(PRIMARY_USER, BIOMETRIC_CONVENIENCE);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_PERMANENT);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -150,7 +147,7 @@ public class MultiBiometricLockoutStateTest {
@Test
public void testWeakUnlock() {
lockoutAllBiometrics();
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_WEAK, true /* canAuthenticate */);
mLockoutState.clearPermanentLockOut(PRIMARY_USER, BIOMETRIC_WEAK);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_PERMANENT);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -162,8 +159,7 @@ public class MultiBiometricLockoutStateTest {
@Test
public void testStrongUnlock() {
lockoutAllBiometrics();
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_STRONG,
true /* canAuthenticate */);
mLockoutState.clearPermanentLockOut(PRIMARY_USER, BIOMETRIC_STRONG);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -180,7 +176,7 @@ public class MultiBiometricLockoutStateTest {
lockoutAllBiometrics(lockoutState, userOne);
lockoutAllBiometrics(lockoutState, userTwo);
lockoutState.setAuthenticatorTo(userOne, BIOMETRIC_WEAK, true /* canAuthenticate */);
lockoutState.clearPermanentLockOut(userOne, BIOMETRIC_WEAK);
assertThat(lockoutState.getLockoutState(userOne, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_PERMANENT);
assertThat(lockoutState.getLockoutState(userOne, BIOMETRIC_WEAK)).isEqualTo(
@@ -205,8 +201,7 @@ public class MultiBiometricLockoutStateTest {
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
mLockoutState.increaseLockoutTime(PRIMARY_USER, BIOMETRIC_STRONG,
System.currentTimeMillis() + 1);
mLockoutState.setTimedLockout(PRIMARY_USER, BIOMETRIC_STRONG);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_TIMED);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -225,8 +220,7 @@ public class MultiBiometricLockoutStateTest {
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
when(mClock.millis()).thenReturn(0L);
mLockoutState.increaseLockoutTime(PRIMARY_USER, BIOMETRIC_STRONG, 1);
mLockoutState.setTimedLockout(PRIMARY_USER, BIOMETRIC_STRONG);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_TIMED);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
@@ -235,7 +229,7 @@ public class MultiBiometricLockoutStateTest {
mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
LockoutTracker.LOCKOUT_TIMED);
when(mClock.millis()).thenReturn(2L);
mLockoutState.clearTimedLockout(PRIMARY_USER, BIOMETRIC_STRONG);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
LockoutTracker.LOCKOUT_NONE);
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(

View File

@@ -19,6 +19,8 @@ package com.android.server.biometrics.sensors.face.aidl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
@@ -109,7 +111,8 @@ public class SensorTest {
mUserSwitchCallback);
mHalCallback = new Sensor.HalSessionCallback(mContext, new Handler(mLooper.getLooper()),
TAG, mScheduler, SENSOR_ID,
USER_ID, mLockoutCache, mLockoutResetDispatcher, mHalSessionCallback);
USER_ID, mLockoutCache, mLockoutResetDispatcher, mAuthSessionCoordinator,
mHalSessionCallback);
final SensorProps sensor1 = new SensorProps();
sensor1.commonProps = new CommonProps();
@@ -164,5 +167,6 @@ public class SensorTest {
private void verifyNotLocked() {
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
verify(mAuthSessionCoordinator).resetLockoutFor(eq(USER_ID), anyInt(), anyLong());
}
}

View File

@@ -18,6 +18,8 @@ package com.android.server.biometrics.sensors.fingerprint.aidl;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
@@ -97,7 +99,8 @@ public class SensorTest {
mUserSwitchCallback);
mHalCallback = new Sensor.HalSessionCallback(mContext, new Handler(mLooper.getLooper()),
TAG, mScheduler, SENSOR_ID,
USER_ID, mLockoutCache, mLockoutResetDispatcher, mHalSessionCallback);
USER_ID, mLockoutCache, mLockoutResetDispatcher, mAuthSessionCoordinator,
mHalSessionCallback);
}
@Test
@@ -130,5 +133,6 @@ public class SensorTest {
private void verifyNotLocked() {
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
verify(mAuthSessionCoordinator).resetLockoutFor(eq(USER_ID), anyInt(), anyLong());
}
}