diff options
| author | 2020-11-17 12:40:14 -0800 | |
|---|---|---|
| committer | 2020-11-17 20:02:56 -0800 | |
| commit | 0a60a1ce041f7265f1274d5bfdb1d648b585231e (patch) | |
| tree | b634f7de08cc9f891a9d9f6e6262571d1cd04b24 | |
| parent | fe03ccafaaf8f96b436dbf4565b65111b7f8c99d (diff) | |
Finish TestSession implementation for FaceProvider
Also moves static classes to top in face/aidl/Sensor.java
Bug: 173453845
Test: atest CtsBiometricsTestCases
Change-Id: I9220747161e3842494ac7d02c1c472037718a9f9
11 files changed, 585 insertions, 109 deletions
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java index 2784f46a96c2..e8e9b9a6b8f6 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java @@ -564,6 +564,11 @@ public class BiometricScheduler { public void dump(PrintWriter pw) { pw.println("Dump of BiometricScheduler " + getTag()); + pw.println("Current operation: " + mCurrentOperation); + pw.println("Pending operations: " + mPendingOperations.size()); + for (Operation operation : mPendingOperations) { + pw.println("Pending operation: " + operation); + } for (CrashState crashState : mCrashStates) { pw.println("Crash State " + crashState); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java new file mode 100644 index 000000000000..13bbb7e8a704 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java @@ -0,0 +1,205 @@ +/* + * 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 static android.Manifest.permission.TEST_BIOMETRIC; + +import android.annotation.NonNull; +import android.content.Context; +import android.hardware.biometrics.ITestSession; +import android.hardware.face.Face; +import android.hardware.face.IFaceServiceReceiver; +import android.os.Binder; +import android.util.Slog; + +import com.android.server.biometrics.HardwareAuthTokenUtils; +import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.face.FaceUtils; + +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * A test session implementation for {@link FaceProvider}. See + * {@link android.hardware.biometrics.BiometricTestSession}. + */ +public class BiometricTestSessionImpl extends ITestSession.Stub { + + private static final String TAG = "BiometricTestSessionImpl"; + + @NonNull private final Context mContext; + private final int mSensorId; + @NonNull private final FaceProvider mProvider; + @NonNull private final Sensor mSensor; + @NonNull private final Set<Integer> mEnrollmentIds; + @NonNull private final Random mRandom; + + /** + * Internal receiver currently only used for enroll. Results do not need to be forwarded to the + * test, since enrollment is a platform-only API. The authentication path is tested through + * the public BiometricPrompt APIs and does not use this receiver. + */ + private final IFaceServiceReceiver mReceiver = new IFaceServiceReceiver.Stub() { + @Override + public void onEnrollResult(Face face, int remaining) { + + } + + @Override + public void onAcquired(int acquireInfo, int vendorCode) { + + } + + @Override + public void onAuthenticationSucceeded(Face face, int userId, boolean isStrongBiometric) { + + } + + @Override + public void onFaceDetected(int sensorId, int userId, boolean isStrongBiometric) { + + } + + @Override + public void onAuthenticationFailed() { + + } + + @Override + public void onError(int error, int vendorCode) { + + } + + @Override + public void onRemoved(Face face, int remaining) { + + } + + @Override + public void onFeatureSet(boolean success, int feature) { + + } + + @Override + public void onFeatureGet(boolean success, int feature, boolean value) { + + } + + @Override + public void onChallengeGenerated(int sensorId, long challenge) { + + } + + @Override + public void onChallengeInterrupted(int sensorId) { + + } + + @Override + public void onChallengeInterruptFinished(int sensorId) { + + } + }; + + BiometricTestSessionImpl(@NonNull Context context, int sensorId, + @NonNull FaceProvider provider, @NonNull Sensor sensor) { + mContext = context; + mSensorId = sensorId; + mProvider = provider; + mSensor = sensor; + mEnrollmentIds = new HashSet<>(); + mRandom = new Random(); + } + + @Override + public void setTestHalEnabled(boolean enabled) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mProvider.setTestHalEnabled(enabled); + mSensor.setTestHalEnabled(enabled); + } + + @Override + public void startEnroll(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mProvider.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver, + mContext.getOpPackageName(), new int[0] /* disabledFeatures */, null /* surface */); + } + + @Override + public void finishEnroll(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + int nextRandomId = mRandom.nextInt(); + while (mEnrollmentIds.contains(nextRandomId)) { + nextRandomId = mRandom.nextInt(); + } + + mEnrollmentIds.add(nextRandomId); + mSensor.getSessionForUser(userId).mHalSessionCallback + .onEnrollmentProgress(nextRandomId, 0 /* remaining */); + } + + @Override + public void acceptAuthentication(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + // Fake authentication with any of the existing faces + List<Face> faces = FaceUtils.getInstance(mSensorId) + .getBiometricsForUser(mContext, userId); + if (faces.isEmpty()) { + Slog.w(TAG, "No faces, returning"); + return; + } + final int fid = faces.get(0).getBiometricId(); + mSensor.getSessionForUser(userId).mHalSessionCallback.onAuthenticationSucceeded(fid, + HardwareAuthTokenUtils.toHardwareAuthToken(new byte[69])); + } + + @Override + public void rejectAuthentication(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mSensor.getSessionForUser(userId).mHalSessionCallback.onAuthenticationFailed(); + } + + @Override + public void notifyAcquired(int userId, int acquireInfo) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mSensor.getSessionForUser(userId).mHalSessionCallback + .onAcquired((byte) acquireInfo, 0 /* vendorCode */); + } + + @Override + public void notifyError(int userId, int errorCode) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mSensor.getSessionForUser(userId).mHalSessionCallback.onError((byte) errorCode, + 0 /* vendorCode */); + } + + @Override + public void cleanupInternalState(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mProvider.scheduleInternalCleanup(mSensorId, userId); + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java index 3280e9815660..c27b6e5a4b7d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java @@ -47,6 +47,11 @@ class FaceGetAuthenticatorIdClient extends ClientMonitor<ISession> { // Nothing to do here } + public void start(@NonNull Callback callback) { + super.start(callback); + startHalOperation(); + } + @Override protected void startHalOperation() { try { diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index 01c16fd1f4a6..cb6b8d405635 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -67,6 +67,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { private static final String TAG = "FaceProvider"; private static final int ENROLL_TIMEOUT_SEC = 75; + private boolean mTestHalEnabled; + @NonNull private final Context mContext; @NonNull private final String mHalInstanceName; @NonNull private final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports @@ -150,6 +152,10 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { @Nullable private synchronized IFace getHalInstance() { + if (mTestHalEnabled) { + return new TestHal(); + } + if (mDaemon != null) { return mDaemon; } @@ -525,7 +531,9 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { @Override public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) { - + if (mSensors.contains(sensorId)) { + mSensors.get(sensorId).dumpProtoState(sensorId, proto); + } } @Override @@ -576,7 +584,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { @NonNull @Override public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { - return null; // TODO + return mSensors.get(sensorId).createTestSession(); } @Override @@ -590,4 +598,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { } }); } + + void setTestHalEnabled(boolean enabled) { + mTestHalEnabled = enabled; + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java index 5d100ec5e6dd..5b1f5465ea0a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java @@ -61,6 +61,11 @@ public class FaceResetLockoutClient extends ClientMonitor<ISession> { // Nothing to do here } + public void start(@NonNull Callback callback) { + super.start(callback); + startHalOperation(); + } + @Override protected void startHalOperation() { try { diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java index 2dd6e7375613..d9d473722fd5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java @@ -19,7 +19,9 @@ package com.android.server.biometrics.sensors.face.aidl; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.content.pm.UserInfo; import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.biometrics.ITestSession; import android.hardware.biometrics.face.Error; import android.hardware.biometrics.face.IFace; import android.hardware.biometrics.face.ISession; @@ -31,10 +33,15 @@ import android.hardware.keymaster.HardwareAuthToken; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.os.UserManager; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import com.android.internal.util.FrameworkStatsLog; import com.android.server.biometrics.HardwareAuthTokenUtils; +import com.android.server.biometrics.SensorServiceStateProto; +import com.android.server.biometrics.SensorStateProto; +import com.android.server.biometrics.UserStateProto; import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AcquisitionClient; import com.android.server.biometrics.sensors.AuthenticationConsumer; @@ -56,6 +63,8 @@ import java.util.Map; */ public class Sensor implements IBinder.DeathRecipient { + private boolean mTestHalEnabled; + @NonNull private final String mTag; @NonNull private final FaceProvider mProvider; @NonNull private final Context mContext; @@ -67,27 +76,6 @@ public class Sensor implements IBinder.DeathRecipient { @NonNull private final ClientMonitor.LazyDaemon<ISession> mLazySession; @Nullable private Session mCurrentSession; - @Override - public void binderDied() { - Slog.e(mTag, "Binder died"); - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (client instanceof Interruptable) { - Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client); - final Interruptable interruptable = (Interruptable) client; - interruptable.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE, - 0 /* vendorCode */); - - mScheduler.recordCrashState(); - - FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, - BiometricsProtoEnums.MODALITY_FACE, - BiometricsProtoEnums.ISSUE_HAL_DEATH); - mCurrentSession = null; - } - }); - } - static class Session { @NonNull final HalSessionCallback mHalSessionCallback; @NonNull private final String mTag; @@ -104,67 +92,6 @@ public class Sensor implements IBinder.DeathRecipient { } } - Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context, - @NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties) { - mTag = tag; - mProvider = provider; - mContext = context; - mHandler = handler; - mSensorProperties = sensorProperties; - mScheduler = new BiometricScheduler(tag, null /* gestureAvailabilityDispatcher */); - mLockoutCache = new LockoutCache(); - mAuthenticatorIds = new HashMap<>(); - mLazySession = () -> (mCurrentSession != null) ? mCurrentSession.mSession : null; - } - - @NonNull ClientMonitor.LazyDaemon<ISession> getLazySession() { - return mLazySession; - } - - @NonNull FaceSensorPropertiesInternal getSensorProperties() { - return mSensorProperties; - } - - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - boolean hasSessionForUser(int userId) { - return mCurrentSession != null && mCurrentSession.mUserId == userId; - } - - @Nullable Session getSessionForUser(int userId) { - if (mCurrentSession != null && mCurrentSession.mUserId == userId) { - return mCurrentSession; - } else { - return null; - } - } - - void createNewSession(@NonNull IFace daemon, int sensorId, int userId) - throws RemoteException { - - final HalSessionCallback.Callback callback = () -> { - Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE"); - mCurrentSession = null; - }; - final HalSessionCallback resultController = new HalSessionCallback(mContext, mHandler, - mTag, mScheduler, sensorId, userId, callback); - - final ISession newSession = daemon.createSession(sensorId, userId, resultController); - newSession.asBinder().linkToDeath(this, 0 /* flags */); - mCurrentSession = new Session(mTag, newSession, userId, resultController); - } - - @NonNull BiometricScheduler getScheduler() { - return mScheduler; - } - - @NonNull LockoutCache getLockoutCache() { - return mLockoutCache; - } - - @NonNull Map<Integer, Long> getAuthenticatorIds() { - return mAuthenticatorIds; - } - static class HalSessionCallback extends ISessionCallback.Stub { /** * Interface to sends results to the HalSessionCallback's owner. @@ -453,4 +380,120 @@ public class Sensor implements IBinder.DeathRecipient { } } + + Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context, + @NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties) { + mTag = tag; + mProvider = provider; + mContext = context; + mHandler = handler; + mSensorProperties = sensorProperties; + 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; + } + }; + } + + @NonNull ClientMonitor.LazyDaemon<ISession> getLazySession() { + return mLazySession; + } + + @NonNull FaceSensorPropertiesInternal getSensorProperties() { + return mSensorProperties; + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + boolean hasSessionForUser(int userId) { + return mCurrentSession != null && mCurrentSession.mUserId == userId; + } + + @Nullable Session getSessionForUser(int userId) { + if (mCurrentSession != null && mCurrentSession.mUserId == userId) { + return mCurrentSession; + } else { + return null; + } + } + + @NonNull ITestSession createTestSession() { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this); + } + + void createNewSession(@NonNull IFace daemon, int sensorId, int userId) + throws RemoteException { + + final HalSessionCallback.Callback callback = () -> { + Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE"); + mCurrentSession = null; + }; + final HalSessionCallback resultController = new HalSessionCallback(mContext, mHandler, + mTag, mScheduler, sensorId, userId, callback); + + final ISession newSession = daemon.createSession(sensorId, userId, resultController); + newSession.asBinder().linkToDeath(this, 0 /* flags */); + mCurrentSession = new Session(mTag, newSession, userId, resultController); + } + + @NonNull BiometricScheduler getScheduler() { + return mScheduler; + } + + @NonNull LockoutCache getLockoutCache() { + return mLockoutCache; + } + + @NonNull Map<Integer, Long> getAuthenticatorIds() { + return mAuthenticatorIds; + } + + void setTestHalEnabled(boolean enabled) { + mTestHalEnabled = enabled; + } + + void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) { + final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES); + + proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId); + proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null); + + for (UserInfo user : UserManager.get(mContext).getUsers()) { + final int userId = user.getUserHandle().getIdentifier(); + + final long userToken = proto.start(SensorStateProto.USER_STATES); + proto.write(UserStateProto.USER_ID, userId); + proto.write(UserStateProto.NUM_ENROLLED, + FaceUtils.getInstance(mSensorProperties.sensorId) + .getBiometricsForUser(mContext, userId).size()); + proto.end(userToken); + } + + proto.end(sensorToken); + } + + @Override + public void binderDied() { + Slog.e(mTag, "Binder died"); + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (client instanceof Interruptable) { + Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client); + final Interruptable interruptable = (Interruptable) client; + interruptable.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE, + 0 /* vendorCode */); + + mScheduler.recordCrashState(); + + FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, + BiometricsProtoEnums.MODALITY_FACE, + BiometricsProtoEnums.ISSUE_HAL_DEATH); + mCurrentSession = null; + } + }); + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java new file mode 100644 index 000000000000..34bf9bc63a64 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java @@ -0,0 +1,98 @@ +/* + * 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.hardware.biometrics.common.ICancellationSignal; +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.Binder; +import android.os.IBinder; + +/** + * Test HAL that provides only no-ops. + */ +public class TestHal extends IFace.Stub { + @Override + public SensorProps[] getSensorProps() { + return new SensorProps[0]; + } + + @Override + public ISession createSession(int sensorId, int userId, ISessionCallback cb) { + return new ISession() { + @Override + public void generateChallenge(int cookie, int timeoutSec) { + + } + + @Override + public void revokeChallenge(int cookie, long challenge) { + + } + + @Override + public ICancellationSignal enroll(int cookie, HardwareAuthToken hat, + NativeHandle previewSurface) { + return null; + } + + @Override + public ICancellationSignal authenticate(int cookie, long operationId) { + return null; + } + + @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 getAuthenticatorId(int cookie) { + + } + + @Override + public void invalidateAuthenticatorId(int cookie) { + + } + + @Override + public void resetLockout(int cookie, HardwareAuthToken hat) { + + } + + @Override + public IBinder asBinder() { + return new Binder(); + } + }; + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java new file mode 100644 index 000000000000..9707eddfee74 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java @@ -0,0 +1,102 @@ +/* + * 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.os.RemoteException; + +/** + * Test session that provides mostly no-ops. + */ +public class TestSession extends ISession.Stub { + private static final String TAG = "TestSession"; + + @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, + NativeHandle previewSurface) { + return null; + } + + @Override + public ICancellationSignal authenticate(int cookie, long operationId) { + return new ICancellationSignal() { + @Override + public void cancel() throws RemoteException { + 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 getAuthenticatorId(int cookie) { + mHalSessionCallback.onAuthenticatorIdRetrieved(0); + } + + @Override + public void invalidateAuthenticatorId(int cookie) { + + } + + @Override + public void resetLockout(int cookie, HardwareAuthToken hat) { + mHalSessionCallback.onLockoutCleared(); + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java index 973132533661..3f9aef2b8651 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java @@ -143,7 +143,7 @@ class BiometricTestSessionImpl extends ITestSession.Stub { Utils.checkPermission(mContext, TEST_BIOMETRIC); // Fake authentication with any of the existing fingers - List<Fingerprint> fingerprints = FingerprintUtils.getInstance() + List<Fingerprint> fingerprints = FingerprintUtils.getInstance(mSensorId) .getBiometricsForUser(mContext, userId); if (fingerprints.isEmpty()) { Slog.w(TAG, "No fingerprints, returning"); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java index 380608f1b0a9..ecb998594d44 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java @@ -80,27 +80,6 @@ class Sensor implements IBinder.DeathRecipient { @Nullable private Session mCurrentSession; @NonNull private final ClientMonitor.LazyDaemon<ISession> mLazySession; - @Override - public void binderDied() { - Slog.e(mTag, "Binder died"); - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (client instanceof Interruptable) { - Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client); - final Interruptable interruptable = (Interruptable) client; - interruptable.onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, - 0 /* vendorCode */); - - mScheduler.recordCrashState(); - - FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, - BiometricsProtoEnums.MODALITY_FINGERPRINT, - BiometricsProtoEnums.ISSUE_HAL_DEATH); - mCurrentSession = null; - } - }); - } - static class Session { @NonNull private final String mTag; @NonNull private final ISession mSession; @@ -501,11 +480,33 @@ class Sensor implements IBinder.DeathRecipient { final long userToken = proto.start(SensorStateProto.USER_STATES); proto.write(UserStateProto.USER_ID, userId); - proto.write(UserStateProto.NUM_ENROLLED, FingerprintUtils.getInstance() - .getBiometricsForUser(mContext, userId).size()); + proto.write(UserStateProto.NUM_ENROLLED, + FingerprintUtils.getInstance(mSensorProperties.sensorId) + .getBiometricsForUser(mContext, userId).size()); proto.end(userToken); } proto.end(sensorToken); } + + @Override + public void binderDied() { + Slog.e(mTag, "Binder died"); + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (client instanceof Interruptable) { + Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client); + final Interruptable interruptable = (Interruptable) client; + interruptable.onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, + 0 /* vendorCode */); + + mScheduler.recordCrashState(); + + FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, + BiometricsProtoEnums.MODALITY_FINGERPRINT, + BiometricsProtoEnums.ISSUE_HAL_DEATH); + mCurrentSession = null; + } + }); + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java index dd9150a32914..d6378780594f 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java @@ -23,7 +23,7 @@ import android.hardware.keymaster.HardwareAuthToken; import android.util.Slog; /** - * Test HAL that provides only provides mostly no-ops. + * Test session that provides mostly no-ops. */ class TestSession extends ISession.Stub { |