Merge "Added features to FaceEnrollClient" into sc-dev

This commit is contained in:
Joshua Mccloskey
2021-04-30 20:00:57 +00:00
committed by Android (Google) Code Review
4 changed files with 84 additions and 65 deletions

View File

@@ -26,17 +26,22 @@ import android.hardware.biometrics.face.Cell;
import android.hardware.biometrics.face.EnrollmentFrame;
import android.hardware.biometrics.face.EnrollmentStage;
import android.hardware.biometrics.face.Error;
import android.hardware.biometrics.face.Feature;
import android.hardware.face.FaceAuthenticationFrame;
import android.hardware.face.FaceDataFrame;
import android.hardware.face.FaceEnrollCell;
import android.hardware.face.FaceEnrollFrame;
import android.hardware.face.FaceEnrollStages;
import android.hardware.face.FaceEnrollStages.FaceEnrollStage;
import android.util.Slog;
/**
* Utilities for converting from hardware to framework-defined AIDL models.
*/
final class AidlConversionUtils {
private static final String TAG = "AidlConversionUtils";
// Prevent instantiation.
private AidlConversionUtils() {
}
@@ -174,4 +179,28 @@ final class AidlConversionUtils {
public static FaceEnrollCell toFrameworkCell(@Nullable Cell cell) {
return cell == null ? null : new FaceEnrollCell(cell.x, cell.y, cell.z);
}
public static byte convertFrameworkToAidlFeature(int feature) throws IllegalArgumentException {
switch (feature) {
case BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION:
return Feature.REQUIRE_ATTENTION;
case BiometricFaceConstants.FEATURE_REQUIRE_REQUIRE_DIVERSITY:
return Feature.REQUIRE_DIVERSE_POSES;
default:
Slog.e(TAG, "Unsupported feature : " + feature);
throw new IllegalArgumentException();
}
}
public static int convertAidlToFrameworkFeature(byte feature) throws IllegalArgumentException {
switch (feature) {
case Feature.REQUIRE_ATTENTION:
return BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION;
case Feature.REQUIRE_DIVERSE_POSES:
return BiometricFaceConstants.FEATURE_REQUIRE_REQUIRE_DIVERSITY;
default:
Slog.e(TAG, "Unsupported feature : " + feature);
throw new IllegalArgumentException();
}
}
}

View File

@@ -45,6 +45,7 @@ import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Face-specific enroll client for the {@link IFace} AIDL HAL interface.
@@ -55,6 +56,7 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
@NonNull private final int[] mEnrollIgnoreList;
@NonNull private final int[] mEnrollIgnoreListVendor;
@NonNull private final int[] mDisabledFeatures;
@Nullable private ICancellationSignal mCancellationSignal;
@Nullable private android.hardware.common.NativeHandle mPreviewSurface;
private final int mMaxTemplatesPerUser;
@@ -75,6 +77,7 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
.getIntArray(R.array.config_face_acquire_vendor_enroll_ignorelist);
mMaxTemplatesPerUser = maxTemplatesPerUser;
mDebugConsent = debugConsent;
mDisabledFeatures = disabledFeatures;
try {
// We must manually close the duplicate handle after it's no longer needed.
// The caller is responsible for closing the original handle.
@@ -144,27 +147,34 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
@Override
protected void startHalOperation() {
final ArrayList<Byte> token = new ArrayList<>();
for (byte b : mHardwareAuthToken) {
token.add(b);
}
try {
// TODO(b/172593978): Pass features.
// TODO(b/174619156): Handle accessibility enrollment.
byte[] features;
List<Byte> featureList = new ArrayList<Byte>();
if (mDebugConsent) {
features = new byte[1];
features[0] = Feature.DEBUG;
} else {
features = new byte[0];
featureList.add(new Byte(Feature.DEBUG));
}
boolean shouldAddDiversePoses = true;
for (int i = 0; i < mDisabledFeatures.length; i++) {
if (AidlConversionUtils.convertFrameworkToAidlFeature(mDisabledFeatures[i])
== Feature.REQUIRE_DIVERSE_POSES) {
shouldAddDiversePoses = false;
}
}
if (shouldAddDiversePoses) {
featureList.add(new Byte(Feature.REQUIRE_DIVERSE_POSES));
}
byte[] features = new byte[featureList.size()];
for (int i = 0; i < featureList.size(); i++) {
features[i] = featureList.get(i);
}
mCancellationSignal = getFreshDaemon().enroll(
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken),
EnrollmentType.DEFAULT, features, mPreviewSurface);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting enroll", e);
} catch (RemoteException | IllegalArgumentException e) {
Slog.e(TAG, "Exception when requesting enroll", e);
onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
}

View File

@@ -21,7 +21,6 @@ import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.face.Feature;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.ISession;
import android.os.IBinder;
@@ -82,36 +81,38 @@ public class FaceGetFeatureClient extends HalClientMonitor<ISession> implements
}
public void onFeatureGet(boolean success, byte[] features) {
HashMap<Integer, Boolean> featureMap = getFeatureMap();
int[] featuresToSend = new int[featureMap.size()];
boolean[] featureState = new boolean[featureMap.size()];
// The AIDL get feature api states that the presence of a feature means
// it is enabled, while the lack thereof means its disabled.
for (int i = 0; i < features.length; i++) {
Integer feature = convertAidlToFrameworkFeature(features[i]);
if (feature != null) {
featureMap.put(feature, true);
}
}
int i = 0;
for (Map.Entry<Integer, Boolean> entry : featureMap.entrySet()) {
featuresToSend[i] = entry.getKey();
featureState[i] = entry.getValue();
i++;
}
boolean attentionEnabled = featureMap.get(BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION);
Slog.d(TAG, "Updating attention value for user: " + mUserId
+ " to value: " + attentionEnabled);
Settings.Secure.putIntForUser(getContext().getContentResolver(),
Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
attentionEnabled ? 1 : 0, mUserId);
try {
HashMap<Integer, Boolean> featureMap = getFeatureMap();
int[] featuresToSend = new int[featureMap.size()];
boolean[] featureState = new boolean[featureMap.size()];
// The AIDL get feature api states that the presence of a feature means
// it is enabled, while the lack thereof means its disabled.
for (int i = 0; i < features.length; i++) {
featureMap.put(AidlConversionUtils.convertAidlToFrameworkFeature(features[i]),
true);
}
int i = 0;
for (Map.Entry<Integer, Boolean> entry : featureMap.entrySet()) {
featuresToSend[i] = entry.getKey();
featureState[i] = entry.getValue();
i++;
}
boolean attentionEnabled =
featureMap.get(BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION);
Slog.d(TAG, "Updating attention value for user: " + mUserId
+ " to value: " + attentionEnabled);
Settings.Secure.putIntForUser(getContext().getContentResolver(),
Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
attentionEnabled ? 1 : 0, mUserId);
getListener().onFeatureGet(success, featuresToSend, featureState);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
} catch (RemoteException | IllegalArgumentException e) {
Slog.e(TAG, "exception", e);
mCallback.onClientFinished(this, false /* success */);
return;
}
mCallback.onClientFinished(this, true /* success */);
@@ -123,15 +124,6 @@ public class FaceGetFeatureClient extends HalClientMonitor<ISession> implements
return featureMap;
}
private Integer convertAidlToFrameworkFeature(byte feature) {
switch (feature) {
case Feature.REQUIRE_ATTENTION:
return new Integer(BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION);
default:
return null;
}
}
@Override
public void onError(int errorCode, int vendorCode) {
try {

View File

@@ -18,9 +18,7 @@ package com.android.server.biometrics.sensors.face.aidl;
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.face.Feature;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.ISession;
import android.hardware.keymaster.HardwareAuthToken;
@@ -77,7 +75,7 @@ public class FaceSetFeatureClient extends HalClientMonitor<ISession> implements
try {
getFreshDaemon()
.setFeature(mHardwareAuthToken,
convertFrameworkToAidlFeature(mFeature), mEnabled);
AidlConversionUtils.convertFrameworkToAidlFeature(mFeature), mEnabled);
} catch (RemoteException | IllegalArgumentException e) {
Slog.e(TAG, "Unable to set feature: " + mFeature + " to enabled: " + mEnabled, e);
mCallback.onClientFinished(this, false /* success */);
@@ -99,16 +97,6 @@ public class FaceSetFeatureClient extends HalClientMonitor<ISession> implements
mCallback.onClientFinished(this, true /* success */);
}
private byte convertFrameworkToAidlFeature(int feature) throws IllegalArgumentException {
switch (feature) {
case BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION:
return Feature.REQUIRE_ATTENTION;
default:
Slog.e(TAG, "Unsupported feature : " + feature);
throw new IllegalArgumentException();
}
}
@Override
public void onError(int errorCode, int vendorCode) {
try {