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

Commit 5b0dd45a authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Update face detectInteraction

1) Sets the sensor property based on the HAL, instead of hard coding
   false
2) Schedules/cancels detection when requested
3) Updates biometric dumpsys to include internal properties

Test: atest com.android.server.biometrics
Test: adb shell dumpsys biometric
Test: manual
Bug: 184672091

Change-Id: I2fb1db0994f6d2ed235420967d78e70f1b13cdd0
parent 9759067e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ public class FaceSensorPropertiesInternal extends SensorPropertiesInternal {

    @Override
    public String toString() {
        return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;
        return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType
                + ", SupportsFaceDetection: " + supportsFaceDetection;
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -2131,8 +2131,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

        // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
        // Lock-down mode shouldn't scan, since it is more explicit.
        boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
                && !isLockDown;
        boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer);

        // If the device supports face detection (without authentication), allow it to happen
        // if the device is in lockdown mode. Otherwise, prevent scanning.
        boolean supportsDetectOnly = mFaceSensorProperties.get(0).supportsFaceDetection;
        if (isLockDown && !supportsDetectOnly) {
            strongAuthAllowsScanning = false;
        }

        // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
        // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
+15 −3
Original line number Diff line number Diff line
@@ -19,10 +19,13 @@ package com.android.server.biometrics;
import static android.hardware.biometrics.BiometricManager.Authenticators;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
@@ -62,6 +65,7 @@ public abstract class BiometricSensor {
    @Retention(RetentionPolicy.SOURCE)
    @interface SensorState {}

    @NonNull private final Context mContext;
    public final int id;
    public final @Authenticators.Types int oemStrength; // strength as configured by the OEM
    public final int modality;
@@ -84,8 +88,9 @@ public abstract class BiometricSensor {
     */
    abstract boolean confirmationSupported();

    BiometricSensor(int id, int modality, @Authenticators.Types int strength,
            IBiometricAuthenticator impl) {
    BiometricSensor(@NonNull Context context, int id, int modality,
            @Authenticators.Types int strength, IBiometricAuthenticator impl) {
        this.mContext = context;
        this.id = id;
        this.modality = modality;
        this.oemStrength = strength;
@@ -169,12 +174,19 @@ public abstract class BiometricSensor {

    @Override
    public String toString() {
        SensorPropertiesInternal properties = null;
        try {
            properties = impl.getSensorProperties(mContext.getOpPackageName());
        } catch (RemoteException e) {
            Slog.e(TAG, "Remote exception", e);
        }

        return "ID(" + id + ")"
                + ", oemStrength: " + oemStrength
                + ", updatedStrength: " + mUpdatedStrength
                + ", modality " + modality
                + ", state: " + mSensorState
                + ", cookie: " + mCookie
                + ", authenticator: " + impl;
                + ", props: " + properties;
    }
}
+3 −8
Original line number Diff line number Diff line
@@ -725,7 +725,7 @@ public class BiometricService extends SystemService {
                }
            }

            mSensors.add(new BiometricSensor(id, modality, strength, authenticator) {
            mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) {
                @Override
                boolean confirmationAlwaysRequired(int userId) {
                    return mSettingObserver.getConfirmationAlwaysRequired(modality, userId);
@@ -1351,13 +1351,8 @@ public class BiometricService extends SystemService {
        for (BiometricSensor sensor : mSensors) {
            pw.println(" " + sensor);
        }
        pw.println();
        pw.println("CurrentSession: " + mCurrentAuthSession);

        final List<FingerprintSensorPropertiesInternal> fpProps =
                mInjector.getFingerprintSensorProperties(getContext());
        pw.println("FingerprintSensorProperties: " + fpProps.size());
        for (FingerprintSensorPropertiesInternal prop : fpProps) {
            pw.println(" " + prop);
        }
        pw.println();
    }
}
+14 −8
Original line number Diff line number Diff line
@@ -559,22 +559,21 @@ public class BiometricScheduler {
    }

    /**
     * Requests to cancel authentication.
     * Requests to cancel authentication or detection.
     * @param token from the caller, should match the token passed in when requesting authentication
     */
    public void cancelAuthentication(IBinder token) {
    public void cancelAuthenticationOrDetection(IBinder token) {
        if (mCurrentOperation == null) {
            Slog.e(getTag(), "Unable to cancel authentication, null operation");
            return;
        }
        final boolean isAuthenticating =
                mCurrentOperation.mClientMonitor instanceof AuthenticationConsumer;
        final boolean isCorrectClient = isAuthenticationOrDetectionOperation(mCurrentOperation);
        final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token;

        if (isAuthenticating && tokenMatches) {
            Slog.d(getTag(), "Cancelling authentication: " + mCurrentOperation);
        if (isCorrectClient && tokenMatches) {
            Slog.d(getTag(), "Cancelling: " + mCurrentOperation);
            cancelInternal(mCurrentOperation);
        } else if (!isAuthenticating) {
        } else if (!isCorrectClient) {
            // Look through the current queue for all authentication clients for the specified
            // token, and mark them as STATE_WAITING_IN_QUEUE_CANCELING. Note that we're marking
            // all of them, instead of just the first one, since the API surface currently doesn't
@@ -582,7 +581,7 @@ public class BiometricScheduler {
            // process. However, this generally does not happen anyway, and would be a class of
            // bugs on its own.
            for (Operation operation : mPendingOperations) {
                if (operation.mClientMonitor instanceof AuthenticationConsumer
                if (isAuthenticationOrDetectionOperation(operation)
                        && operation.mClientMonitor.getToken() == token) {
                    Slog.d(getTag(), "Marking " + operation
                            + " as STATE_WAITING_IN_QUEUE_CANCELING");
@@ -592,6 +591,13 @@ public class BiometricScheduler {
        }
    }

    private boolean isAuthenticationOrDetectionOperation(@NonNull Operation operation) {
        final boolean isAuthentication = operation.mClientMonitor
                instanceof AuthenticationConsumer;
        final boolean isDetection = operation.mClientMonitor instanceof DetectionConsumer;
        return isAuthentication || isDetection;
    }

    /**
     * @return the current operation
     */
Loading