Update biometric test paths
1) Test HALs should always respond to enumerate with no enrollments. CTS tests use this path to consciously remove (framework) enrollments when cleaning up. 2) Removes unnecessary TestSession classes from AIDL providers. These are redundant with the existing sessions returned from the TestHals themselves. We just need the framework to retrieve a new HAL session (from either the real HAL or the test HAL) whenever changing between test and non-test modes Test: atest CtsBiometricsTestCases Test: atest com.android.server.biometrics Fixes: 179949545 Fixes: 179856730 Change-Id: I1bbf0b77c69a36c9065193d10be32e942af8db70
This commit is contained in:
@@ -436,13 +436,7 @@ public class Sensor implements IBinder.DeathRecipient {
|
||||
mScheduler = new BiometricScheduler(tag, null /* gestureAvailabilityDispatcher */);
|
||||
mLockoutCache = new LockoutCache();
|
||||
mAuthenticatorIds = new HashMap<>();
|
||||
mLazySession = () -> {
|
||||
if (mTestHalEnabled) {
|
||||
return new TestSession(mCurrentSession.mHalSessionCallback);
|
||||
} else {
|
||||
return mCurrentSession != null ? mCurrentSession.mSession : null;
|
||||
}
|
||||
};
|
||||
mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
|
||||
}
|
||||
|
||||
@NonNull HalClientMonitor.LazyDaemon<ISession> getLazySession() {
|
||||
@@ -499,6 +493,10 @@ public class Sensor implements IBinder.DeathRecipient {
|
||||
|
||||
void setTestHalEnabled(boolean enabled) {
|
||||
Slog.w(mTag, "setTestHalEnabled: " + enabled);
|
||||
if (enabled != mTestHalEnabled) {
|
||||
// The framework should retrieve a new session from the HAL.
|
||||
mCurrentSession = null;
|
||||
}
|
||||
mTestHalEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package com.android.server.biometrics.sensors.face.aidl;
|
||||
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.face.Error;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
import android.hardware.biometrics.face.ISessionCallback;
|
||||
import android.hardware.biometrics.face.SensorProps;
|
||||
import android.hardware.common.NativeHandle;
|
||||
import android.hardware.keymaster.HardwareAuthToken;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
/**
|
||||
@@ -38,70 +40,96 @@ public class TestHal extends IFace.Stub {
|
||||
|
||||
@Override
|
||||
public ISession createSession(int sensorId, int userId, ISessionCallback cb) {
|
||||
Slog.w(TAG, "createSession, sensorId: " + sensorId + " userId: " + userId);
|
||||
|
||||
return new ISession.Stub() {
|
||||
@Override
|
||||
public void generateChallenge(int cookie, int timeoutSec) {
|
||||
public void generateChallenge(int cookie, int timeoutSec) throws RemoteException {
|
||||
Slog.w(TAG, "generateChallenge, cookie: " + cookie);
|
||||
cb.onChallengeGenerated(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokeChallenge(int cookie, long challenge) {
|
||||
public void revokeChallenge(int cookie, long challenge) throws RemoteException {
|
||||
Slog.w(TAG, "revokeChallenge: " + challenge + ", cookie: " + cookie);
|
||||
cb.onChallengeRevoked(challenge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal enroll(int cookie, HardwareAuthToken hat,
|
||||
byte enrollmentType, byte[] features, NativeHandle previewSurface) {
|
||||
Slog.w(TAG, "enroll, cookie: " + cookie);
|
||||
return null;
|
||||
return new ICancellationSignal.Stub() {
|
||||
@Override
|
||||
public void cancel() throws RemoteException {
|
||||
cb.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal authenticate(int cookie, long operationId) {
|
||||
Slog.w(TAG, "authenticate, cookie: " + cookie);
|
||||
return null;
|
||||
return new ICancellationSignal.Stub() {
|
||||
@Override
|
||||
public void cancel() throws RemoteException {
|
||||
cb.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal detectInteraction(int cookie) {
|
||||
Slog.w(TAG, "detectInteraction, cookie: " + cookie);
|
||||
return null;
|
||||
return new ICancellationSignal.Stub() {
|
||||
@Override
|
||||
public void cancel() throws RemoteException {
|
||||
cb.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enumerateEnrollments(int cookie) {
|
||||
public void enumerateEnrollments(int cookie) throws RemoteException {
|
||||
Slog.w(TAG, "enumerateEnrollments, cookie: " + cookie);
|
||||
cb.onEnrollmentsEnumerated(new int[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEnrollments(int cookie, int[] enrollmentIds) {
|
||||
public void removeEnrollments(int cookie, int[] enrollmentIds) throws RemoteException {
|
||||
Slog.w(TAG, "removeEnrollments, cookie: " + cookie);
|
||||
cb.onEnrollmentsRemoved(enrollmentIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFeatures(int cookie, int enrollmentId) {
|
||||
public void getFeatures(int cookie, int enrollmentId) throws RemoteException {
|
||||
Slog.w(TAG, "getFeatures, cookie: " + cookie);
|
||||
cb.onFeaturesRetrieved(new byte[0], enrollmentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFeature(int cookie, HardwareAuthToken hat, int enrollmentId,
|
||||
byte feature, boolean enabled) {
|
||||
byte feature, boolean enabled) throws RemoteException {
|
||||
Slog.w(TAG, "setFeature, cookie: " + cookie);
|
||||
cb.onFeatureSet(enrollmentId, feature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAuthenticatorId(int cookie) {
|
||||
public void getAuthenticatorId(int cookie) throws RemoteException {
|
||||
Slog.w(TAG, "getAuthenticatorId, cookie: " + cookie);
|
||||
cb.onAuthenticatorIdRetrieved(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateAuthenticatorId(int cookie) {
|
||||
public void invalidateAuthenticatorId(int cookie) throws RemoteException {
|
||||
Slog.w(TAG, "invalidateAuthenticatorId, cookie: " + cookie);
|
||||
cb.onAuthenticatorIdInvalidated(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLockout(int cookie, HardwareAuthToken hat) {
|
||||
public void resetLockout(int cookie, HardwareAuthToken hat) throws RemoteException {
|
||||
Slog.w(TAG, "resetLockout, cookie: " + cookie);
|
||||
cb.onLockoutCleared();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.face.Error;
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
import android.hardware.common.NativeHandle;
|
||||
import android.hardware.keymaster.HardwareAuthToken;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.util.Slog;
|
||||
|
||||
/**
|
||||
* Test session that provides mostly no-ops.
|
||||
*/
|
||||
public class TestSession extends ISession.Stub {
|
||||
private static final String TAG = "FaceTestSession";
|
||||
|
||||
@NonNull
|
||||
private final Sensor.HalSessionCallback mHalSessionCallback;
|
||||
|
||||
TestSession(@NonNull Sensor.HalSessionCallback halSessionCallback) {
|
||||
mHalSessionCallback = halSessionCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateChallenge(int cookie, int timeoutSec) {
|
||||
mHalSessionCallback.onChallengeGenerated(0 /* challenge */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokeChallenge(int cookie, long challenge) {
|
||||
mHalSessionCallback.onChallengeRevoked(challenge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal enroll(int cookie, HardwareAuthToken hat, byte enrollmentType,
|
||||
byte[] features, NativeHandle previewSurface) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal authenticate(int cookie, long operationId) {
|
||||
return new ICancellationSignal() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
mHalSessionCallback.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return new Binder();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal detectInteraction(int cookie) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enumerateEnrollments(int cookie) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEnrollments(int cookie, int[] enrollmentIds) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFeatures(int cookie, int enrollmentId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFeature(int cookie, HardwareAuthToken hat, int enrollmentId, byte feature,
|
||||
boolean enabled) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAuthenticatorId(int cookie) {
|
||||
Slog.d(TAG, "getAuthenticatorId");
|
||||
// Immediately return a value so the framework can continue with subsequent requests.
|
||||
mHalSessionCallback.onAuthenticatorIdRetrieved(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateAuthenticatorId(int cookie) {
|
||||
Slog.d(TAG, "invalidateAuthenticatorId");
|
||||
// Immediately return a value so the framework can continue with subsequent requests.
|
||||
mHalSessionCallback.onAuthenticatorIdInvalidated(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLockout(int cookie, HardwareAuthToken hat) {
|
||||
mHalSessionCallback.onLockoutCleared();
|
||||
}
|
||||
}
|
||||
@@ -98,8 +98,11 @@ public class TestHal extends IBiometricsFace.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enumerate() {
|
||||
public int enumerate() throws RemoteException {
|
||||
Slog.w(TAG, "enumerate");
|
||||
if (mCallback != null) {
|
||||
mCallback.onEnumerate(0 /* deviceId */, new ArrayList<>(), 0 /* userId */);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -416,13 +416,7 @@ class Sensor implements IBinder.DeathRecipient {
|
||||
mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher);
|
||||
mLockoutCache = new LockoutCache();
|
||||
mAuthenticatorIds = new HashMap<>();
|
||||
mLazySession = () -> {
|
||||
if (mTestHalEnabled) {
|
||||
return new TestSession(mCurrentSession.mHalSessionCallback);
|
||||
} else {
|
||||
return mCurrentSession != null ? mCurrentSession.mSession : null;
|
||||
}
|
||||
};
|
||||
mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
|
||||
}
|
||||
|
||||
@NonNull HalClientMonitor.LazyDaemon<ISession> getLazySession() {
|
||||
@@ -478,7 +472,11 @@ class Sensor implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
void setTestHalEnabled(boolean enabled) {
|
||||
Slog.w(mTag, "setTestHalEnabled, enabled");
|
||||
Slog.w(mTag, "setTestHalEnabled: " + enabled);
|
||||
if (enabled != mTestHalEnabled) {
|
||||
// The framework should retrieve a new session from the HAL.
|
||||
mCurrentSession = null;
|
||||
}
|
||||
mTestHalEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
package com.android.server.biometrics.sensors.fingerprint.aidl;
|
||||
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.fingerprint.Error;
|
||||
import android.hardware.biometrics.fingerprint.IFingerprint;
|
||||
import android.hardware.biometrics.fingerprint.ISession;
|
||||
import android.hardware.biometrics.fingerprint.ISessionCallback;
|
||||
import android.hardware.biometrics.fingerprint.SensorProps;
|
||||
import android.hardware.keymaster.HardwareAuthToken;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
/**
|
||||
@@ -38,58 +40,82 @@ public class TestHal extends IFingerprint.Stub {
|
||||
|
||||
@Override
|
||||
public ISession createSession(int sensorId, int userId, ISessionCallback cb) {
|
||||
Slog.w(TAG, "createSession, sensorId: " + sensorId + " userId: " + userId);
|
||||
|
||||
return new ISession.Stub() {
|
||||
@Override
|
||||
public void generateChallenge(int cookie, int timeoutSec) {
|
||||
public void generateChallenge(int cookie, int timeoutSec) throws RemoteException {
|
||||
Slog.w(TAG, "generateChallenge, cookie: " + cookie);
|
||||
cb.onChallengeGenerated(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokeChallenge(int cookie, long challenge) {
|
||||
public void revokeChallenge(int cookie, long challenge) throws RemoteException {
|
||||
Slog.w(TAG, "revokeChallenge: " + challenge + ", cookie: " + cookie);
|
||||
cb.onChallengeRevoked(challenge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal enroll(int cookie, HardwareAuthToken hat) {
|
||||
Slog.w(TAG, "enroll, cookie: " + cookie);
|
||||
return null;
|
||||
return new ICancellationSignal.Stub() {
|
||||
@Override
|
||||
public void cancel() throws RemoteException {
|
||||
cb.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal authenticate(int cookie, long operationId) {
|
||||
Slog.w(TAG, "authenticate, cookie: " + cookie);
|
||||
return null;
|
||||
return new ICancellationSignal.Stub() {
|
||||
@Override
|
||||
public void cancel() throws RemoteException {
|
||||
cb.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal detectInteraction(int cookie) {
|
||||
Slog.w(TAG, "detectInteraction, cookie: " + cookie);
|
||||
return null;
|
||||
return new ICancellationSignal.Stub() {
|
||||
@Override
|
||||
public void cancel() throws RemoteException {
|
||||
cb.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enumerateEnrollments(int cookie) {
|
||||
public void enumerateEnrollments(int cookie) throws RemoteException {
|
||||
Slog.w(TAG, "enumerateEnrollments, cookie: " + cookie);
|
||||
cb.onEnrollmentsEnumerated(new int[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEnrollments(int cookie, int[] enrollmentIds) {
|
||||
public void removeEnrollments(int cookie, int[] enrollmentIds) throws RemoteException {
|
||||
Slog.w(TAG, "removeEnrollments, cookie: " + cookie);
|
||||
cb.onEnrollmentsRemoved(enrollmentIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAuthenticatorId(int cookie) {
|
||||
public void getAuthenticatorId(int cookie) throws RemoteException {
|
||||
Slog.w(TAG, "getAuthenticatorId, cookie: " + cookie);
|
||||
cb.onAuthenticatorIdRetrieved(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateAuthenticatorId(int cookie) {
|
||||
public void invalidateAuthenticatorId(int cookie) throws RemoteException {
|
||||
Slog.w(TAG, "invalidateAuthenticatorId, cookie: " + cookie);
|
||||
cb.onAuthenticatorIdInvalidated(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLockout(int cookie, HardwareAuthToken hat) {
|
||||
public void resetLockout(int cookie, HardwareAuthToken hat) throws RemoteException {
|
||||
Slog.w(TAG, "resetLockout, cookie: " + cookie);
|
||||
cb.onLockoutCleared();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.fingerprint.aidl;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.face.Error;
|
||||
import android.hardware.biometrics.fingerprint.ISession;
|
||||
import android.hardware.keymaster.HardwareAuthToken;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.util.Slog;
|
||||
|
||||
/**
|
||||
* Test session that provides mostly no-ops.
|
||||
*/
|
||||
class TestSession extends ISession.Stub {
|
||||
|
||||
private static final String TAG = "FingerprintTestSession";
|
||||
|
||||
@NonNull private final Sensor.HalSessionCallback mHalSessionCallback;
|
||||
|
||||
TestSession(@NonNull Sensor.HalSessionCallback halSessionCallback) {
|
||||
mHalSessionCallback = halSessionCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateChallenge(int cookie, int timeoutSec) {
|
||||
mHalSessionCallback.onChallengeGenerated(0 /* challenge */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokeChallenge(int cookie, long challenge) {
|
||||
mHalSessionCallback.onChallengeRevoked(challenge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal enroll(int cookie, HardwareAuthToken hat) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal authenticate(int cookie, long operationId) {
|
||||
return new ICancellationSignal() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
mHalSessionCallback.onError(Error.CANCELED, 0 /* vendorCode */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return new Binder();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal detectInteraction(int cookie) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enumerateEnrollments(int cookie) {
|
||||
Slog.d(TAG, "enumerate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEnrollments(int cookie, int[] enrollmentIds) {
|
||||
Slog.d(TAG, "remove");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAuthenticatorId(int cookie) {
|
||||
Slog.d(TAG, "getAuthenticatorId");
|
||||
// Immediately return a value so the framework can continue with subsequent requests.
|
||||
mHalSessionCallback.onAuthenticatorIdRetrieved(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateAuthenticatorId(int cookie) {
|
||||
Slog.d(TAG, "invalidateAuthenticatorId");
|
||||
// Immediately return a value so the framework can continue with subsequent requests.
|
||||
mHalSessionCallback.onAuthenticatorIdInvalidated(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLockout(int cookie, HardwareAuthToken hat) {
|
||||
mHalSessionCallback.onLockoutCleared();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointerDown(int pointerId, int x, int y, float minor, float major) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointerUp(int pointerId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUiReady() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,12 @@ public class TestHal extends IBiometricsFingerprint.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enumerate() {
|
||||
public int enumerate() throws RemoteException {
|
||||
Slog.w(TAG, "Enumerate");
|
||||
if (mCallback != null) {
|
||||
mCallback.onEnumerate(0 /* deviceId */, 0 /* fingerId */, 0 /* groupId */,
|
||||
0 /* remaining */);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user