Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85d29a95 authored by Jeff Pu's avatar Jeff Pu Committed by Android (Google) Code Review
Browse files

Merge "Face VHAL for user build" into main

parents 6e19a449 7b3dcebe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ filegroup {
        ":android.hardware.biometrics.common-V4-java-source",
        ":android.hardware.biometrics.fingerprint-V5-java-source",
        ":android.hardware.biometrics.fingerprint.virtualhal-java-source",
        ":android.hardware.biometrics.face.virtualhal-java-source",
        ":android.hardware.biometrics.face-V4-java-source",
        ":android.hardware.gnss-V2-java-source",
        ":android.hardware.graphics.common-V3-java-source",
+41 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.SensorProps;
import android.hardware.biometrics.face.virtualhal.IVirtualHal;
import android.os.Binder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -160,6 +161,41 @@ public class FaceSensorConfigurations implements Parcelable {
        dest.writeByte((byte) (mResetLockoutRequiresChallenge ? 1 : 0));
        dest.writeMap(mSensorPropsMap);
    }
    /**
     * Remap fqName of VHAL because the `virtual` instance is registered
     * with IVirtulalHal now (IFace previously)
     * @param fqName fqName to be translated
     * @return real fqName
     */
    public static String remapFqName(String fqName) {
        if (!fqName.contains(IFace.DESCRIPTOR + "/virtual")) {
            return fqName;  //no remap needed for real hardware HAL
        } else {
            //new Vhal instance name
            return fqName.replace("IFace", "virtualhal.IVirtualHal");
        }
    }
    /**
     * @param fqName aidl interface instance name
     * @return aidl interface
     */
    public static IFace getIFace(String fqName) {
        if (fqName.contains("virtual")) {
            String fqNameMapped = remapFqName(fqName);
            Slog.i(TAG, "getIFace fqName is mapped: " + fqName + "->" + fqNameMapped);
            try {
                IVirtualHal vhal = IVirtualHal.Stub.asInterface(
                        Binder.allowBlocking(ServiceManager.waitForService(fqNameMapped)));
                return vhal.getFaceHal();
            } catch (RemoteException e) {
                Slog.e(TAG, "Remote exception in vhal.getFaceHal() call" + fqNameMapped);
            }
        }

        return IFace.Stub.asInterface(
                Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
    }


    /**
     * Returns face sensor props for the HAL {@param instance}.
@@ -173,14 +209,13 @@ public class FaceSensorConfigurations implements Parcelable {
            return props;
        }

        final String fqName = IFace.DESCRIPTOR + "/" + instance;
        IFace face = IFace.Stub.asInterface(Binder.allowBlocking(
                ServiceManager.waitForDeclaredService(fqName)));
        try {
            if (face != null) {
                props = face.getSensorProps();
            final String fqName = IFace.DESCRIPTOR + "/" + instance;
            final IFace fp = getIFace(fqName);
            if (fp != null) {
                props = fp.getSensorProps();
            } else {
                Slog.e(TAG, "Unable to get declared service: " + fqName);
                Log.d(TAG, "IFace null for instance " + instance);
            }
        } catch (RemoteException e) {
            Log.d(TAG, "Unable to get sensor properties!");
+2 −2
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorLocationInternal;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.biometrics.face.IFace;
import android.hardware.face.FaceSensorConfigurations;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
@@ -73,6 +72,7 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.SystemService;
import com.android.server.biometrics.sensors.face.FaceService;
import com.android.server.biometrics.sensors.fingerprint.FingerprintService;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;

@@ -211,7 +211,7 @@ public class AuthService extends SystemService {
         */
        @VisibleForTesting
        public String[] getFaceAidlInstances() {
            return ServiceManager.getDeclaredInstances(IFace.DESCRIPTOR);
            return FaceService.getDeclaredInstances();
        }

        /**
+21 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors.face;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.MANAGE_FACE;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.face.FaceSensorConfigurations.getIFace;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -60,6 +61,7 @@ import android.util.proto.ProtoOutputStream;
import android.view.Surface;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.SystemService;
@@ -753,7 +755,7 @@ public class FaceService extends SystemService {
    public FaceService(Context context) {
        this(context, null /* faceProviderFunction */, () -> IBiometricService.Stub.asInterface(
                ServiceManager.getService(Context.BIOMETRIC_SERVICE)), null /* faceProvider */,
                () -> ServiceManager.getDeclaredInstances(IFace.DESCRIPTOR));
                () -> getDeclaredInstances());
    }

    @VisibleForTesting FaceService(Context context,
@@ -778,8 +780,7 @@ public class FaceService extends SystemService {

        mFaceProvider = faceProvider != null ? faceProvider : (name) -> {
            final String fqName = IFace.DESCRIPTOR + "/" + name;
            final IFace face = IFace.Stub.asInterface(
                    Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
            final IFace face = getIFace(fqName);
            if (face == null) {
                Slog.e(TAG, "Unable to get declared service: " + fqName);
                return null;
@@ -835,6 +836,23 @@ public class FaceService extends SystemService {
     */
    public static native void releaseSurfaceHandle(@NonNull NativeHandle handle);

    /**
     * Get all face hal instances declared in manifest
     * @return instance names
     */
    public static String[] getDeclaredInstances() {
        String[] a = ServiceManager.getDeclaredInstances(IFace.DESCRIPTOR);
        Slog.i(TAG, "Before:getDeclaredInstances: IFace instance found, a.length="
                + a.length);
        if (!ArrayUtils.contains(a, "virtual")) {
            // Now, the virtual hal is registered with IVirtualHal interface and it is also
            //   moved from vendor to system_ext partition without a device manifest. So
            //   if the old vhal is not declared, add here.
            a = ArrayUtils.appendElement(String.class, a, "virtual");
        }
        Slog.i(TAG, "After:getDeclaredInstances: a.length=" + a.length);
        return a;
    }

    void syncEnrollmentsNow() {
        Utils.checkPermissionOrShell(getContext(), MANAGE_FACE);
+48 −5
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.face.AuthenticationFrame;
import android.hardware.biometrics.face.BaseFrame;
import android.hardware.biometrics.face.EnrollmentFrame;
import android.hardware.biometrics.face.virtualhal.AcquiredInfoAndVendorCode;
import android.hardware.biometrics.face.virtualhal.EnrollmentProgressStep;
import android.hardware.biometrics.face.virtualhal.NextEnrollment;
import android.hardware.face.Face;
import android.hardware.face.FaceAuthenticationFrame;
import android.hardware.face.FaceEnrollFrame;
@@ -50,6 +53,7 @@ import java.util.Set;
public class BiometricTestSessionImpl extends ITestSession.Stub {

    private static final String TAG = "face/aidl/BiometricTestSessionImpl";
    private static final int VHAL_ENROLLMENT_ID = 9999;

    @NonNull private final Context mContext;
    private final int mSensorId;
@@ -144,16 +148,35 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {

        super.setTestHalEnabled_enforcePermission();

        mProvider.setTestHalEnabled(enabled);
        mSensor.setTestHalEnabled(enabled);
        mProvider.setTestHalEnabled(enabled);
    }

    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
    @Override
    public void startEnroll(int userId) {
    public void startEnroll(int userId) throws RemoteException {

        super.startEnroll_enforcePermission();

        Slog.i(TAG, "startEnroll(): isVhalForTesting=" + mProvider.isVhalForTesting());
        if (mProvider.isVhalForTesting()) {
            final AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes =
                    {new AcquiredInfoAndVendorCode()};
            final EnrollmentProgressStep[] enrollmentProgressSteps =
                    {new EnrollmentProgressStep(), new EnrollmentProgressStep()};
            enrollmentProgressSteps[0].durationMs = 100;
            enrollmentProgressSteps[0].acquiredInfoAndVendorCodes = acquiredInfoAndVendorCodes;
            enrollmentProgressSteps[1].durationMs = 200;
            enrollmentProgressSteps[1].acquiredInfoAndVendorCodes = acquiredInfoAndVendorCodes;

            final NextEnrollment nextEnrollment = new NextEnrollment();
            nextEnrollment.id = VHAL_ENROLLMENT_ID;
            nextEnrollment.progressSteps = enrollmentProgressSteps;
            nextEnrollment.result = true;
            mProvider.getVhal().setNextEnrollment(nextEnrollment);
            mProvider.getVhal().setOperationAuthenticateDuration(6000);
        }

        mProvider.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
                mContext.getOpPackageName(), new int[0] /* disabledFeatures */,
                null /* previewSurface */, false /* debugConsent */,
@@ -166,6 +189,10 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {

        super.finishEnroll_enforcePermission();

        if (mProvider.isVhalForTesting()) {
            return;
        }

        int nextRandomId = mRandom.nextInt();
        while (mEnrollmentIds.contains(nextRandomId)) {
            nextRandomId = mRandom.nextInt();
@@ -178,11 +205,16 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {

    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
    @Override
    public void acceptAuthentication(int userId)  {
    public void acceptAuthentication(int userId) throws RemoteException {

        // Fake authentication with any of the existing faces
        super.acceptAuthentication_enforcePermission();

        if (mProvider.isVhalForTesting()) {
            mProvider.getVhal().setEnrollmentHit(VHAL_ENROLLMENT_ID);
            return;
        }

        List<Face> faces = FaceUtils.getInstance(mSensorId)
                .getBiometricsForUser(mContext, userId);
        if (faces.isEmpty()) {
@@ -196,10 +228,15 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {

    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
    @Override
    public void rejectAuthentication(int userId)  {
    public void rejectAuthentication(int userId) throws RemoteException {

        super.rejectAuthentication_enforcePermission();

        if (mProvider.isVhalForTesting()) {
            mProvider.getVhal().setEnrollmentHit(VHAL_ENROLLMENT_ID + 1);
            return;
        }

        mSensor.getSessionForUser(userId).getHalSessionCallback().onAuthenticationFailed();
    }

@@ -236,11 +273,17 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {

    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
    @Override
    public void cleanupInternalState(int userId)  {
    public void cleanupInternalState(int userId) throws RemoteException {

        super.cleanupInternalState_enforcePermission();

        Slog.d(TAG, "cleanupInternalState: " + userId);

        if (mProvider.isVhalForTesting()) {
            Slog.i(TAG, "cleanup virtualhal configurations");
            mProvider.getVhal().resetConfigurations(); //setEnrollments(new int[]{});
        }

        mProvider.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
            @Override
            public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
Loading