Update framework for fingerprint and multi-biometric CTS

Bug: 173453845
Test: atest CtsBiometricsTestCases

Change-Id: I9d43f362570a2b610af7bfb07c112e0904acc8f4
This commit is contained in:
Kevin Chyn
2020-11-17 22:35:55 -08:00
parent 9a654b2886
commit fdf810a455
9 changed files with 89 additions and 25 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -500,7 +500,11 @@ public class BiometricService extends SystemService {
final List<SensorPropertiesInternal> 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<? extends SensorPropertiesInternal> ...
final SensorPropertiesInternal prop = SensorPropertiesInternal
.from(sensor.impl.getSensorProperties(opPackageName));
sensors.add(prop);
}
return sensors;

View File

@@ -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());

View File

@@ -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 */);
}

View File

@@ -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()) {

View File

@@ -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

View File

@@ -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

View File

@@ -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()) {