Merge "Revert "Update face detectInteraction"" into sc-dev

This commit is contained in:
Wei Wang
2021-04-10 01:45:35 +00:00
committed by Android (Google) Code Review
19 changed files with 46 additions and 275 deletions

View File

@@ -96,7 +96,6 @@ public class FaceSensorPropertiesInternal extends SensorPropertiesInternal {
@Override @Override
public String toString() { public String toString() {
return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;
+ ", SupportsFaceDetection: " + supportsFaceDetection;
} }
} }

View File

@@ -2137,14 +2137,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// Scan even when encrypted or timeout to show a preemptive bouncer when bypassing. // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
// Lock-down mode shouldn't scan, since it is more explicit. // Lock-down mode shouldn't scan, since it is more explicit.
boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer); boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
&& !isLockDown;
// If the device supports face detection (without authentication), allow it to happen
// if the device is in lockdown mode. Otherwise, prevent scanning.
boolean supportsDetectOnly = mFaceSensorProperties.get(0).supportsFaceDetection;
if (isLockDown && !supportsDetectOnly) {
strongAuthAllowsScanning = false;
}
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware. // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.

View File

@@ -19,13 +19,10 @@ package com.android.server.biometrics;
import static android.hardware.biometrics.BiometricManager.Authenticators; import static android.hardware.biometrics.BiometricManager.Authenticators;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Slog; import android.util.Slog;
@@ -65,7 +62,6 @@ public abstract class BiometricSensor {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@interface SensorState {} @interface SensorState {}
@NonNull private final Context mContext;
public final int id; public final int id;
public final @Authenticators.Types int oemStrength; // strength as configured by the OEM public final @Authenticators.Types int oemStrength; // strength as configured by the OEM
public final int modality; public final int modality;
@@ -88,9 +84,8 @@ public abstract class BiometricSensor {
*/ */
abstract boolean confirmationSupported(); abstract boolean confirmationSupported();
BiometricSensor(@NonNull Context context, int id, int modality, BiometricSensor(int id, int modality, @Authenticators.Types int strength,
@Authenticators.Types int strength, IBiometricAuthenticator impl) { IBiometricAuthenticator impl) {
this.mContext = context;
this.id = id; this.id = id;
this.modality = modality; this.modality = modality;
this.oemStrength = strength; this.oemStrength = strength;
@@ -174,19 +169,12 @@ public abstract class BiometricSensor {
@Override @Override
public String toString() { public String toString() {
SensorPropertiesInternal properties = null;
try {
properties = impl.getSensorProperties(mContext.getOpPackageName());
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
}
return "ID(" + id + ")" return "ID(" + id + ")"
+ ", oemStrength: " + oemStrength + ", oemStrength: " + oemStrength
+ ", updatedStrength: " + mUpdatedStrength + ", updatedStrength: " + mUpdatedStrength
+ ", modality " + modality + ", modality " + modality
+ ", state: " + mSensorState + ", state: " + mSensorState
+ ", cookie: " + mCookie + ", cookie: " + mCookie
+ ", props: " + properties; + ", authenticator: " + impl;
} }
} }

View File

@@ -725,7 +725,7 @@ public class BiometricService extends SystemService {
} }
} }
mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) { mSensors.add(new BiometricSensor(id, modality, strength, authenticator) {
@Override @Override
boolean confirmationAlwaysRequired(int userId) { boolean confirmationAlwaysRequired(int userId) {
return mSettingObserver.getConfirmationAlwaysRequired(modality, userId); return mSettingObserver.getConfirmationAlwaysRequired(modality, userId);
@@ -1351,8 +1351,13 @@ public class BiometricService extends SystemService {
for (BiometricSensor sensor : mSensors) { for (BiometricSensor sensor : mSensors) {
pw.println(" " + sensor); pw.println(" " + sensor);
} }
pw.println();
pw.println("CurrentSession: " + mCurrentAuthSession); pw.println("CurrentSession: " + mCurrentAuthSession);
pw.println();
final List<FingerprintSensorPropertiesInternal> fpProps =
mInjector.getFingerprintSensorProperties(getContext());
pw.println("FingerprintSensorProperties: " + fpProps.size());
for (FingerprintSensorPropertiesInternal prop : fpProps) {
pw.println(" " + prop);
}
} }
} }

View File

@@ -559,21 +559,22 @@ public class BiometricScheduler {
} }
/** /**
* Requests to cancel authentication or detection. * Requests to cancel authentication.
* @param token from the caller, should match the token passed in when requesting authentication * @param token from the caller, should match the token passed in when requesting authentication
*/ */
public void cancelAuthenticationOrDetection(IBinder token) { public void cancelAuthentication(IBinder token) {
if (mCurrentOperation == null) { if (mCurrentOperation == null) {
Slog.e(getTag(), "Unable to cancel authentication, null operation"); Slog.e(getTag(), "Unable to cancel authentication, null operation");
return; return;
} }
final boolean isCorrectClient = isAuthenticationOrDetectionOperation(mCurrentOperation); final boolean isAuthenticating =
mCurrentOperation.mClientMonitor instanceof AuthenticationConsumer;
final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token; final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token;
if (isCorrectClient && tokenMatches) { if (isAuthenticating && tokenMatches) {
Slog.d(getTag(), "Cancelling: " + mCurrentOperation); Slog.d(getTag(), "Cancelling authentication: " + mCurrentOperation);
cancelInternal(mCurrentOperation); cancelInternal(mCurrentOperation);
} else if (!isCorrectClient) { } else if (!isAuthenticating) {
// Look through the current queue for all authentication clients for the specified // Look through the current queue for all authentication clients for the specified
// token, and mark them as STATE_WAITING_IN_QUEUE_CANCELING. Note that we're marking // token, and mark them as STATE_WAITING_IN_QUEUE_CANCELING. Note that we're marking
// all of them, instead of just the first one, since the API surface currently doesn't // all of them, instead of just the first one, since the API surface currently doesn't
@@ -581,7 +582,7 @@ public class BiometricScheduler {
// process. However, this generally does not happen anyway, and would be a class of // process. However, this generally does not happen anyway, and would be a class of
// bugs on its own. // bugs on its own.
for (Operation operation : mPendingOperations) { for (Operation operation : mPendingOperations) {
if (isAuthenticationOrDetectionOperation(operation) if (operation.mClientMonitor instanceof AuthenticationConsumer
&& operation.mClientMonitor.getToken() == token) { && operation.mClientMonitor.getToken() == token) {
Slog.d(getTag(), "Marking " + operation Slog.d(getTag(), "Marking " + operation
+ " as STATE_WAITING_IN_QUEUE_CANCELING"); + " as STATE_WAITING_IN_QUEUE_CANCELING");
@@ -591,13 +592,6 @@ public class BiometricScheduler {
} }
} }
private boolean isAuthenticationOrDetectionOperation(@NonNull Operation operation) {
final boolean isAuthentication = operation.mClientMonitor
instanceof AuthenticationConsumer;
final boolean isDetection = operation.mClientMonitor instanceof DetectionConsumer;
return isAuthentication || isDetection;
}
/** /**
* @return the current operation * @return the current operation
*/ */

View File

@@ -1,24 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.biometrics.sensors;
/**
* Interface that clients interested/eligible for interaction detection events should implement.
*/
public interface DetectionConsumer {
void onInteractionDetected();
}

View File

@@ -296,15 +296,7 @@ public class FaceService extends SystemService implements BiometricServiceCallba
return; return;
} }
final Pair<Integer, ServiceProvider> provider = getSingleProvider(); // TODO(b/152413782): Implement this once it's supported in the HAL
if (provider == null) {
Slog.w(TAG, "Null provider for detectFace");
return;
}
provider.second.scheduleFaceDetect(provider.first, token, userId,
new ClientMonitorCallbackConverter(receiver), opPackageName,
BiometricsProtoEnums.CLIENT_KEYGUARD);
} }
@Override // Binder call @Override // Binder call
@@ -361,13 +353,7 @@ public class FaceService extends SystemService implements BiometricServiceCallba
return; return;
} }
final Pair<Integer, ServiceProvider> provider = getSingleProvider(); // TODO(b/152413782): Implement this once it's supported in the HAL
if (provider == null) {
Slog.w(TAG, "Null provider for cancelFaceDetect");
return;
}
provider.second.cancelFaceDetect(provider.first, token);
} }
@Override // Binder call @Override // Binder call

View File

@@ -101,17 +101,12 @@ public interface ServiceProvider {
void cancelEnrollment(int sensorId, @NonNull IBinder token); void cancelEnrollment(int sensorId, @NonNull IBinder token);
void scheduleFaceDetect(int sensorId, @NonNull IBinder token, int userId,
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
int statsClient);
void cancelFaceDetect(int sensorId, @NonNull IBinder token);
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId, void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
int cookie, @NonNull ClientMonitorCallbackConverter callback, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient, @NonNull String opPackageName, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication); boolean allowBackgroundAuthentication);
void cancelAuthentication(int sensorId, @NonNull IBinder token); void cancelAuthentication(int sensorId, @NonNull IBinder token);
void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId, void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,

View File

@@ -1,102 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.biometrics.sensors.face.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.face.ISession;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.DetectionConsumer;
/**
* Performs face detection without exposing any matching information (e.g. accept/reject have the
* same haptic, lockout counter is not increased).
*/
public class FaceDetectClient extends AcquisitionClient<ISession> implements DetectionConsumer {
private static final String TAG = "FaceDetectClient";
private final boolean mIsStrongBiometric;
@Nullable private ICancellationSignal mCancellationSignal;
public FaceDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
@NonNull String owner, int sensorId, boolean isStrongBiometric, int statsClient) {
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
BiometricsProtoEnums.MODALITY_FACE, BiometricsProtoEnums.ACTION_AUTHENTICATE,
statsClient);
mIsStrongBiometric = isStrongBiometric;
}
@Override
public void start(@NonNull Callback callback) {
super.start(callback);
startHalOperation();
}
@Override
protected void stopHalOperation() {
try {
mCancellationSignal.cancel();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
mCallback.onClientFinished(this, false /* success */);
}
}
@Override
protected void startHalOperation() {
try {
mCancellationSignal = getFreshDaemon().detectInteraction();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting face detect", e);
mCallback.onClientFinished(this, false /* success */);
}
}
@Override
public void onInteractionDetected() {
vibrateSuccess();
try {
getListener().onDetected(getSensorId(), getTargetUserId(), mIsStrongBiometric);
mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when sending onDetected", e);
mCallback.onClientFinished(this, false /* success */);
}
}
@Override
public int getProtoEnum() {
return BiometricsProto.CM_DETECT_INTERACTION;
}
@Override
public boolean interruptsPrecedingClients() {
return true;
}
}

View File

@@ -110,7 +110,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
Slog.e(getTag(), "Stopping background authentication, top: " Slog.e(getTag(), "Stopping background authentication, top: "
+ topPackage + " currentClient: " + client); + topPackage + " currentClient: " + client);
mSensors.valueAt(i).getScheduler() mSensors.valueAt(i).getScheduler()
.cancelAuthenticationOrDetection(client.getToken()); .cancelAuthentication(client.getToken());
} }
} }
} }
@@ -145,7 +145,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal( final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
prop.commonProps.sensorId, prop.commonProps.sensorStrength, prop.commonProps.sensorId, prop.commonProps.sensorStrength,
prop.commonProps.maxEnrollmentsPerUser, componentInfo, prop.sensorType, prop.commonProps.maxEnrollmentsPerUser, componentInfo, prop.sensorType,
prop.supportsDetectInteraction, prop.halControlsPreview, false /* supportsFaceDetection */, prop.halControlsPreview,
false /* resetLockoutRequiresChallenge */); false /* resetLockoutRequiresChallenge */);
final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler, final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
internalProp); internalProp);
@@ -345,25 +345,6 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelEnrollment(token)); mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelEnrollment(token));
} }
@Override
public void scheduleFaceDetect(int sensorId, @NonNull IBinder token,
int userId, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, int statsClient) {
mHandler.post(() -> {
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FaceDetectClient client = new FaceDetectClient(mContext,
mSensors.get(sensorId).getLazySession(), token, callback, userId, opPackageName,
sensorId, isStrongBiometric, statsClient);
scheduleForSensor(sensorId, client);
});
}
@Override
public void cancelFaceDetect(int sensorId, @NonNull IBinder token) {
mHandler.post(() -> mSensors.get(sensorId).getScheduler()
.cancelAuthenticationOrDetection(token));
}
@Override @Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback, int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@@ -383,8 +364,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
@Override @Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) { public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
mHandler.post(() -> mSensors.get(sensorId).getScheduler() mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelAuthentication(token));
.cancelAuthenticationOrDetection(token));
} }
@Override @Override

View File

@@ -338,17 +338,7 @@ public class Sensor {
@Override @Override
public void onInteractionDetected() { public void onInteractionDetected() {
mHandler.post(() -> { // no-op
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof FaceDetectClient)) {
Slog.e(mTag, "onInteractionDetected for wrong client: "
+ Utils.getClientName(client));
return;
}
final FaceDetectClient detectClient = (FaceDetectClient) client;
detectClient.onInteractionDetected();
});
} }
@Override @Override

View File

@@ -638,20 +638,6 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}); });
} }
@Override
public void scheduleFaceDetect(int sensorId, @NonNull IBinder token,
int userId, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, int statsClient) {
throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
+ "forget to check the supportsFaceDetection flag?");
}
@Override
public void cancelFaceDetect(int sensorId, @NonNull IBinder token) {
throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
+ "forget to check the supportsFaceDetection flag?");
}
@Override @Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver, int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
@@ -672,7 +658,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
@Override @Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) { public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
mHandler.post(() -> { mHandler.post(() -> {
mScheduler.cancelAuthenticationOrDetection(token); mScheduler.cancelAuthentication(token);
}); });
} }

View File

@@ -57,12 +57,6 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> {
mUdfpsOverlayController = udfpsOverlayController; mUdfpsOverlayController = udfpsOverlayController;
} }
@Override
public void start(@NonNull Callback callback) {
super.start(callback);
startHalOperation();
}
@Override @Override
protected void stopHalOperation() { protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);

View File

@@ -115,7 +115,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
Slog.e(getTag(), "Stopping background authentication, top: " Slog.e(getTag(), "Stopping background authentication, top: "
+ topPackage + " currentClient: " + client); + topPackage + " currentClient: " + client);
mSensors.valueAt(i).getScheduler() mSensors.valueAt(i).getScheduler()
.cancelAuthenticationOrDetection(client.getToken()); .cancelAuthentication(client.getToken());
} }
} }
} }
@@ -383,8 +383,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
@Override @Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) { public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
mHandler.post(() -> mSensors.get(sensorId).getScheduler() mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelAuthentication(token));
.cancelAuthenticationOrDetection(token));
} }
@Override @Override

View File

@@ -144,7 +144,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
&& !client.isAlreadyDone()) { && !client.isAlreadyDone()) {
Slog.e(TAG, "Stopping background authentication, top: " Slog.e(TAG, "Stopping background authentication, top: "
+ topPackage + " currentClient: " + client); + topPackage + " currentClient: " + client);
mScheduler.cancelAuthenticationOrDetection(client.getToken()); mScheduler.cancelAuthentication(client.getToken());
} }
} }
}); });
@@ -645,7 +645,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
@Override @Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) { public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token)); mHandler.post(() -> mScheduler.cancelAuthentication(token));
} }
@Override @Override

View File

@@ -279,7 +279,7 @@ public class AuthSessionTest {
IBiometricAuthenticator fingerprintAuthenticator = mock(IBiometricAuthenticator.class); IBiometricAuthenticator fingerprintAuthenticator = mock(IBiometricAuthenticator.class);
when(fingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true); when(fingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
when(fingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); when(fingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
mSensors.add(new BiometricSensor(mContext, id, mSensors.add(new BiometricSensor(id,
TYPE_FINGERPRINT /* modality */, TYPE_FINGERPRINT /* modality */,
Authenticators.BIOMETRIC_STRONG /* strength */, Authenticators.BIOMETRIC_STRONG /* strength */,
fingerprintAuthenticator) { fingerprintAuthenticator) {
@@ -314,7 +314,7 @@ public class AuthSessionTest {
IBiometricAuthenticator authenticator) throws RemoteException { IBiometricAuthenticator authenticator) throws RemoteException {
when(authenticator.isHardwareDetected(any())).thenReturn(true); when(authenticator.isHardwareDetected(any())).thenReturn(true);
when(authenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); when(authenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
mSensors.add(new BiometricSensor(mContext, id, mSensors.add(new BiometricSensor(id,
TYPE_FACE /* modality */, TYPE_FACE /* modality */,
Authenticators.BIOMETRIC_STRONG /* strength */, Authenticators.BIOMETRIC_STRONG /* strength */,
authenticator) { authenticator) {

View File

@@ -1278,10 +1278,10 @@ public class BiometricServiceTest {
for (int i = 0; i < testCases.length; i++) { for (int i = 0; i < testCases.length; i++) {
final BiometricSensor sensor = final BiometricSensor sensor =
new BiometricSensor(mContext, 0 /* id */, new BiometricSensor(0 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT, BiometricAuthenticator.TYPE_FINGERPRINT,
testCases[i][0], testCases[i][0],
mock(IBiometricAuthenticator.class)) { null /* impl */) {
@Override @Override
boolean confirmationAlwaysRequired(int userId) { boolean confirmationAlwaysRequired(int userId) {
return false; return false;

View File

@@ -24,7 +24,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricManager.Authenticators; import android.hardware.biometrics.BiometricManager.Authenticators;
@@ -36,10 +35,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.BiometricService.InvalidationTracker; import com.android.server.biometrics.BiometricService.InvalidationTracker;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList; import java.util.ArrayList;
@@ -47,37 +43,29 @@ import java.util.ArrayList;
@SmallTest @SmallTest
public class InvalidationTrackerTest { public class InvalidationTrackerTest {
@Mock
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test @Test
public void testCallbackReceived_whenAllStrongSensorsInvalidated() throws Exception { public void testCallbackReceived_whenAllStrongSensorsInvalidated() throws Exception {
final IBiometricAuthenticator authenticator1 = mock(IBiometricAuthenticator.class); final IBiometricAuthenticator authenticator1 = mock(IBiometricAuthenticator.class);
when(authenticator1.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); when(authenticator1.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor1 = new TestSensor(mContext, 0 /* id */, final TestSensor sensor1 = new TestSensor(0 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
authenticator1); authenticator1);
final IBiometricAuthenticator authenticator2 = mock(IBiometricAuthenticator.class); final IBiometricAuthenticator authenticator2 = mock(IBiometricAuthenticator.class);
when(authenticator2.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); when(authenticator2.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor2 = new TestSensor(mContext, 1 /* id */, final TestSensor sensor2 = new TestSensor(1 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
authenticator2); authenticator2);
final IBiometricAuthenticator authenticator3 = mock(IBiometricAuthenticator.class); final IBiometricAuthenticator authenticator3 = mock(IBiometricAuthenticator.class);
when(authenticator3.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); when(authenticator3.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor3 = new TestSensor(mContext, 2 /* id */, final TestSensor sensor3 = new TestSensor(2 /* id */,
BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG, BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG,
authenticator3); authenticator3);
final IBiometricAuthenticator authenticator4 = mock(IBiometricAuthenticator.class); final IBiometricAuthenticator authenticator4 = mock(IBiometricAuthenticator.class);
when(authenticator4.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); when(authenticator4.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor4 = new TestSensor(mContext, 3 /* id */, final TestSensor sensor4 = new TestSensor(3 /* id */,
BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_WEAK, BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_WEAK,
authenticator4); authenticator4);
@@ -113,9 +101,8 @@ public class InvalidationTrackerTest {
private static class TestSensor extends BiometricSensor { private static class TestSensor extends BiometricSensor {
TestSensor(@NonNull Context context, int id, int modality, int strength, TestSensor(int id, int modality, int strength, IBiometricAuthenticator impl) {
@NonNull IBiometricAuthenticator impl) { super(id, modality, strength, impl);
super(context, id, modality, strength, impl);
} }
@Override @Override

View File

@@ -188,7 +188,7 @@ public class BiometricSchedulerTest {
// Request it to be canceled. The operation can be canceled immediately, and the scheduler // Request it to be canceled. The operation can be canceled immediately, and the scheduler
// should go back to idle, since in this case the framework has not even requested the HAL // should go back to idle, since in this case the framework has not even requested the HAL
// to authenticate yet. // to authenticate yet.
mScheduler.cancelAuthenticationOrDetection(mToken); mScheduler.cancelAuthentication(mToken);
assertNull(mScheduler.mCurrentOperation); assertNull(mScheduler.mCurrentOperation);
} }
@@ -298,7 +298,7 @@ public class BiometricSchedulerTest {
mScheduler.mPendingOperations.getFirst().mState); mScheduler.mPendingOperations.getFirst().mState);
// Request cancel before the authentication client has started // Request cancel before the authentication client has started
mScheduler.cancelAuthenticationOrDetection(mToken); mScheduler.cancelAuthentication(mToken);
waitForIdle(); waitForIdle();
assertEquals(Operation.STATE_WAITING_IN_QUEUE_CANCELING, assertEquals(Operation.STATE_WAITING_IN_QUEUE_CANCELING,
mScheduler.mPendingOperations.getFirst().mState); mScheduler.mPendingOperations.getFirst().mState);