Enabled multibiometric lockout for aidl hals
Test: atest com.android.server.biometrics Test: atest com.android.server.locksettings Test: tested on hidl fingerprint device Test: tested on hidl face device Test: tested on aidl fingerprint/face device with various different combinations of strengths. The device tested consisted of: * Locking out device in keyguard, resetting, ensuring it works as expected * Locking out device in biometric prompt, resetting, ensuring it works as expected for work profile & default profile. Bug: 244355277 Change-Id: I849dfc13da17a49ec9b20fa58390707e1f8109ab
This commit is contained in:
committed by
Joshua Mccloskey
parent
c04a673604
commit
a3967d8a7d
@@ -639,5 +639,24 @@ public class BiometricManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies AuthService that keyguard has been dismissed for the given userId.
|
||||
*
|
||||
* @param userId
|
||||
* @param hardwareAuthToken
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public void resetLockout(int userId, byte[] hardwareAuthToken) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.resetLockout(userId, hardwareAuthToken);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,4 +73,5 @@ public abstract class BiometricStateListener extends IBiometricStateListener.Stu
|
||||
*/
|
||||
public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,6 +79,9 @@ interface IAuthService {
|
||||
void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, int userId,
|
||||
in byte[] hardwareAuthToken);
|
||||
|
||||
// See documentation in BiometricManager.
|
||||
void resetLockout(int userId, in byte[] hardwareAuthToken);
|
||||
|
||||
// Provides a localized string that may be used as the label for a button that invokes
|
||||
// BiometricPrompt.
|
||||
CharSequence getButtonLabel(int userId, String opPackageName, int authenticators);
|
||||
|
||||
@@ -91,6 +91,10 @@ interface IBiometricService {
|
||||
void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, int userId,
|
||||
in byte[] hardwareAuthToken);
|
||||
|
||||
// See documentation in BiometricManager.
|
||||
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
|
||||
void resetLockout(int userId, in byte[] hardwareAuthToken);
|
||||
|
||||
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
|
||||
int getCurrentStrength(int sensorId);
|
||||
|
||||
|
||||
@@ -409,6 +409,17 @@ public class AuthService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLockout(int userId, byte[] hardwareAuthToken) throws RemoteException {
|
||||
checkInternalPermission();
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.resetLockout(userId, hardwareAuthToken);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getButtonLabel(
|
||||
int userId,
|
||||
|
||||
@@ -72,6 +72,7 @@ import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -100,6 +101,7 @@ public class BiometricService extends SystemService {
|
||||
private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
|
||||
private final Random mRandom = new Random();
|
||||
@NonNull private final Supplier<Long> mRequestCounter;
|
||||
@NonNull private final BiometricContext mBiometricContext;
|
||||
|
||||
@VisibleForTesting
|
||||
IStatusBarService mStatusBarService;
|
||||
@@ -774,6 +776,16 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
@Override // Binder call
|
||||
public void resetLockout(
|
||||
int userId, byte[] hardwareAuthToken) {
|
||||
Slog.d(TAG, "resetLockout(userId=" + userId
|
||||
+ ", hat=" + (hardwareAuthToken == null ? "null " : "present") + ")");
|
||||
mBiometricContext.getAuthSessionCoordinator()
|
||||
.resetLockoutFor(userId, Authenticators.BIOMETRIC_STRONG, -1);
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
@Override // Binder call
|
||||
public int getCurrentStrength(int sensorId) {
|
||||
@@ -984,6 +996,10 @@ public class BiometricService extends SystemService {
|
||||
final AtomicLong generator = new AtomicLong(0);
|
||||
return () -> generator.incrementAndGet();
|
||||
}
|
||||
|
||||
public BiometricContext getBiometricContext(Context context) {
|
||||
return BiometricContext.getInstance(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,6 +1026,7 @@ public class BiometricService extends SystemService {
|
||||
mSettingObserver = mInjector.getSettingObserver(context, mHandler,
|
||||
mEnabledOnKeyguardCallbacks);
|
||||
mRequestCounter = mInjector.getRequestGenerator();
|
||||
mBiometricContext = injector.getBiometricContext(context);
|
||||
|
||||
try {
|
||||
injector.getActivityManagerService().registerUserSwitchObserver(
|
||||
|
||||
@@ -48,8 +48,6 @@ import java.util.List;
|
||||
* the PreAuthInfo should not change any sensor state.
|
||||
*/
|
||||
class PreAuthInfo {
|
||||
private static final String TAG = "BiometricService/PreAuthInfo";
|
||||
|
||||
static final int AUTHENTICATOR_OK = 1;
|
||||
static final int BIOMETRIC_NO_HARDWARE = 2;
|
||||
static final int BIOMETRIC_DISABLED_BY_DEVICE_POLICY = 3;
|
||||
@@ -62,24 +60,7 @@ class PreAuthInfo {
|
||||
static final int BIOMETRIC_LOCKOUT_TIMED = 10;
|
||||
static final int BIOMETRIC_LOCKOUT_PERMANENT = 11;
|
||||
static final int BIOMETRIC_SENSOR_PRIVACY_ENABLED = 12;
|
||||
@IntDef({AUTHENTICATOR_OK,
|
||||
BIOMETRIC_NO_HARDWARE,
|
||||
BIOMETRIC_DISABLED_BY_DEVICE_POLICY,
|
||||
BIOMETRIC_INSUFFICIENT_STRENGTH,
|
||||
BIOMETRIC_INSUFFICIENT_STRENGTH_AFTER_DOWNGRADE,
|
||||
BIOMETRIC_HARDWARE_NOT_DETECTED,
|
||||
BIOMETRIC_NOT_ENROLLED,
|
||||
BIOMETRIC_NOT_ENABLED_FOR_APPS,
|
||||
CREDENTIAL_NOT_ENROLLED,
|
||||
BIOMETRIC_LOCKOUT_TIMED,
|
||||
BIOMETRIC_LOCKOUT_PERMANENT,
|
||||
BIOMETRIC_SENSOR_PRIVACY_ENABLED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface AuthenticatorStatus {}
|
||||
|
||||
private final boolean mBiometricRequested;
|
||||
private final int mBiometricStrengthRequested;
|
||||
|
||||
private static final String TAG = "BiometricService/PreAuthInfo";
|
||||
final boolean credentialRequested;
|
||||
// Sensors that can be used for this request (e.g. strong enough, enrolled, enabled).
|
||||
final List<BiometricSensor> eligibleSensors;
|
||||
@@ -90,6 +71,25 @@ class PreAuthInfo {
|
||||
final boolean ignoreEnrollmentState;
|
||||
final int userId;
|
||||
final Context context;
|
||||
private final boolean mBiometricRequested;
|
||||
private final int mBiometricStrengthRequested;
|
||||
private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested,
|
||||
boolean credentialRequested, List<BiometricSensor> eligibleSensors,
|
||||
List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable,
|
||||
boolean confirmationRequested, boolean ignoreEnrollmentState, int userId,
|
||||
Context context) {
|
||||
mBiometricRequested = biometricRequested;
|
||||
mBiometricStrengthRequested = biometricStrengthRequested;
|
||||
this.credentialRequested = credentialRequested;
|
||||
|
||||
this.eligibleSensors = eligibleSensors;
|
||||
this.ineligibleSensors = ineligibleSensors;
|
||||
this.credentialAvailable = credentialAvailable;
|
||||
this.confirmationRequested = confirmationRequested;
|
||||
this.ignoreEnrollmentState = ignoreEnrollmentState;
|
||||
this.userId = userId;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
static PreAuthInfo create(ITrustManager trustManager,
|
||||
DevicePolicyManager devicePolicyManager,
|
||||
@@ -158,7 +158,8 @@ class PreAuthInfo {
|
||||
*
|
||||
* @return @AuthenticatorStatus
|
||||
*/
|
||||
private static @AuthenticatorStatus int getStatusForBiometricAuthenticator(
|
||||
private static @AuthenticatorStatus
|
||||
int getStatusForBiometricAuthenticator(
|
||||
DevicePolicyManager devicePolicyManager,
|
||||
BiometricService.SettingObserver settingObserver,
|
||||
BiometricSensor sensor, int userId, String opPackageName,
|
||||
@@ -200,7 +201,6 @@ class PreAuthInfo {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final @LockoutTracker.LockoutMode int lockoutMode =
|
||||
sensor.impl.getLockoutModeForUser(userId);
|
||||
if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
|
||||
@@ -248,8 +248,8 @@ class PreAuthInfo {
|
||||
|
||||
/**
|
||||
* @param modality one of {@link BiometricAuthenticator#TYPE_FINGERPRINT},
|
||||
* {@link BiometricAuthenticator#TYPE_IRIS} or {@link BiometricAuthenticator#TYPE_FACE}
|
||||
* @return
|
||||
* {@link BiometricAuthenticator#TYPE_IRIS} or
|
||||
* {@link BiometricAuthenticator#TYPE_FACE}
|
||||
*/
|
||||
private static int mapModalityToDevicePolicyType(int modality) {
|
||||
switch (modality) {
|
||||
@@ -265,24 +265,6 @@ class PreAuthInfo {
|
||||
}
|
||||
}
|
||||
|
||||
private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested,
|
||||
boolean credentialRequested, List<BiometricSensor> eligibleSensors,
|
||||
List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable,
|
||||
boolean confirmationRequested, boolean ignoreEnrollmentState, int userId,
|
||||
Context context) {
|
||||
mBiometricRequested = biometricRequested;
|
||||
mBiometricStrengthRequested = biometricStrengthRequested;
|
||||
this.credentialRequested = credentialRequested;
|
||||
|
||||
this.eligibleSensors = eligibleSensors;
|
||||
this.ineligibleSensors = ineligibleSensors;
|
||||
this.credentialAvailable = credentialAvailable;
|
||||
this.confirmationRequested = confirmationRequested;
|
||||
this.ignoreEnrollmentState = ignoreEnrollmentState;
|
||||
this.userId = userId;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private Pair<BiometricSensor, Integer> calculateErrorByPriority() {
|
||||
// If the caller requested STRONG, and the device contains both STRONG and non-STRONG
|
||||
// sensors, prioritize BIOMETRIC_NOT_ENROLLED over the weak sensor's
|
||||
@@ -303,6 +285,7 @@ class PreAuthInfo {
|
||||
* surface, combined with the actual sensor/credential and user/system settings, calculate the
|
||||
* internal {@link AuthenticatorStatus} that should be returned to the client. Note that this
|
||||
* will need to be converted into the public API constant.
|
||||
*
|
||||
* @return Pair<Modality, Error> with error being the internal {@link AuthenticatorStatus} code
|
||||
*/
|
||||
private Pair<Integer, Integer> getInternalStatus() {
|
||||
@@ -391,7 +374,8 @@ class PreAuthInfo {
|
||||
/**
|
||||
* @return public BiometricManager result for the current request.
|
||||
*/
|
||||
@BiometricManager.BiometricError int getCanAuthenticateResult() {
|
||||
@BiometricManager.BiometricError
|
||||
int getCanAuthenticateResult() {
|
||||
// TODO: Convert this directly
|
||||
return Utils.biometricConstantsToBiometricManager(
|
||||
Utils.authenticatorStatusToBiometricConstant(
|
||||
@@ -401,6 +385,7 @@ class PreAuthInfo {
|
||||
/**
|
||||
* For the given request, generate the appropriate reason why authentication cannot be started.
|
||||
* Note that for some errors, modality is intentionally cleared.
|
||||
*
|
||||
* @return Pair<Modality, Error> with modality being filtered if necessary, and error
|
||||
* being one of the public {@link android.hardware.biometrics.BiometricConstants} codes.
|
||||
*/
|
||||
@@ -443,7 +428,8 @@ class PreAuthInfo {
|
||||
* @return bitmask representing the modalities that are running or could be running for the
|
||||
* current session.
|
||||
*/
|
||||
@BiometricAuthenticator.Modality int getEligibleModalities() {
|
||||
@BiometricAuthenticator.Modality
|
||||
int getEligibleModalities() {
|
||||
@BiometricAuthenticator.Modality int modalities = 0;
|
||||
for (BiometricSensor sensor : eligibleSensors) {
|
||||
modalities |= sensor.modality;
|
||||
@@ -474,7 +460,7 @@ class PreAuthInfo {
|
||||
+ ", StrengthRequested: " + mBiometricStrengthRequested
|
||||
+ ", CredentialRequested: " + credentialRequested);
|
||||
string.append(", Eligible:{");
|
||||
for (BiometricSensor sensor: eligibleSensors) {
|
||||
for (BiometricSensor sensor : eligibleSensors) {
|
||||
string.append(sensor.id).append(" ");
|
||||
}
|
||||
string.append("}");
|
||||
@@ -489,4 +475,20 @@ class PreAuthInfo {
|
||||
string.append(", ");
|
||||
return string.toString();
|
||||
}
|
||||
|
||||
@IntDef({AUTHENTICATOR_OK,
|
||||
BIOMETRIC_NO_HARDWARE,
|
||||
BIOMETRIC_DISABLED_BY_DEVICE_POLICY,
|
||||
BIOMETRIC_INSUFFICIENT_STRENGTH,
|
||||
BIOMETRIC_INSUFFICIENT_STRENGTH_AFTER_DOWNGRADE,
|
||||
BIOMETRIC_HARDWARE_NOT_DETECTED,
|
||||
BIOMETRIC_NOT_ENROLLED,
|
||||
BIOMETRIC_NOT_ENABLED_FOR_APPS,
|
||||
CREDENTIAL_NOT_ENROLLED,
|
||||
BIOMETRIC_LOCKOUT_TIMED,
|
||||
BIOMETRIC_LOCKOUT_PERMANENT,
|
||||
BIOMETRIC_SENSOR_PRIVACY_ENABLED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface AuthenticatorStatus {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import java.util.function.Consumer;
|
||||
/**
|
||||
* A default provider for {@link BiometricContext}.
|
||||
*/
|
||||
final class BiometricContextProvider implements BiometricContext {
|
||||
public final class BiometricContextProvider implements BiometricContext {
|
||||
|
||||
private static final String TAG = "BiometricContextProvider";
|
||||
|
||||
@@ -83,7 +83,8 @@ final class BiometricContextProvider implements BiometricContext {
|
||||
private boolean mIsAwake = false;
|
||||
|
||||
@VisibleForTesting
|
||||
BiometricContextProvider(@NonNull AmbientDisplayConfiguration ambientDisplayConfiguration,
|
||||
public BiometricContextProvider(
|
||||
@NonNull AmbientDisplayConfiguration ambientDisplayConfiguration,
|
||||
@NonNull IStatusBarService service, @Nullable Handler handler,
|
||||
AuthSessionCoordinator authSessionCoordinator) {
|
||||
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
|
||||
|
||||
@@ -75,7 +75,10 @@ class AuthResultCoordinator {
|
||||
* Adds auth success for a given strength to the current operation list.
|
||||
*/
|
||||
void authenticatedFor(@Authenticators.Types int strength) {
|
||||
updateState(strength, (old) -> AUTHENTICATOR_UNLOCKED | old);
|
||||
// Only strong unlocks matter.
|
||||
if (strength == Authenticators.BIOMETRIC_STRONG) {
|
||||
updateState(strength, (old) -> AUTHENTICATOR_UNLOCKED | old);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,6 +75,7 @@ public class AuthSessionCoordinator implements AuthSessionListener {
|
||||
mUserId = userId;
|
||||
mIsAuthenticating = true;
|
||||
mAuthOperations.clear();
|
||||
mTimedLockouts.clear();
|
||||
mAuthResultCoordinator = new AuthResultCoordinator();
|
||||
mRingBuffer.addApiCall("internal : onAuthSessionStarted(" + userId + ")");
|
||||
}
|
||||
@@ -88,7 +89,6 @@ public class AuthSessionCoordinator implements AuthSessionListener {
|
||||
*/
|
||||
void endAuthSession() {
|
||||
if (mIsAuthenticating) {
|
||||
mAuthOperations.clear();
|
||||
final long currentTime = mClock.millis();
|
||||
for (Pair<Integer, Long> timedLockouts : mTimedLockouts) {
|
||||
mMultiBiometricLockoutState.increaseLockoutTime(mUserId, timedLockouts.first,
|
||||
@@ -109,16 +109,24 @@ public class AuthSessionCoordinator implements AuthSessionListener {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mRingBuffer.addApiCall("internal : onAuthSessionEnded(" + mUserId + ")");
|
||||
mIsAuthenticating = false;
|
||||
clearSession();
|
||||
}
|
||||
}
|
||||
|
||||
private void clearSession() {
|
||||
mIsAuthenticating = false;
|
||||
mTimedLockouts.clear();
|
||||
mAuthOperations.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if a user can authenticate with a given strength.
|
||||
* Returns the current lockout state for a given user/strength.
|
||||
*/
|
||||
public boolean getCanAuthFor(int userId, @Authenticators.Types int strength) {
|
||||
return mMultiBiometricLockoutState.canUserAuthenticate(userId, strength);
|
||||
@LockoutTracker.LockoutMode
|
||||
public int getLockoutStateFor(int userId, @Authenticators.Types int strength) {
|
||||
return mMultiBiometricLockoutState.getLockoutState(userId, strength);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,19 +153,8 @@ public class AuthSessionCoordinator implements AuthSessionListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authenticatedFor(int userId, @Authenticators.Types int biometricStrength,
|
||||
int sensorId, long requestId) {
|
||||
final String authStr =
|
||||
"authenticatedFor(userId=" + userId + ", strength=" + biometricStrength
|
||||
+ " , sensorId=" + sensorId + ", requestId= " + requestId + ")";
|
||||
mRingBuffer.addApiCall(authStr);
|
||||
mAuthResultCoordinator.authenticatedFor(biometricStrength);
|
||||
attemptToFinish(userId, sensorId, authStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockedOutFor(int userId, @Authenticators.Types int biometricStrength,
|
||||
int sensorId, long requestId) {
|
||||
public void lockedOutFor(int userId, @Authenticators.Types int biometricStrength, int sensorId,
|
||||
long requestId) {
|
||||
final String lockedOutStr =
|
||||
"lockOutFor(userId=" + userId + ", biometricStrength=" + biometricStrength
|
||||
+ ", sensorId=" + sensorId + ", requestId=" + requestId + ")";
|
||||
@@ -179,12 +176,16 @@ public class AuthSessionCoordinator implements AuthSessionListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authEndedFor(int userId, @Authenticators.Types int biometricStrength,
|
||||
int sensorId, long requestId) {
|
||||
public void authEndedFor(int userId, @Authenticators.Types int biometricStrength, int sensorId,
|
||||
long requestId, boolean wasSuccessful) {
|
||||
final String authEndedStr =
|
||||
"authEndedFor(userId=" + userId + " ,biometricStrength=" + biometricStrength
|
||||
+ ", sensorId=" + sensorId + ", requestId=" + requestId + ")";
|
||||
+ ", sensorId=" + sensorId + ", requestId=" + requestId + ", wasSuccessful="
|
||||
+ wasSuccessful + ")";
|
||||
mRingBuffer.addApiCall(authEndedStr);
|
||||
if (wasSuccessful) {
|
||||
mAuthResultCoordinator.authenticatedFor(biometricStrength);
|
||||
}
|
||||
attemptToFinish(userId, sensorId, authEndedStr);
|
||||
}
|
||||
|
||||
@@ -195,6 +196,12 @@ public class AuthSessionCoordinator implements AuthSessionListener {
|
||||
"resetLockoutFor(userId=" + userId + " ,biometricStrength=" + biometricStrength
|
||||
+ ", requestId=" + requestId + ")";
|
||||
mRingBuffer.addApiCall(resetLockStr);
|
||||
if (biometricStrength == Authenticators.BIOMETRIC_STRONG) {
|
||||
clearSession();
|
||||
} else {
|
||||
// Lockouts cannot be reset by non-strong biometrics
|
||||
return;
|
||||
}
|
||||
mMultiBiometricLockoutState.setAuthenticatorTo(userId, biometricStrength,
|
||||
true /*canAuthenticate */);
|
||||
mMultiBiometricLockoutState.clearLockoutTime(userId, biometricStrength);
|
||||
|
||||
@@ -27,17 +27,11 @@ interface AuthSessionListener {
|
||||
*/
|
||||
void authStartedFor(int userId, int sensorId, long requestId);
|
||||
|
||||
/**
|
||||
* Indicates a successful authentication occurred for a sensor of a given strength.
|
||||
*/
|
||||
void authenticatedFor(int userId, @Authenticators.Types int biometricStrength, int sensorId,
|
||||
long requestId);
|
||||
|
||||
/**
|
||||
* Indicates authentication ended for a sensor of a given strength.
|
||||
*/
|
||||
void authEndedFor(int userId, @Authenticators.Types int biometricStrength, int sensorId,
|
||||
long requestId);
|
||||
long requestId, boolean wasSuccessful);
|
||||
|
||||
/**
|
||||
* Indicates a lockout occurred for a sensor of a given strength.
|
||||
|
||||
@@ -81,9 +81,12 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
@State
|
||||
protected int mState = STATE_NEW;
|
||||
private long mStartTimeMs;
|
||||
|
||||
private boolean mAuthAttempted;
|
||||
private boolean mAuthSuccess = false;
|
||||
private final int mSensorStrength;
|
||||
// This is used to determine if we should use the old lockout counter (HIDL) or the new lockout
|
||||
// counter implementation (AIDL)
|
||||
private final boolean mShouldUseLockoutTracker;
|
||||
|
||||
public AuthenticationClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon,
|
||||
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
|
||||
@@ -92,7 +95,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @Nullable TaskStackListener taskStackListener,
|
||||
@NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication,
|
||||
boolean shouldVibrate, boolean isKeyguardBypassEnabled) {
|
||||
boolean shouldVibrate, boolean isKeyguardBypassEnabled, int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
|
||||
shouldVibrate, biometricLogger, biometricContext);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
@@ -105,22 +108,13 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
mIsRestricted = restricted;
|
||||
mAllowBackgroundAuthentication = allowBackgroundAuthentication;
|
||||
mIsKeyguardBypassEnabled = isKeyguardBypassEnabled;
|
||||
mShouldUseLockoutTracker = lockoutTracker != null;
|
||||
mSensorStrength = sensorStrength;
|
||||
}
|
||||
|
||||
@LockoutTracker.LockoutMode
|
||||
public int handleFailedAttempt(int userId) {
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
mLockoutTracker.getLockoutModeForUser(userId);
|
||||
final PerformanceTracker performanceTracker =
|
||||
PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
|
||||
if (lockoutMode == LockoutTracker.LOCKOUT_PERMANENT) {
|
||||
performanceTracker.incrementPermanentLockoutForUser(userId);
|
||||
} else if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
|
||||
performanceTracker.incrementTimedLockoutForUser(userId);
|
||||
}
|
||||
|
||||
return lockoutMode;
|
||||
return LockoutTracker.LOCKOUT_NONE;
|
||||
}
|
||||
|
||||
protected long getStartTimeMs() {
|
||||
@@ -273,10 +267,12 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
cancel();
|
||||
} else {
|
||||
// Allow system-defined limit of number of attempts before giving up
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
handleFailedAttempt(getTargetUserId());
|
||||
if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
|
||||
markAlreadyDone();
|
||||
if (mShouldUseLockoutTracker) {
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
handleFailedAttempt(getTargetUserId());
|
||||
if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
|
||||
markAlreadyDone();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -309,13 +305,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
@Override
|
||||
public void onAcquired(int acquiredInfo, int vendorCode) {
|
||||
super.onAcquired(acquiredInfo, vendorCode);
|
||||
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
mLockoutTracker.getLockoutModeForUser(getTargetUserId());
|
||||
if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
|
||||
PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -331,8 +320,14 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
public void start(@NonNull ClientMonitorCallback callback) {
|
||||
super.start(callback);
|
||||
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
mLockoutTracker.getLockoutModeForUser(getTargetUserId());
|
||||
final @LockoutTracker.LockoutMode int lockoutMode;
|
||||
if (mShouldUseLockoutTracker) {
|
||||
lockoutMode = mLockoutTracker.getLockoutModeForUser(getTargetUserId());
|
||||
} else {
|
||||
lockoutMode = getBiometricContext().getAuthSessionCoordinator()
|
||||
.getLockoutStateFor(getTargetUserId(), mSensorStrength);
|
||||
}
|
||||
|
||||
if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
|
||||
Slog.v(TAG, "In lockout mode(" + lockoutMode + ") ; disallowing authentication");
|
||||
int errorCode = lockoutMode == LockoutTracker.LOCKOUT_TIMED
|
||||
@@ -406,6 +401,14 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
return mAuthSuccess;
|
||||
}
|
||||
|
||||
protected int getSensorStrength() {
|
||||
return mSensorStrength;
|
||||
}
|
||||
|
||||
protected LockoutTracker getLockoutTracker() {
|
||||
return mLockoutTracker;
|
||||
}
|
||||
|
||||
protected int getShowOverlayReason() {
|
||||
if (isKeyguard()) {
|
||||
return BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
|
||||
|
||||
@@ -75,6 +75,9 @@ class MultiBiometricLockoutState {
|
||||
// fall through
|
||||
case Authenticators.BIOMETRIC_CONVENIENCE:
|
||||
authMap.get(BIOMETRIC_CONVENIENCE).mPermanentlyLockedOut = !canAuth;
|
||||
return;
|
||||
default:
|
||||
Slog.e(TAG, "increaseLockoutTime called for invalid strength : " + strength);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +92,9 @@ class MultiBiometricLockoutState {
|
||||
// fall through
|
||||
case Authenticators.BIOMETRIC_CONVENIENCE:
|
||||
authMap.get(BIOMETRIC_CONVENIENCE).increaseLockoutTo(duration);
|
||||
return;
|
||||
default:
|
||||
Slog.e(TAG, "increaseLockoutTime called for invalid strength : " + strength);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,22 +109,34 @@ class MultiBiometricLockoutState {
|
||||
// fall through
|
||||
case Authenticators.BIOMETRIC_CONVENIENCE:
|
||||
authMap.get(BIOMETRIC_CONVENIENCE).setTimedLockout(0);
|
||||
return;
|
||||
default:
|
||||
Slog.e(TAG, "clearLockoutTime called for invalid strength : " + strength);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if a user can perform an authentication operation with a given
|
||||
* {@link Authenticators.Types}
|
||||
* Retrieves the lockout state for a user of a specified strength.
|
||||
*
|
||||
* @param userId The user.
|
||||
* @param strength The strength of biometric that is requested to authenticate.
|
||||
* @return If a user can authenticate with a given biometric of this strength.
|
||||
*/
|
||||
boolean canUserAuthenticate(int userId, @Authenticators.Types int strength) {
|
||||
final boolean canAuthenticate = getAuthMapForUser(userId).get(strength).canAuthenticate();
|
||||
Slog.d(TAG, "canUserAuthenticate(userId=" + userId + ", strength=" + strength + ") ="
|
||||
+ canAuthenticate);
|
||||
return canAuthenticate;
|
||||
@LockoutTracker.LockoutMode
|
||||
int getLockoutState(int userId, @Authenticators.Types int strength) {
|
||||
final Map<Integer, AuthenticatorState> authMap = getAuthMapForUser(userId);
|
||||
if (!authMap.containsKey(strength)) {
|
||||
Slog.e(TAG, "Error, getLockoutState for unknown strength: " + strength
|
||||
+ " returning LOCKOUT_NONE");
|
||||
return LockoutTracker.LOCKOUT_NONE;
|
||||
}
|
||||
final AuthenticatorState state = authMap.get(strength);
|
||||
if (state.mPermanentlyLockedOut) {
|
||||
return LockoutTracker.LOCKOUT_PERMANENT;
|
||||
} else if (state.isTimedLockout()) {
|
||||
return LockoutTracker.LOCKOUT_TIMED;
|
||||
} else {
|
||||
return LockoutTracker.LOCKOUT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,7 +170,15 @@ class MultiBiometricLockoutState {
|
||||
}
|
||||
|
||||
boolean canAuthenticate() {
|
||||
return !mPermanentlyLockedOut && mClock.millis() - mTimedLockout >= 0;
|
||||
return !mPermanentlyLockedOut && !isTimedLockout();
|
||||
}
|
||||
|
||||
boolean isTimedLockout() {
|
||||
return mClock.millis() - mTimedLockout < 0;
|
||||
}
|
||||
|
||||
void setTimedLockout(long duration) {
|
||||
mTimedLockout = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,10 +188,6 @@ class MultiBiometricLockoutState {
|
||||
mTimedLockout = Math.max(mTimedLockout, duration);
|
||||
}
|
||||
|
||||
void setTimedLockout(long duration) {
|
||||
mTimedLockout = duration;
|
||||
}
|
||||
|
||||
String toString(long currentTime) {
|
||||
final String duration =
|
||||
mTimedLockout - currentTime > 0 ? (mTimedLockout - currentTime) + "ms" : "none";
|
||||
|
||||
@@ -85,7 +85,7 @@ public class PerformanceTracker {
|
||||
}
|
||||
}
|
||||
|
||||
void incrementAcquireForUser(int userId, boolean isCrypto) {
|
||||
public void incrementAcquireForUser(int userId, boolean isCrypto) {
|
||||
createUserEntryIfNecessary(userId);
|
||||
|
||||
if (isCrypto) {
|
||||
@@ -95,13 +95,13 @@ public class PerformanceTracker {
|
||||
}
|
||||
}
|
||||
|
||||
void incrementTimedLockoutForUser(int userId) {
|
||||
public void incrementTimedLockoutForUser(int userId) {
|
||||
createUserEntryIfNecessary(userId);
|
||||
|
||||
mAllUsersInfo.get(userId).mTimedLockout++;
|
||||
}
|
||||
|
||||
void incrementPermanentLockoutForUser(int userId) {
|
||||
public void incrementPermanentLockoutForUser(int userId) {
|
||||
createUserEntryIfNecessary(userId);
|
||||
|
||||
mAllUsersInfo.get(userId).mPermanentLockout++;
|
||||
|
||||
@@ -47,7 +47,7 @@ import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
|
||||
import com.android.server.biometrics.sensors.LockoutCache;
|
||||
import com.android.server.biometrics.sensors.LockoutConsumer;
|
||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||
import com.android.server.biometrics.sensors.PerformanceTracker;
|
||||
import com.android.server.biometrics.sensors.face.UsageStats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -63,8 +63,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@NonNull
|
||||
private final UsageStats mUsageStats;
|
||||
@NonNull
|
||||
private final LockoutCache mLockoutCache;
|
||||
@NonNull
|
||||
private final AuthSessionCoordinator mAuthSessionCoordinator;
|
||||
@Nullable
|
||||
private final NotificationManager mNotificationManager;
|
||||
@@ -72,7 +70,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
private final int[] mBiometricPromptIgnoreListVendor;
|
||||
private final int[] mKeyguardIgnoreList;
|
||||
private final int[] mKeyguardIgnoreListVendor;
|
||||
private final int mBiometricStrength;
|
||||
@Nullable
|
||||
private ICancellationSignal mCancellationSignal;
|
||||
@Nullable
|
||||
@@ -88,12 +85,12 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull UsageStats usageStats,
|
||||
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
|
||||
boolean isKeyguardBypassEnabled, @Authenticators.Types int biometricStrength) {
|
||||
boolean isKeyguardBypassEnabled, @Authenticators.Types int sensorStrength) {
|
||||
this(context, lazyDaemon, token, requestId, listener, targetUserId, operationId,
|
||||
restricted, owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, usageStats, lockoutCache, allowBackgroundAuthentication,
|
||||
isKeyguardBypassEnabled, context.getSystemService(SensorPrivacyManager.class),
|
||||
biometricStrength);
|
||||
isStrongBiometric, usageStats, lockoutCache /* lockoutCache */,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled,
|
||||
context.getSystemService(SensorPrivacyManager.class), sensorStrength);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -109,13 +106,11 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@Authenticators.Types int biometricStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */, lockoutCache,
|
||||
allowBackgroundAuthentication,
|
||||
false /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled);
|
||||
isStrongBiometric, null /* taskStackListener */, null /* lockoutCache */,
|
||||
allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled, biometricStrength);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
mLockoutCache = lockoutCache;
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
mSensorPrivacyManager = sensorPrivacyManager;
|
||||
mAuthSessionCoordinator = biometricContext.getAuthSessionCoordinator();
|
||||
@@ -129,14 +124,12 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
R.array.config_face_acquire_keyguard_ignorelist);
|
||||
mKeyguardIgnoreListVendor = resources.getIntArray(
|
||||
R.array.config_face_acquire_vendor_keyguard_ignorelist);
|
||||
mBiometricStrength = biometricStrength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull ClientMonitorCallback callback) {
|
||||
super.start(callback);
|
||||
mState = STATE_STARTED;
|
||||
mAuthSessionCoordinator.authStartedFor(getTargetUserId(), getSensorId(), getRequestId());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -221,9 +214,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
0 /* error */,
|
||||
0 /* vendorError */,
|
||||
getTargetUserId()));
|
||||
mAuthSessionCoordinator
|
||||
.authenticatedFor(getTargetUserId(), mBiometricStrength, getSensorId(),
|
||||
getRequestId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -239,8 +229,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
if (error == BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL) {
|
||||
BiometricNotificationUtils.showReEnrollmentNotification(getContext());
|
||||
}
|
||||
mAuthSessionCoordinator.authEndedFor(getTargetUserId(), mBiometricStrength, getSensorId(),
|
||||
getRequestId());
|
||||
super.onError(error, vendorCode);
|
||||
}
|
||||
|
||||
@@ -263,6 +251,8 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
mLastAcquire = acquireInfo;
|
||||
final boolean shouldSend = shouldSendAcquiredMessage(acquireInfo, vendorCode);
|
||||
onAcquiredInternal(acquireInfo, vendorCode, shouldSend);
|
||||
PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,35 +280,39 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
|
||||
@Override
|
||||
public void onLockoutTimed(long durationMillis) {
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
|
||||
mAuthSessionCoordinator.lockOutTimed(getTargetUserId(), getSensorStrength(), getSensorId(),
|
||||
durationMillis, getRequestId());
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT;
|
||||
getLogger().logOnError(getContext(), getOperationContext(),
|
||||
error, 0 /* vendorCode */, getTargetUserId());
|
||||
|
||||
PerformanceTracker.getInstanceForSensorId(getSensorId())
|
||||
.incrementTimedLockoutForUser(getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
}
|
||||
mAuthSessionCoordinator.lockOutTimed(getTargetUserId(), mBiometricStrength, getSensorId(),
|
||||
durationMillis, getRequestId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLockoutPermanent() {
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
|
||||
mAuthSessionCoordinator.lockedOutFor(getTargetUserId(), getSensorStrength(), getSensorId(),
|
||||
getRequestId());
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
|
||||
getLogger().logOnError(getContext(), getOperationContext(),
|
||||
error, 0 /* vendorCode */, getTargetUserId());
|
||||
|
||||
PerformanceTracker.getInstanceForSensorId(getSensorId())
|
||||
.incrementPermanentLockoutForUser(getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
}
|
||||
mAuthSessionCoordinator.lockedOutFor(getTargetUserId(), mBiometricStrength, getSensorId(),
|
||||
getRequestId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +50,11 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
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.AuthenticationClient;
|
||||
import com.android.server.biometrics.sensors.BaseClientMonitor;
|
||||
import com.android.server.biometrics.sensors.BiometricStateCallback;
|
||||
import com.android.server.biometrics.sensors.BiometricScheduler;
|
||||
import com.android.server.biometrics.sensors.BiometricStateCallback;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallback;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
|
||||
@@ -82,20 +83,34 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
private boolean mTestHalEnabled;
|
||||
|
||||
@NonNull private final Context mContext;
|
||||
@NonNull private final BiometricStateCallback mBiometricStateCallback;
|
||||
@NonNull private final String mHalInstanceName;
|
||||
@NonNull @VisibleForTesting
|
||||
@NonNull
|
||||
@VisibleForTesting
|
||||
final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports
|
||||
@NonNull private final Handler mHandler;
|
||||
@NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@NonNull private final UsageStats mUsageStats;
|
||||
@NonNull private final ActivityTaskManager mActivityTaskManager;
|
||||
@NonNull private final BiometricTaskStackListener mTaskStackListener;
|
||||
@NonNull
|
||||
private final Context mContext;
|
||||
@NonNull
|
||||
private final BiometricStateCallback mBiometricStateCallback;
|
||||
@NonNull
|
||||
private final String mHalInstanceName;
|
||||
@NonNull
|
||||
private final Handler mHandler;
|
||||
@NonNull
|
||||
private final LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@NonNull
|
||||
private final UsageStats mUsageStats;
|
||||
@NonNull
|
||||
private final ActivityTaskManager mActivityTaskManager;
|
||||
@NonNull
|
||||
private final BiometricTaskStackListener mTaskStackListener;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
@NonNull private final BiometricContext mBiometricContext;
|
||||
@Nullable private IFace mDaemon;
|
||||
@NonNull
|
||||
private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
@NonNull
|
||||
private final BiometricContext mBiometricContext;
|
||||
@NonNull
|
||||
private final AuthSessionCoordinator mAuthSessionCoordinator;
|
||||
@Nullable
|
||||
private IFace mDaemon;
|
||||
|
||||
private final class BiometricTaskStackListener extends TaskStackListener {
|
||||
@Override
|
||||
@@ -141,6 +156,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mActivityTaskManager = ActivityTaskManager.getInstance();
|
||||
mTaskStackListener = new BiometricTaskStackListener();
|
||||
mBiometricContext = biometricContext;
|
||||
mAuthSessionCoordinator = mBiometricContext.getAuthSessionCoordinator();
|
||||
|
||||
for (SensorProps prop : props) {
|
||||
final int sensorId = prop.commonProps.sensorId;
|
||||
@@ -312,7 +328,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
@Override
|
||||
public int getLockoutModeForUser(int sensorId, int userId) {
|
||||
return mSensors.get(sensorId).getLockoutCache().getLockoutModeForUser(userId);
|
||||
return mBiometricContext.getAuthSessionCoordinator().getLockoutStateFor(userId,
|
||||
Utils.getCurrentStrength(sensorId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -423,7 +440,6 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
mHandler.post(() -> {
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final int biometricStrength = Utils.getCurrentStrength(sensorId);
|
||||
final FaceAuthenticationClient client = new FaceAuthenticationClient(
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
|
||||
userId, operationId, restricted, opPackageName, cookie,
|
||||
@@ -431,8 +447,24 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled, biometricStrength);
|
||||
scheduleForSensor(sensorId, client, mBiometricStateCallback);
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled,
|
||||
Utils.getCurrentStrength(sensorId)
|
||||
);
|
||||
scheduleForSensor(sensorId, client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
public void onClientStarted(
|
||||
BaseClientMonitor clientMonitor) {
|
||||
mAuthSessionCoordinator.authStartedFor(userId, sensorId, requestId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientFinished(
|
||||
BaseClientMonitor clientMonitor,
|
||||
boolean success) {
|
||||
mAuthSessionCoordinator.authEndedFor(userId, Utils.getCurrentStrength(sensorId),
|
||||
sensorId, requestId, success);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +89,9 @@ public class FaceResetLockoutClient extends HalClientMonitor<AidlSession> implem
|
||||
void onLockoutCleared() {
|
||||
resetLocalLockoutStateToNone(getSensorId(), getTargetUserId(), mLockoutCache,
|
||||
mLockoutResetDispatcher);
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
getBiometricContext().getAuthSessionCoordinator()
|
||||
.resetLockoutFor(getTargetUserId(), mBiometricStrength, getRequestId());
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
public boolean interruptsPrecedingClients() {
|
||||
|
||||
@@ -677,8 +677,9 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
opPackageName, cookie, false /* requireConfirmation */, mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric, mLockoutTracker,
|
||||
mUsageStats, allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
|
||||
mUsageStats, allowBackgroundAuthentication, isKeyguardBypassEnabled,
|
||||
Utils.getCurrentStrength(mSensorId));
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricFaceConstants;
|
||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.os.IBinder;
|
||||
@@ -39,6 +40,7 @@ import com.android.server.biometrics.sensors.ClientMonitorCallback;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
|
||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||
import com.android.server.biometrics.sensors.PerformanceTracker;
|
||||
import com.android.server.biometrics.sensors.face.UsageStats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -70,12 +72,12 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull LockoutTracker lockoutTracker,
|
||||
@NonNull UsageStats usageStats, boolean allowBackgroundAuthentication,
|
||||
boolean isKeyguardBypassEnabled) {
|
||||
boolean isKeyguardBypassEnabled, @Authenticators.Types int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */,
|
||||
lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled);
|
||||
isKeyguardBypassEnabled, sensorStrength);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
@@ -153,6 +155,21 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
getLockoutTracker().getLockoutModeForUser(userId);
|
||||
final PerformanceTracker performanceTracker =
|
||||
PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
if (lockoutMode == LockoutTracker.LOCKOUT_PERMANENT) {
|
||||
performanceTracker.incrementPermanentLockoutForUser(userId);
|
||||
} else if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
|
||||
performanceTracker.incrementTimedLockoutForUser(userId);
|
||||
}
|
||||
|
||||
return lockoutMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
||||
boolean authenticated, ArrayList<Byte> token) {
|
||||
@@ -204,6 +221,12 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) {
|
||||
BiometricNotificationUtils.showReEnrollmentNotification(getContext());
|
||||
}
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
getLockoutTracker().getLockoutModeForUser(getTargetUserId());
|
||||
if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
|
||||
PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
|
||||
}
|
||||
|
||||
final boolean shouldSend = shouldSend(acquireInfo, vendorCode);
|
||||
onAcquiredInternal(acquireInfo, vendorCode, shouldSend);
|
||||
|
||||
@@ -56,7 +56,7 @@ import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
|
||||
import com.android.server.biometrics.sensors.LockoutCache;
|
||||
import com.android.server.biometrics.sensors.LockoutConsumer;
|
||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||
import com.android.server.biometrics.sensors.PerformanceTracker;
|
||||
import com.android.server.biometrics.sensors.SensorOverlays;
|
||||
import com.android.server.biometrics.sensors.fingerprint.PowerPressHandler;
|
||||
import com.android.server.biometrics.sensors.fingerprint.Udfps;
|
||||
@@ -75,8 +75,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
private static final int MESSAGE_AUTH_SUCCESS = 2;
|
||||
private static final int MESSAGE_FINGER_UP = 3;
|
||||
@NonNull
|
||||
private final LockoutCache mLockoutCache;
|
||||
@NonNull
|
||||
private final SensorOverlays mSensorOverlays;
|
||||
@NonNull
|
||||
private final FingerprintSensorPropertiesInternal mSensorProps;
|
||||
@@ -85,7 +83,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
private final Handler mHandler;
|
||||
private final int mSkipWaitForPowerAcquireMessage;
|
||||
private final int mSkipWaitForPowerVendorAcquireMessage;
|
||||
private final int mBiometricStrength;
|
||||
private final long mFingerUpIgnoresPower = 500;
|
||||
private final AuthSessionCoordinator mAuthSessionCoordinator;
|
||||
@Nullable
|
||||
@@ -140,12 +137,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
biometricContext,
|
||||
isStrongBiometric,
|
||||
taskStackListener,
|
||||
lockoutCache,
|
||||
null /* lockoutCache */,
|
||||
allowBackgroundAuthentication,
|
||||
false /* shouldVibrate */,
|
||||
false /* isKeyguardBypassEnabled */);
|
||||
false /* isKeyguardBypassEnabled */,
|
||||
biometricStrength);
|
||||
setRequestId(requestId);
|
||||
mLockoutCache = lockoutCache;
|
||||
mSensorOverlays = new SensorOverlays(udfpsOverlayController,
|
||||
sidefpsController, udfpsOverlay);
|
||||
mSensorProps = sensorProps;
|
||||
@@ -166,7 +163,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
mSkipWaitForPowerVendorAcquireMessage =
|
||||
context.getResources().getInteger(
|
||||
R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage);
|
||||
mBiometricStrength = biometricStrength;
|
||||
mAuthSessionCoordinator = biometricContext.getAuthSessionCoordinator();
|
||||
mSideFpsLastAcquireStartTime = -1;
|
||||
mClock = clock;
|
||||
@@ -196,8 +192,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
} else {
|
||||
mState = STATE_STARTED;
|
||||
}
|
||||
mAuthSessionCoordinator.authStartedFor(getTargetUserId(), getSensorId(),
|
||||
getRequestId());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -211,8 +205,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
protected void handleLifecycleAfterAuth(boolean authenticated) {
|
||||
if (authenticated) {
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
mAuthSessionCoordinator.authenticatedFor(
|
||||
getTargetUserId(), mBiometricStrength, getSensorId(), getRequestId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,6 +296,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
});
|
||||
}
|
||||
}
|
||||
PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
|
||||
|
||||
}
|
||||
|
||||
@@ -316,8 +310,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
}
|
||||
|
||||
mSensorOverlays.hide(getSensorId());
|
||||
mAuthSessionCoordinator.authEndedFor(getTargetUserId(), mBiometricStrength, getSensorId(),
|
||||
getRequestId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -455,7 +447,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
|
||||
@Override
|
||||
public void onLockoutTimed(long durationMillis) {
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
|
||||
mAuthSessionCoordinator.lockOutTimed(getTargetUserId(), getSensorStrength(), getSensorId(),
|
||||
durationMillis, getRequestId());
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
|
||||
getLogger()
|
||||
@@ -466,6 +459,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
0 /* vendorCode */,
|
||||
getTargetUserId());
|
||||
|
||||
PerformanceTracker.getInstanceForSensorId(getSensorId())
|
||||
.incrementTimedLockoutForUser(getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
} catch (RemoteException e) {
|
||||
@@ -474,13 +470,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
|
||||
mSensorOverlays.hide(getSensorId());
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
mAuthSessionCoordinator.lockOutTimed(getTargetUserId(), mBiometricStrength, getSensorId(),
|
||||
durationMillis, getRequestId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLockoutPermanent() {
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
|
||||
mAuthSessionCoordinator.lockedOutFor(getTargetUserId(), getSensorStrength(), getSensorId(),
|
||||
getRequestId());
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
|
||||
getLogger()
|
||||
@@ -491,6 +486,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
0 /* vendorCode */,
|
||||
getTargetUserId());
|
||||
|
||||
PerformanceTracker.getInstanceForSensorId(getSensorId())
|
||||
.incrementPermanentLockoutForUser(getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
} catch (RemoteException e) {
|
||||
@@ -499,8 +497,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
|
||||
mSensorOverlays.hide(getSensorId());
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
mAuthSessionCoordinator.lockedOutFor(getTargetUserId(), mBiometricStrength, getSensorId(),
|
||||
getRequestId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -515,8 +511,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
onErrorInternal(BiometricConstants.BIOMETRIC_ERROR_POWER_PRESSED,
|
||||
0, true);
|
||||
mSensorOverlays.hide(getSensorId());
|
||||
mAuthSessionCoordinator.authEndedFor(getTargetUserId(),
|
||||
mBiometricStrength, getSensorId(), getRequestId());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
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.AuthenticationClient;
|
||||
import com.android.server.biometrics.sensors.BaseClientMonitor;
|
||||
import com.android.server.biometrics.sensors.BiometricScheduler;
|
||||
@@ -94,15 +95,23 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
|
||||
private boolean mTestHalEnabled;
|
||||
|
||||
@NonNull private final Context mContext;
|
||||
@NonNull private final BiometricStateCallback mBiometricStateCallback;
|
||||
@NonNull private final String mHalInstanceName;
|
||||
@NonNull @VisibleForTesting
|
||||
@NonNull
|
||||
@VisibleForTesting
|
||||
final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports
|
||||
@NonNull private final Handler mHandler;
|
||||
@NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@NonNull private final ActivityTaskManager mActivityTaskManager;
|
||||
@NonNull private final BiometricTaskStackListener mTaskStackListener;
|
||||
@NonNull
|
||||
private final Context mContext;
|
||||
@NonNull
|
||||
private final BiometricStateCallback mBiometricStateCallback;
|
||||
@NonNull
|
||||
private final String mHalInstanceName;
|
||||
@NonNull
|
||||
private final Handler mHandler;
|
||||
@NonNull
|
||||
private final LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@NonNull
|
||||
private final ActivityTaskManager mActivityTaskManager;
|
||||
@NonNull
|
||||
private final BiometricTaskStackListener mTaskStackListener;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
@NonNull private final BiometricContext mBiometricContext;
|
||||
@@ -110,6 +119,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private ISidefpsController mSidefpsController;
|
||||
@Nullable private IUdfpsOverlay mUdfpsOverlay;
|
||||
private AuthSessionCoordinator mAuthSessionCoordinator;
|
||||
|
||||
private final class BiometricTaskStackListener extends TaskStackListener {
|
||||
@Override
|
||||
@@ -154,6 +164,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mActivityTaskManager = ActivityTaskManager.getInstance();
|
||||
mTaskStackListener = new BiometricTaskStackListener();
|
||||
mBiometricContext = biometricContext;
|
||||
mAuthSessionCoordinator = mBiometricContext.getAuthSessionCoordinator();
|
||||
|
||||
final List<SensorLocationInternal> workaroundLocations = getWorkaroundSensorProps(context);
|
||||
|
||||
@@ -179,11 +190,11 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
!workaroundLocations.isEmpty() ? workaroundLocations :
|
||||
Arrays.stream(prop.sensorLocations).map(location ->
|
||||
new SensorLocationInternal(
|
||||
location.display,
|
||||
location.sensorLocationX,
|
||||
location.sensorLocationY,
|
||||
location.sensorRadius))
|
||||
new SensorLocationInternal(
|
||||
location.display,
|
||||
location.sensorLocationX,
|
||||
location.sensorLocationY,
|
||||
location.sensorRadius))
|
||||
.collect(Collectors.toList()));
|
||||
final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
|
||||
internalProp, lockoutResetDispatcher, gestureAvailabilityDispatcher,
|
||||
@@ -347,7 +358,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mSensors.get(sensorId).getLazySession(), token,
|
||||
new ClientMonitorCallbackConverter(receiver), userId, opPackageName,
|
||||
sensorId, createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
mBiometricContext);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -445,8 +456,30 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mUdfpsOverlayController, mSidefpsController, mUdfpsOverlay,
|
||||
allowBackgroundAuthentication,
|
||||
mSensors.get(sensorId).getSensorProperties(), mHandler,
|
||||
Utils.getCurrentStrength(sensorId), SystemClock.elapsedRealtimeClock());
|
||||
scheduleForSensor(sensorId, client, mBiometricStateCallback);
|
||||
Utils.getCurrentStrength(sensorId),
|
||||
SystemClock.elapsedRealtimeClock());
|
||||
scheduleForSensor(sensorId, client, new ClientMonitorCallback() {
|
||||
|
||||
@Override
|
||||
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
|
||||
mBiometricStateCallback.onClientStarted(clientMonitor);
|
||||
mAuthSessionCoordinator.authStartedFor(userId, sensorId, requestId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBiometricAction(int action) {
|
||||
mBiometricStateCallback.onBiometricAction(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
|
||||
boolean success) {
|
||||
mBiometricStateCallback.onClientFinished(clientMonitor, success);
|
||||
mAuthSessionCoordinator.authEndedFor(userId, Utils.getCurrentStrength(sensorId),
|
||||
sensorId, requestId, success);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -584,7 +617,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
|
||||
@Override
|
||||
public int getLockoutModeForUser(int sensorId, int userId) {
|
||||
return mSensors.get(sensorId).getLockoutCache().getLockoutModeForUser(userId);
|
||||
return mBiometricContext.getAuthSessionCoordinator().getLockoutStateFor(userId,
|
||||
Utils.getCurrentStrength(sensorId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -93,9 +93,9 @@ class FingerprintResetLockoutClient extends HalClientMonitor<AidlSession> implem
|
||||
void onLockoutCleared() {
|
||||
resetLocalLockoutStateToNone(getSensorId(), getTargetUserId(), mLockoutCache,
|
||||
mLockoutResetDispatcher);
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
getBiometricContext().getAuthSessionCoordinator()
|
||||
.resetLockoutFor(getTargetUserId(), mBiometricStrength, getRequestId());
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -667,7 +667,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mTaskStackListener, mLockoutTracker,
|
||||
mUdfpsOverlayController, mSidefpsController, mUdfpsOverlay,
|
||||
allowBackgroundAuthentication, mSensorProperties);
|
||||
allowBackgroundAuthentication, mSensorProperties,
|
||||
Utils.getCurrentStrength(mSensorId));
|
||||
mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricFingerprintConstants;
|
||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
@@ -42,6 +43,7 @@ import com.android.server.biometrics.sensors.ClientMonitorCallback;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
|
||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||
import com.android.server.biometrics.sensors.PerformanceTracker;
|
||||
import com.android.server.biometrics.sensors.SensorOverlays;
|
||||
import com.android.server.biometrics.sensors.fingerprint.Udfps;
|
||||
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
|
||||
@@ -79,12 +81,13 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
@Nullable ISidefpsController sidefpsController,
|
||||
@Nullable IUdfpsOverlay udfpsOverlay,
|
||||
boolean allowBackgroundAuthentication,
|
||||
@NonNull FingerprintSensorPropertiesInternal sensorProps) {
|
||||
@NonNull FingerprintSensorPropertiesInternal sensorProps,
|
||||
@Authenticators.Types int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, taskStackListener, lockoutTracker,
|
||||
allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
false /* isKeyguardBypassEnabled */);
|
||||
isStrongBiometric, taskStackListener, lockoutTracker, allowBackgroundAuthentication,
|
||||
false /* shouldVibrate */, false /* isKeyguardBypassEnabled */,
|
||||
sensorStrength);
|
||||
setRequestId(requestId);
|
||||
mLockoutFrameworkImpl = lockoutTracker;
|
||||
mSensorOverlays = new SensorOverlays(udfpsOverlayController,
|
||||
@@ -166,6 +169,18 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAcquired(int acquiredInfo, int vendorCode) {
|
||||
super.onAcquired(acquiredInfo, vendorCode);
|
||||
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
getLockoutTracker().getLockoutModeForUser(getTargetUserId());
|
||||
if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
|
||||
PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasUserDetected() {
|
||||
// TODO: Update if it needs to be used for fingerprint, i.e. success/reject, error_timeout
|
||||
@@ -175,7 +190,17 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
@Override
|
||||
public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
|
||||
mLockoutFrameworkImpl.addFailedAttemptForUser(userId);
|
||||
return super.handleFailedAttempt(userId);
|
||||
@LockoutTracker.LockoutMode final int lockoutMode =
|
||||
getLockoutTracker().getLockoutModeForUser(userId);
|
||||
final PerformanceTracker performanceTracker =
|
||||
PerformanceTracker.getInstanceForSensorId(getSensorId());
|
||||
if (lockoutMode == LockoutTracker.LOCKOUT_PERMANENT) {
|
||||
performanceTracker.incrementPermanentLockoutForUser(userId);
|
||||
} else if (lockoutMode == LockoutTracker.LOCKOUT_TIMED) {
|
||||
performanceTracker.incrementTimedLockoutForUser(userId);
|
||||
}
|
||||
|
||||
return lockoutMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.locksettings;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
@@ -48,11 +49,13 @@ public class BiometricDeferredQueue {
|
||||
@NonNull private final Handler mHandler;
|
||||
@Nullable private FingerprintManager mFingerprintManager;
|
||||
@Nullable private FaceManager mFaceManager;
|
||||
@Nullable private BiometricManager mBiometricManager;
|
||||
|
||||
// Entries added by LockSettingsService once a user's synthetic password is known. At this point
|
||||
// things are still keyed by userId.
|
||||
@NonNull private final ArrayList<UserAuthInfo> mPendingResetLockoutsForFingerprint;
|
||||
@NonNull private final ArrayList<UserAuthInfo> mPendingResetLockoutsForFace;
|
||||
@NonNull private final ArrayList<UserAuthInfo> mPendingResetLockouts;
|
||||
|
||||
/**
|
||||
* Authentication info for a successful user unlock via Synthetic Password. This can be used to
|
||||
@@ -125,7 +128,6 @@ public class BiometricDeferredQueue {
|
||||
}
|
||||
|
||||
@Nullable private FaceResetLockoutTask mFaceResetLockoutTask;
|
||||
|
||||
private final FaceResetLockoutTask.FinishCallback mFaceFinishCallback = () -> {
|
||||
mFaceResetLockoutTask = null;
|
||||
};
|
||||
@@ -135,12 +137,14 @@ public class BiometricDeferredQueue {
|
||||
mHandler = handler;
|
||||
mPendingResetLockoutsForFingerprint = new ArrayList<>();
|
||||
mPendingResetLockoutsForFace = new ArrayList<>();
|
||||
mPendingResetLockouts = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void systemReady(@Nullable FingerprintManager fingerprintManager,
|
||||
@Nullable FaceManager faceManager) {
|
||||
@Nullable FaceManager faceManager, @Nullable BiometricManager biometricManager) {
|
||||
mFingerprintManager = fingerprintManager;
|
||||
mFaceManager = faceManager;
|
||||
mBiometricManager = biometricManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +155,7 @@ public class BiometricDeferredQueue {
|
||||
* Note that this should only ever be invoked for successful authentications, otherwise it will
|
||||
* consume a Gatekeeper authentication attempt and potentially wipe the user/device.
|
||||
*
|
||||
* @param userId The user that the operation will apply for.
|
||||
* @param userId The user that the operation will apply for.
|
||||
* @param gatekeeperPassword The Gatekeeper Password
|
||||
*/
|
||||
void addPendingLockoutResetForUser(int userId, @NonNull byte[] gatekeeperPassword) {
|
||||
@@ -167,6 +171,12 @@ public class BiometricDeferredQueue {
|
||||
mPendingResetLockoutsForFingerprint.add(new UserAuthInfo(userId,
|
||||
gatekeeperPassword));
|
||||
}
|
||||
|
||||
if (mBiometricManager != null) {
|
||||
Slog.d(TAG, "Fingerprint addPendingLockoutResetForUser: " + userId);
|
||||
mPendingResetLockouts.add(new UserAuthInfo(userId,
|
||||
gatekeeperPassword));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -184,6 +194,14 @@ public class BiometricDeferredQueue {
|
||||
new ArrayList<>(mPendingResetLockoutsForFingerprint));
|
||||
mPendingResetLockoutsForFingerprint.clear();
|
||||
}
|
||||
|
||||
if (!mPendingResetLockouts.isEmpty()) {
|
||||
Slog.d(TAG, "Processing pending resetLockouts(Generic)");
|
||||
processPendingLockoutsGeneric(
|
||||
new ArrayList<>(mPendingResetLockouts));
|
||||
mPendingResetLockouts.clear();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -257,6 +275,17 @@ public class BiometricDeferredQueue {
|
||||
}
|
||||
}
|
||||
|
||||
private void processPendingLockoutsGeneric(List<UserAuthInfo> pendingResetLockouts) {
|
||||
for (UserAuthInfo user : pendingResetLockouts) {
|
||||
Slog.d(TAG, "Resetting biometric lockout for user: " + user.userId);
|
||||
final byte[] hat = requestHatFromGatekeeperPassword(mSpManager, user,
|
||||
0 /* challenge */);
|
||||
if (hat != null) {
|
||||
mBiometricManager.resetLockout(user.userId, hat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static byte[] requestHatFromGatekeeperPassword(
|
||||
@NonNull SyntheticPasswordManager spManager,
|
||||
|
||||
@@ -70,6 +70,7 @@ import android.content.pm.UserInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.hardware.authsecret.V1_0.IAuthSecret;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
@@ -552,6 +553,10 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public BiometricManager getBiometricManager() {
|
||||
return (BiometricManager) mContext.getSystemService(Context.BIOMETRIC_SERVICE);
|
||||
}
|
||||
|
||||
public int settingsGlobalGetInt(ContentResolver contentResolver, String keyName,
|
||||
int defaultValue) {
|
||||
return Settings.Global.getInt(contentResolver, keyName, defaultValue);
|
||||
@@ -837,7 +842,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
// TODO: maybe skip this for split system user mode.
|
||||
mStorage.prefetchUser(UserHandle.USER_SYSTEM);
|
||||
mBiometricDeferredQueue.systemReady(mInjector.getFingerprintManager(),
|
||||
mInjector.getFaceManager());
|
||||
mInjector.getFaceManager(), mInjector.getBiometricManager());
|
||||
}
|
||||
|
||||
private void loadEscrowData() {
|
||||
|
||||
@@ -64,6 +64,7 @@ import android.hardware.biometrics.IBiometricService;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiver;
|
||||
import android.hardware.biometrics.IBiometricSysuiReceiver;
|
||||
import android.hardware.biometrics.PromptInfo;
|
||||
import android.hardware.display.AmbientDisplayConfiguration;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
@@ -75,7 +76,10 @@ import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.statusbar.ISessionListener;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.server.biometrics.log.BiometricContextProvider;
|
||||
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
|
||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -129,6 +133,16 @@ public class BiometricServiceTest {
|
||||
ITrustManager mTrustManager;
|
||||
@Mock
|
||||
DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock
|
||||
private IStatusBarService mStatusBarService;
|
||||
@Mock
|
||||
private ISessionListener mSessionListener;
|
||||
@Mock
|
||||
private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
||||
@Mock
|
||||
private AuthSessionCoordinator mAuthSessionCoordinator;
|
||||
|
||||
BiometricContextProvider mBiometricContextProvider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -160,6 +174,11 @@ public class BiometricServiceTest {
|
||||
when(mResources.getString(R.string.biometric_error_user_canceled))
|
||||
.thenReturn(ERROR_USER_CANCELED);
|
||||
|
||||
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||
mBiometricContextProvider = new BiometricContextProvider(mAmbientDisplayConfiguration,
|
||||
mStatusBarService, null /* handler */, mAuthSessionCoordinator);
|
||||
when(mInjector.getBiometricContext(any())).thenReturn(mBiometricContextProvider);
|
||||
|
||||
final String[] config = {
|
||||
"0:2:15", // ID0:Fingerprint:Strong
|
||||
"1:8:15", // ID1:Face:Strong
|
||||
|
||||
@@ -61,11 +61,11 @@ public class AuthResultCoordinatorTest {
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
AUTHENTICATOR_UNLOCKED);
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLockout() {
|
||||
public void testConvenientLockout() {
|
||||
mAuthResultCoordinator.lockedOutFor(
|
||||
BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class AuthResultCoordinatorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvenientLockout() {
|
||||
public void testConvenientUnlock() {
|
||||
mAuthResultCoordinator.authenticatedFor(
|
||||
BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE);
|
||||
|
||||
@@ -91,11 +91,26 @@ public class AuthResultCoordinatorTest {
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
AUTHENTICATOR_UNLOCKED);
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWeakLockout() {
|
||||
mAuthResultCoordinator.lockedOutFor(
|
||||
BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE);
|
||||
|
||||
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_LOCKED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWeakUnlock() {
|
||||
mAuthResultCoordinator.authenticatedFor(
|
||||
BiometricManager.Authenticators.BIOMETRIC_WEAK);
|
||||
|
||||
@@ -104,13 +119,29 @@ public class AuthResultCoordinatorTest {
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
|
||||
AUTHENTICATOR_UNLOCKED);
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
AUTHENTICATOR_UNLOCKED);
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStrongLockout() {
|
||||
mAuthResultCoordinator.lockedOutFor(
|
||||
BiometricManager.Authenticators.BIOMETRIC_STRONG);
|
||||
|
||||
Map<Integer, Integer> authMap = mAuthResultCoordinator.getResult();
|
||||
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
|
||||
AUTHENTICATOR_LOCKED);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
|
||||
AUTHENTICATOR_LOCKED);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
AUTHENTICATOR_LOCKED);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testStrongUnlock() {
|
||||
mAuthResultCoordinator.authenticatedFor(
|
||||
BiometricManager.Authenticators.BIOMETRIC_STRONG);
|
||||
|
||||
@@ -136,9 +167,9 @@ public class AuthResultCoordinatorTest {
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_STRONG)).isEqualTo(
|
||||
AUTHENTICATOR_DEFAULT);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_WEAK)).isEqualTo(
|
||||
AUTHENTICATOR_UNLOCKED | AUTHENTICATOR_LOCKED);
|
||||
AUTHENTICATOR_LOCKED);
|
||||
assertThat(authMap.get(BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
AUTHENTICATOR_UNLOCKED | AUTHENTICATOR_LOCKED);
|
||||
AUTHENTICATOR_LOCKED);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -53,22 +53,28 @@ public class AuthSessionCoordinatorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserUnlocked() {
|
||||
public void testUserUnlockedWithWeak() {
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 1 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.lockedOutFor(PRIMARY_USER, BIOMETRIC_STRONG, 1 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 1 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.authenticatedFor(PRIMARY_USER, BIOMETRIC_WEAK, 1 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
mCoordinator.authEndedFor(PRIMARY_USER, BIOMETRIC_WEAK, 1 /* sensorId */,
|
||||
0 /* requestId */, true /* wasSuccessful */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,38 +83,79 @@ public class AuthSessionCoordinatorTest {
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 2 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.lockedOutFor(PRIMARY_USER, BIOMETRIC_STRONG, 1 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
mCoordinator.authenticatedFor(PRIMARY_USER, BIOMETRIC_WEAK, 2 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
mCoordinator.authEndedFor(PRIMARY_USER, BIOMETRIC_WEAK, 2 /* sensorId */,
|
||||
0 /* requestId */, false /* wasSuccessful */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 1 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.authenticatedFor(PRIMARY_USER, BIOMETRIC_WEAK, 1 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
mCoordinator.authEndedFor(PRIMARY_USER, BIOMETRIC_WEAK, 1 /* sensorId */,
|
||||
0 /* requestId */, false /* wasSuccessful */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWeakAndConvenientCannotResetLockout() {
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 1 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.lockedOutFor(PRIMARY_USER, BIOMETRIC_STRONG, 1 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
|
||||
mCoordinator.resetLockoutFor(PRIMARY_USER, BIOMETRIC_WEAK, 0 /* requestId */);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
|
||||
mCoordinator.resetLockoutFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE, 0 /* requestId */);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserCanAuthDuringLockoutOfSameSession() {
|
||||
mCoordinator.resetLockoutFor(PRIMARY_USER, BIOMETRIC_STRONG, 0 /* requestId */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 1 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 2 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.lockedOutFor(PRIMARY_USER, BIOMETRIC_WEAK, 2 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -123,25 +170,39 @@ public class AuthSessionCoordinatorTest {
|
||||
|
||||
mCoordinator.resetLockoutFor(PRIMARY_USER, BIOMETRIC_STRONG, 0 /* requestId */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(SECONDARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(SECONDARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(SECONDARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(
|
||||
mCoordinator.getLockoutStateFor(SECONDARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(SECONDARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(SECONDARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 1 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.authStartedFor(PRIMARY_USER, 2 /* sensorId */, 0 /* requestId */);
|
||||
mCoordinator.lockedOutFor(PRIMARY_USER, BIOMETRIC_WEAK, 2 /* sensorId */,
|
||||
0 /* requestId */);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getCanAuthFor(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mCoordinator.getLockoutStateFor(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
|
||||
assertThat(mCoordinator.getCanAuthFor(SECONDARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(SECONDARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mCoordinator.getCanAuthFor(SECONDARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(
|
||||
mCoordinator.getLockoutStateFor(SECONDARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(SECONDARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mCoordinator.getLockoutStateFor(SECONDARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.biometrics.sensors;
|
||||
|
||||
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED;
|
||||
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_SUCCESS;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.Assert.fail;
|
||||
@@ -78,17 +79,24 @@ public class BiometricSchedulerTest {
|
||||
private static final int TEST_SENSOR_ID = 1;
|
||||
private static final int LOG_NUM_RECENT_OPERATIONS = 2;
|
||||
@Rule
|
||||
public final TestableContext mContext =
|
||||
new TestableContext(InstrumentationRegistry.getContext(), null);
|
||||
public final TestableContext mContext = new TestableContext(
|
||||
InstrumentationRegistry.getContext(), null);
|
||||
private BiometricScheduler mScheduler;
|
||||
private IBinder mToken;
|
||||
@Mock
|
||||
private IBiometricService mBiometricService;
|
||||
@Mock
|
||||
private BiometricContext mBiometricContext;
|
||||
@Mock
|
||||
private AuthSessionCoordinator mAuthSessionCoordinator;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mToken = new Binder();
|
||||
when(mAuthSessionCoordinator.getLockoutStateFor(anyInt(), anyInt())).thenReturn(
|
||||
BIOMETRIC_SUCCESS);
|
||||
when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
|
||||
mScheduler = new BiometricScheduler(TAG, new Handler(TestableLooper.get(this).getLooper()),
|
||||
BiometricScheduler.SENSOR_TYPE_UNKNOWN, null /* gestureAvailabilityTracker */,
|
||||
mBiometricService, LOG_NUM_RECENT_OPERATIONS);
|
||||
@@ -98,10 +106,10 @@ public class BiometricSchedulerTest {
|
||||
public void testClientDuplicateFinish_ignoredBySchedulerAndDoesNotCrash() {
|
||||
final Supplier<Object> nonNullDaemon = () -> mock(Object.class);
|
||||
|
||||
final HalClientMonitor<Object> client1 =
|
||||
new TestHalClientMonitor(mContext, mToken, nonNullDaemon);
|
||||
final HalClientMonitor<Object> client2 =
|
||||
new TestHalClientMonitor(mContext, mToken, nonNullDaemon);
|
||||
final HalClientMonitor<Object> client1 = new TestHalClientMonitor(mContext, mToken,
|
||||
nonNullDaemon);
|
||||
final HalClientMonitor<Object> client2 = new TestHalClientMonitor(mContext, mToken,
|
||||
nonNullDaemon);
|
||||
mScheduler.scheduleClientMonitor(client1);
|
||||
mScheduler.scheduleClientMonitor(client2);
|
||||
|
||||
@@ -112,10 +120,9 @@ public class BiometricSchedulerTest {
|
||||
@Test
|
||||
public void testRemovesPendingOperations_whenNullHal_andNotBiometricPrompt() {
|
||||
// Even if second client has a non-null daemon, it needs to be canceled.
|
||||
final TestHalClientMonitor client1 = new TestHalClientMonitor(
|
||||
mContext, mToken, () -> null);
|
||||
final TestHalClientMonitor client2 = new TestHalClientMonitor(
|
||||
mContext, mToken, () -> mock(Object.class));
|
||||
final TestHalClientMonitor client1 = new TestHalClientMonitor(mContext, mToken, () -> null);
|
||||
final TestHalClientMonitor client2 = new TestHalClientMonitor(mContext, mToken,
|
||||
() -> mock(Object.class));
|
||||
|
||||
final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);
|
||||
final ClientMonitorCallback callback2 = mock(ClientMonitorCallback.class);
|
||||
@@ -150,10 +157,10 @@ public class BiometricSchedulerTest {
|
||||
|
||||
final ClientMonitorCallbackConverter listener1 = mock(ClientMonitorCallbackConverter.class);
|
||||
|
||||
final TestAuthenticationClient client1 =
|
||||
new TestAuthenticationClient(mContext, () -> null, mToken, listener1);
|
||||
final TestHalClientMonitor client2 =
|
||||
new TestHalClientMonitor(mContext, mToken, () -> daemon2);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext, () -> null,
|
||||
mToken, listener1, mBiometricContext);
|
||||
final TestHalClientMonitor client2 = new TestHalClientMonitor(mContext, mToken,
|
||||
() -> daemon2);
|
||||
|
||||
final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);
|
||||
final ClientMonitorCallback callback2 = mock(ClientMonitorCallback.class);
|
||||
@@ -188,15 +195,15 @@ public class BiometricSchedulerTest {
|
||||
@Test
|
||||
public void testCancelNotInvoked_whenOperationWaitingForCookie() {
|
||||
final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class));
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext, lazyDaemon1,
|
||||
mToken, mock(ClientMonitorCallbackConverter.class), mBiometricContext);
|
||||
final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);
|
||||
|
||||
// Schedule a BiometricPrompt authentication request
|
||||
mScheduler.scheduleClientMonitor(client1, callback1);
|
||||
|
||||
assertNotEquals(0, mScheduler.mCurrentOperation.isReadyToStart(
|
||||
mock(ClientMonitorCallback.class)));
|
||||
assertNotEquals(0,
|
||||
mScheduler.mCurrentOperation.isReadyToStart(mock(ClientMonitorCallback.class)));
|
||||
assertEquals(client1, mScheduler.mCurrentOperation.getClientMonitor());
|
||||
assertEquals(0, mScheduler.mPendingOperations.size());
|
||||
|
||||
@@ -304,7 +311,7 @@ public class BiometricSchedulerTest {
|
||||
final TestHalClientMonitor client1 = new TestHalClientMonitor(mContext, mToken, lazyDaemon);
|
||||
final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class);
|
||||
final TestAuthenticationClient client2 = new TestAuthenticationClient(mContext, lazyDaemon,
|
||||
mToken, callback);
|
||||
mToken, callback, mBiometricContext);
|
||||
|
||||
// Add a non-cancellable client, then add the auth client
|
||||
mScheduler.scheduleClientMonitor(client1);
|
||||
@@ -367,7 +374,8 @@ public class BiometricSchedulerTest {
|
||||
final Supplier<Object> lazyDaemon = () -> mock(Object.class);
|
||||
final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class);
|
||||
testCancelsWhenRequestId(requestId, cancelRequestId, started,
|
||||
new TestAuthenticationClient(mContext, lazyDaemon, mToken, callback));
|
||||
new TestAuthenticationClient(mContext, lazyDaemon, mToken, callback,
|
||||
mBiometricContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -448,11 +456,11 @@ public class BiometricSchedulerTest {
|
||||
final long requestId2 = 20;
|
||||
final Supplier<Object> lazyDaemon = () -> mock(Object.class);
|
||||
final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(
|
||||
mContext, lazyDaemon, mToken, callback);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext, lazyDaemon,
|
||||
mToken, callback, mBiometricContext);
|
||||
client1.setRequestId(requestId1);
|
||||
final TestAuthenticationClient client2 = new TestAuthenticationClient(
|
||||
mContext, lazyDaemon, mToken, callback);
|
||||
final TestAuthenticationClient client2 = new TestAuthenticationClient(mContext, lazyDaemon,
|
||||
mToken, callback, mBiometricContext);
|
||||
client2.setRequestId(requestId2);
|
||||
|
||||
mScheduler.scheduleClientMonitor(client1);
|
||||
@@ -506,8 +514,8 @@ public class BiometricSchedulerTest {
|
||||
@Test
|
||||
public void testClientDestroyed_afterFinish() {
|
||||
final Supplier<Object> nonNullDaemon = () -> mock(Object.class);
|
||||
final TestHalClientMonitor client =
|
||||
new TestHalClientMonitor(mContext, mToken, nonNullDaemon);
|
||||
final TestHalClientMonitor client = new TestHalClientMonitor(mContext, mToken,
|
||||
nonNullDaemon);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
client.mCallback.onClientFinished(client, true /* success */);
|
||||
waitForIdle();
|
||||
@@ -520,7 +528,8 @@ public class BiometricSchedulerTest {
|
||||
final TestableLooper looper = TestableLooper.get(this);
|
||||
final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */);
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */,
|
||||
mBiometricContext);
|
||||
final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);
|
||||
|
||||
mScheduler.scheduleClientMonitor(client1, callback1);
|
||||
@@ -555,7 +564,8 @@ public class BiometricSchedulerTest {
|
||||
final TestableLooper looper = TestableLooper.get(this);
|
||||
final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */);
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */,
|
||||
mBiometricContext);
|
||||
final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);
|
||||
|
||||
mScheduler.scheduleClientMonitor(client1, callback1);
|
||||
@@ -589,7 +599,8 @@ public class BiometricSchedulerTest {
|
||||
|
||||
//Run additional auth client
|
||||
final TestAuthenticationClient client2 = new TestAuthenticationClient(mContext,
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */);
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */,
|
||||
mBiometricContext);
|
||||
final ClientMonitorCallback callback2 = mock(ClientMonitorCallback.class);
|
||||
|
||||
mScheduler.scheduleClientMonitor(client2, callback2);
|
||||
@@ -626,7 +637,8 @@ public class BiometricSchedulerTest {
|
||||
final TestableLooper looper = TestableLooper.get(this);
|
||||
final Supplier<Object> lazyDaemon1 = () -> mock(Object.class);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */);
|
||||
lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class), 0 /* cookie */,
|
||||
mBiometricContext);
|
||||
final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);
|
||||
|
||||
mScheduler.scheduleClientMonitor(client1, callback1);
|
||||
@@ -679,19 +691,22 @@ public class BiometricSchedulerTest {
|
||||
|
||||
TestAuthenticationClient(@NonNull Context context,
|
||||
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter listener) {
|
||||
this(context, lazyDaemon, token, listener, 1 /* cookie */);
|
||||
@NonNull ClientMonitorCallbackConverter listener,
|
||||
BiometricContext biometricContext) {
|
||||
this(context, lazyDaemon, token, listener, 1 /* cookie */, biometricContext);
|
||||
}
|
||||
|
||||
TestAuthenticationClient(@NonNull Context context,
|
||||
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int cookie) {
|
||||
@NonNull ClientMonitorCallbackConverter listener, int cookie,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
super(context, lazyDaemon, token, listener, 0 /* targetUserId */, 0 /* operationId */,
|
||||
false /* restricted */, TAG, cookie, false /* requireConfirmation */,
|
||||
TEST_SENSOR_ID, mock(BiometricLogger.class), mock(BiometricContext.class),
|
||||
TEST_SENSOR_ID, mock(BiometricLogger.class), biometricContext,
|
||||
true /* isStrongBiometric */, null /* taskStackListener */,
|
||||
mock(LockoutTracker.class), false /* isKeyguard */,
|
||||
true /* shouldVibrate */, false /* isKeyguardBypassEnabled */);
|
||||
null /* lockoutTracker */, false /* isKeyguard */,
|
||||
true /* shouldVibrate */, false /* isKeyguardBypassEnabled */,
|
||||
0 /* sensorStrength */);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -742,14 +757,12 @@ public class BiometricSchedulerTest {
|
||||
boolean mStoppedHal = false;
|
||||
int mNumCancels = 0;
|
||||
|
||||
TestEnrollClient(@NonNull Context context,
|
||||
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter listener) {
|
||||
TestEnrollClient(@NonNull Context context, @NonNull Supplier<Object> lazyDaemon,
|
||||
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener) {
|
||||
super(context, lazyDaemon, token, listener, 0 /* userId */, new byte[69],
|
||||
"test" /* owner */, mock(BiometricUtils.class),
|
||||
5 /* timeoutSec */, TEST_SENSOR_ID,
|
||||
true /* shouldVibrate */,
|
||||
mock(BiometricLogger.class), mock(BiometricContext.class));
|
||||
"test" /* owner */, mock(BiometricUtils.class), 5 /* timeoutSec */,
|
||||
TEST_SENSOR_ID, true /* shouldVibrate */, mock(BiometricLogger.class),
|
||||
mock(BiometricContext.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -787,9 +800,9 @@ public class BiometricSchedulerTest {
|
||||
|
||||
TestHalClientMonitor(@NonNull Context context, @NonNull IBinder token,
|
||||
@NonNull Supplier<Object> lazyDaemon, int cookie, int protoEnum) {
|
||||
super(context, lazyDaemon, token /* token */, null /* listener */, 0 /* userId */,
|
||||
TAG, cookie, TEST_SENSOR_ID,
|
||||
mock(BiometricLogger.class), mock(BiometricContext.class));
|
||||
super(context, lazyDaemon, token /* token */, null /* listener */, 0 /* userId */, TAG,
|
||||
cookie, TEST_SENSOR_ID, mock(BiometricLogger.class),
|
||||
mock(BiometricContext.class));
|
||||
mProtoEnum = protoEnum;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,16 +50,22 @@ public class MultiBiometricLockoutStateTest {
|
||||
|
||||
private static void unlockAllBiometrics(MultiBiometricLockoutState lockoutState, int userId) {
|
||||
lockoutState.setAuthenticatorTo(userId, BIOMETRIC_STRONG, true /* canAuthenticate */);
|
||||
assertThat(lockoutState.canUserAuthenticate(userId, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(lockoutState.canUserAuthenticate(userId, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(lockoutState.canUserAuthenticate(userId, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
}
|
||||
|
||||
private static void lockoutAllBiometrics(MultiBiometricLockoutState lockoutState, int userId) {
|
||||
lockoutState.setAuthenticatorTo(userId, BIOMETRIC_STRONG, false /* canAuthenticate */);
|
||||
assertThat(lockoutState.canUserAuthenticate(userId, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(lockoutState.canUserAuthenticate(userId, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(lockoutState.canUserAuthenticate(userId, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(lockoutState.getLockoutState(userId, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
private void unlockAllBiometrics() {
|
||||
@@ -79,9 +85,12 @@ public class MultiBiometricLockoutStateTest {
|
||||
|
||||
@Test
|
||||
public void testInitialStateLockedOut() {
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -89,20 +98,26 @@ public class MultiBiometricLockoutStateTest {
|
||||
unlockAllBiometrics();
|
||||
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_CONVENIENCE,
|
||||
false /* canAuthenticate */);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(
|
||||
mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWeakLockout() {
|
||||
unlockAllBiometrics();
|
||||
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_WEAK, false /* canAuthenticate */);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(
|
||||
mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -110,10 +125,13 @@ public class MultiBiometricLockoutStateTest {
|
||||
lockoutAllBiometrics();
|
||||
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_STRONG,
|
||||
false /* canAuthenticate */);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(
|
||||
mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -121,18 +139,24 @@ public class MultiBiometricLockoutStateTest {
|
||||
lockoutAllBiometrics();
|
||||
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_CONVENIENCE,
|
||||
true /* canAuthenticate */);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWeakUnlock() {
|
||||
lockoutAllBiometrics();
|
||||
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_WEAK, true /* canAuthenticate */);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -140,9 +164,12 @@ public class MultiBiometricLockoutStateTest {
|
||||
lockoutAllBiometrics();
|
||||
mLockoutState.setAuthenticatorTo(PRIMARY_USER, BIOMETRIC_STRONG,
|
||||
true /* canAuthenticate */);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -154,45 +181,66 @@ public class MultiBiometricLockoutStateTest {
|
||||
lockoutAllBiometrics(lockoutState, userTwo);
|
||||
|
||||
lockoutState.setAuthenticatorTo(userOne, BIOMETRIC_WEAK, true /* canAuthenticate */);
|
||||
assertThat(lockoutState.canUserAuthenticate(userOne, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(lockoutState.canUserAuthenticate(userOne, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(lockoutState.canUserAuthenticate(userOne, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(lockoutState.getLockoutState(userOne, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(lockoutState.getLockoutState(userOne, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(lockoutState.getLockoutState(userOne, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
|
||||
assertThat(lockoutState.canUserAuthenticate(userTwo, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(lockoutState.canUserAuthenticate(userTwo, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(lockoutState.canUserAuthenticate(userTwo, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
assertThat(lockoutState.getLockoutState(userTwo, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(lockoutState.getLockoutState(userTwo, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
assertThat(lockoutState.getLockoutState(userTwo, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_PERMANENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimedLockout() {
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
|
||||
mLockoutState.increaseLockoutTime(PRIMARY_USER, BIOMETRIC_STRONG,
|
||||
System.currentTimeMillis() + 1);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_TIMED);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_TIMED);
|
||||
assertThat(
|
||||
mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_TIMED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimedLockoutAfterDuration() {
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
|
||||
when(mClock.millis()).thenReturn(0L);
|
||||
mLockoutState.increaseLockoutTime(PRIMARY_USER, BIOMETRIC_STRONG, 1);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isFalse();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isFalse();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_TIMED);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_TIMED);
|
||||
assertThat(
|
||||
mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isFalse();
|
||||
mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_TIMED);
|
||||
|
||||
when(mClock.millis()).thenReturn(2L);
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_STRONG)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_WEAK)).isTrue();
|
||||
assertThat(mLockoutState.canUserAuthenticate(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isTrue();
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_STRONG)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_WEAK)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
assertThat(mLockoutState.getLockoutState(PRIMARY_USER, BIOMETRIC_CONVENIENCE)).isEqualTo(
|
||||
LockoutTracker.LOCKOUT_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ 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.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.LockoutCache;
|
||||
import com.android.server.biometrics.sensors.face.UsageStats;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -85,8 +84,6 @@ public class FaceAuthenticationClientTest {
|
||||
@Mock
|
||||
private BiometricContext mBiometricContext;
|
||||
@Mock
|
||||
private LockoutCache mLockoutCache;
|
||||
@Mock
|
||||
private UsageStats mUsageStats;
|
||||
@Mock
|
||||
private ClientMonitorCallback mCallback;
|
||||
@@ -161,7 +158,7 @@ public class FaceAuthenticationClientTest {
|
||||
false /* restricted */, "test-owner", 4 /* cookie */,
|
||||
false /* requireConfirmation */, 9 /* sensorId */,
|
||||
mBiometricLogger, mBiometricContext, true /* isStrongBiometric */,
|
||||
mUsageStats, mLockoutCache, false /* allowBackgroundAuthentication */,
|
||||
mUsageStats, null /* mLockoutCache */, false /* allowBackgroundAuthentication */,
|
||||
false /* isKeyguardBypassEnabled */, null /* sensorPrivacyManager */,
|
||||
0 /* biometricStrength */) {
|
||||
@Override
|
||||
|
||||
@@ -63,7 +63,6 @@ import com.android.server.biometrics.log.Probe;
|
||||
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallback;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.LockoutCache;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@@ -114,8 +113,6 @@ public class FingerprintAuthenticationClientTest {
|
||||
@Mock
|
||||
private BiometricManager mBiometricManager;
|
||||
@Mock
|
||||
private LockoutCache mLockoutCache;
|
||||
@Mock
|
||||
private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Mock
|
||||
private ISidefpsController mSideFpsController;
|
||||
@@ -658,7 +655,7 @@ public class FingerprintAuthenticationClientTest {
|
||||
false /* requireConfirmation */,
|
||||
9 /* sensorId */, mBiometricLogger, mBiometricContext,
|
||||
true /* isStrongBiometric */,
|
||||
null /* taskStackListener */, mLockoutCache,
|
||||
null /* taskStackListener */, null /* lockoutCache */,
|
||||
mUdfpsOverlayController, mSideFpsController, null, allowBackgroundAuthentication,
|
||||
mSensorProps,
|
||||
new Handler(mLooper.getLooper()), 0 /* biometricStrength */, mClock) {
|
||||
|
||||
Reference in New Issue
Block a user