From fdf810a455abd9374bd073d1554bbf006ff8b892 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 17 Nov 2020 22:35:55 -0800 Subject: [PATCH] Update framework for fingerprint and multi-biometric CTS Bug: 173453845 Test: atest CtsBiometricsTestCases Change-Id: I9d43f362570a2b610af7bfb07c112e0904acc8f4 --- .../biometrics/SensorPropertiesInternal.java | 16 +++++-- .../face/FaceSensorPropertiesInternal.java | 6 ++- .../server/biometrics/BiometricService.java | 6 ++- .../sensors/face/aidl/FaceProvider.java | 12 +++--- .../sensors/face/aidl/TestSession.java | 3 +- .../biometrics/sensors/face/hidl/Face10.java | 3 +- .../fingerprint/aidl/FingerprintProvider.java | 43 ++++++++++++++++++- .../sensors/fingerprint/aidl/TestSession.java | 23 +++++++--- .../fingerprint/hidl/Fingerprint21.java | 2 +- 9 files changed, 89 insertions(+), 25 deletions(-) diff --git a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java index 2189de0827b77..0b81c6c8cc25a 100644 --- a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java +++ b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java @@ -16,13 +16,10 @@ package android.hardware.biometrics; -import android.annotation.IntDef; +import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - /** * The base class containing all modality-agnostic information. This is a superset of the * {@link android.hardware.biometrics.common.CommonProps}, and provides backwards-compatible @@ -35,6 +32,11 @@ public class SensorPropertiesInternal implements Parcelable { @SensorProperties.Strength public final int sensorStrength; public final int maxEnrollmentsPerUser; + public static SensorPropertiesInternal from(@NonNull SensorPropertiesInternal prop) { + return new SensorPropertiesInternal(prop.sensorId, prop.sensorStrength, + prop.maxEnrollmentsPerUser); + } + protected SensorPropertiesInternal(int sensorId, @SensorProperties.Strength int sensorStrength, int maxEnrollmentsPerUser) { this.sensorId = sensorId; @@ -72,4 +74,10 @@ public class SensorPropertiesInternal implements Parcelable { dest.writeInt(sensorStrength); dest.writeInt(maxEnrollmentsPerUser); } + + @Override + public String toString() { + return "ID: " + sensorId + ", Strength: " + sensorStrength + + ", MaxEnrollmentsPerUser: " + maxEnrollmentsPerUser; + } } diff --git a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java index e91554b532b08..b9c0d12de22ba 100644 --- a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java +++ b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java @@ -19,7 +19,6 @@ package android.hardware.face; import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; import android.os.Parcel; -import android.os.Parcelable; /** * Container for face sensor properties. @@ -78,4 +77,9 @@ public class FaceSensorPropertiesInternal extends SensorPropertiesInternal { dest.writeBoolean(supportsFaceDetection); dest.writeBoolean(supportsSelfIllumination); } + + @Override + public String toString() { + return "ID: " + sensorId + ", Strength: " + sensorStrength; + } } diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index a471664b19b76..8494e515a406b 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -500,7 +500,11 @@ public class BiometricService extends SystemService { final List sensors = new ArrayList<>(); for (BiometricSensor sensor : mSensors) { - sensors.add(sensor.impl.getSensorProperties(opPackageName)); + // Explicitly re-create as the super class, since AIDL doesn't play nicely with + // "List ... + final SensorPropertiesInternal prop = SensorPropertiesInternal + .from(sensor.impl.getSensorProperties(opPackageName)); + sensors.add(prop); } return sensors; 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 26f62644e38bf..ea0d94974fbbe 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 @@ -65,7 +65,6 @@ import java.util.List; * Provider for a single instance of the {@link IFace} HAL. */ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { - private static final String TAG = "FaceProvider"; private static final int ENROLL_TIMEOUT_SEC = 75; private boolean mTestHalEnabled; @@ -88,7 +87,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { public void onTaskStackChanged() { mHandler.post(() -> { for (int i = 0; i < mSensors.size(); i++) { - final ClientMonitor client = mSensors.get(i).getScheduler() + final ClientMonitor client = mSensors.valueAt(i).getScheduler() .getCurrentClient(); if (!(client instanceof AuthenticationClient)) { Slog.e(getTag(), "Task stack changed for client: " + client); @@ -108,7 +107,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { && !client.isAlreadyDone()) { Slog.e(getTag(), "Stopping background authentication, top: " + topPackage + " currentClient: " + client); - mSensors.get(i).getScheduler() + mSensors.valueAt(i).getScheduler() .cancelAuthentication(client.getToken()); } } @@ -550,12 +549,13 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { JSONObject dump = new JSONObject(); try { - dump.put("service", "Face Manager"); + dump.put("service", getTag()); JSONArray sets = new JSONArray(); for (UserInfo user : UserManager.get(mContext).getUsers()) { final int userId = user.getUserHandle().getIdentifier(); - final int c = FaceUtils.getInstance().getBiometricsForUser(mContext, userId).size(); + final int c = FaceUtils.getInstance(sensorId) + .getBiometricsForUser(mContext, userId).size(); JSONObject set = new JSONObject(); set.put("id", userId); set.put("count", c); @@ -574,7 +574,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { dump.put("prints", sets); } catch (JSONException e) { - Slog.e(TAG, "dump formatting failure", e); + Slog.e(getTag(), "dump formatting failure", e); } pw.println(dump); pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount()); 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 index 9707eddfee74d..fbc26c6498b30 100644 --- 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 @@ -24,7 +24,6 @@ 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. @@ -59,7 +58,7 @@ public class TestSession extends ISession.Stub { public ICancellationSignal authenticate(int cookie, long operationId) { return new ICancellationSignal() { @Override - public void cancel() throws RemoteException { + public void cancel() { mHalSessionCallback.onError(Error.CANCELED, 0 /* vendorCode */); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index 3555bbe629aed..dfc89272d14e3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -71,7 +71,6 @@ import com.android.server.biometrics.sensors.face.FaceUtils; import com.android.server.biometrics.sensors.face.LockoutHalImpl; import com.android.server.biometrics.sensors.face.ServiceProvider; import com.android.server.biometrics.sensors.face.UsageStats; -import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; import org.json.JSONArray; import org.json.JSONException; @@ -803,7 +802,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { JSONObject dump = new JSONObject(); try { - dump.put("service", "Face Manager"); + dump.put("service", TAG); JSONArray sets = new JSONArray(); for (UserInfo user : UserManager.get(mContext).getUsers()) { diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index db34d1444650a..98c32cbcfc4ae 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -53,6 +53,10 @@ import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDisp import com.android.server.biometrics.sensors.fingerprint.ServiceProvider; import com.android.server.biometrics.sensors.fingerprint.Udfps; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; @@ -84,7 +88,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi public void onTaskStackChanged() { mHandler.post(() -> { for (int i = 0; i < mSensors.size(); i++) { - final ClientMonitor client = mSensors.get(i).getScheduler() + final ClientMonitor client = mSensors.valueAt(i).getScheduler() .getCurrentClient(); if (!(client instanceof AuthenticationClient)) { Slog.e(getTag(), "Task stack changed for client: " + client); @@ -104,7 +108,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi && !client.isAlreadyDone()) { Slog.e(getTag(), "Stopping background authentication, top: " + topPackage + " currentClient: " + client); - mSensors.get(i).getScheduler() + mSensors.valueAt(i).getScheduler() .cancelAuthentication(client.getToken()); } } @@ -593,7 +597,42 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi @Override public void dumpInternal(int sensorId, @NonNull PrintWriter pw) { + PerformanceTracker performanceTracker = + PerformanceTracker.getInstanceForSensorId(sensorId); + JSONObject dump = new JSONObject(); + try { + dump.put("service", getTag()); + + JSONArray sets = new JSONArray(); + for (UserInfo user : UserManager.get(mContext).getUsers()) { + final int userId = user.getUserHandle().getIdentifier(); + final int c = FingerprintUtils.getInstance(sensorId) + .getBiometricsForUser(mContext, userId).size(); + JSONObject set = new JSONObject(); + set.put("id", userId); + set.put("count", c); + set.put("accept", performanceTracker.getAcceptForUser(userId)); + set.put("reject", performanceTracker.getRejectForUser(userId)); + set.put("acquire", performanceTracker.getAcquireForUser(userId)); + set.put("lockout", performanceTracker.getTimedLockoutForUser(userId)); + set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId)); + // cryptoStats measures statistics about secure fingerprint transactions + // (e.g. to unlock password storage, make secure purchases, etc.) + set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId)); + set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId)); + set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId)); + sets.put(set); + } + + dump.put("prints", sets); + } catch (JSONException e) { + Slog.e(getTag(), "dump formatting failure", e); + } + pw.println(dump); + pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount()); + + mSensors.get(sensorId).getScheduler().dump(pw); } @NonNull 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 d6378780594f3..ddae1107ff77b 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 @@ -18,8 +18,11 @@ 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; /** @@ -37,24 +40,32 @@ class TestSession extends ISession.Stub { @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) { - Slog.d(TAG, "enroll"); return null; } @Override public ICancellationSignal authenticate(int cookie, long operationId) { - Slog.d(TAG, "authenticate"); - return null; + return new ICancellationSignal() { + @Override + public void cancel() { + mHalSessionCallback.onError(Error.CANCELED, 0 /* vendorCode */); + } + + @Override + public IBinder asBinder() { + return new Binder(); + } + }; } @Override @@ -86,7 +97,7 @@ class TestSession extends ISession.Stub { @Override public void resetLockout(int cookie, HardwareAuthToken hat) { - + mHalSessionCallback.onLockoutCleared(); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java index 11372a30599df..f38dd092007a3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java @@ -776,7 +776,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider JSONObject dump = new JSONObject(); try { - dump.put("service", "Fingerprint Manager"); + dump.put("service", TAG); JSONArray sets = new JSONArray(); for (UserInfo user : UserManager.get(mContext).getUsers()) {