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

Commit 9d3f1be6 authored by Joshua Mccloskey's avatar Joshua Mccloskey
Browse files

Add SensorPrivacy error message to FaceService.

If the camera privacy sensor is enabled, show an error message
on Keyguard.

Test: Verified that the sensor privacy error is shown when privacy sensor is enabled.
Bug: 201045056
Change-Id: Ib7709596d378caa690a782294197a5b26e55857f
parent c7f6a075
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ public interface BiometricFaceConstants {
            BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
            BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
            BIOMETRIC_ERROR_RE_ENROLL,
            FACE_ERROR_UNKNOWN
            FACE_ERROR_UNKNOWN,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface FaceError {}
+3 −0
Original line number Diff line number Diff line
@@ -219,6 +219,9 @@
    <!-- Face hint message when finger was not recognized. [CHAR LIMIT=20] -->
    <string name="kg_face_not_recognized">Not recognized</string>

     <!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=NONE] -->
    <string name="kg_face_sensor_privacy_enabled">To use Face Unlock, turn on <b>Camera access</b> in Settings > Privacy</string>

    <!-- Instructions telling the user remaining times when enter SIM PIN view.  -->
    <plurals name="kg_password_default_pin_message">
        <item quantity="one">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining
+18 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
@@ -322,6 +323,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private boolean mLockIconPressed;
    private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private final Executor mBackgroundExecutor;
    private SensorPrivacyManager mSensorPrivacyManager;
    private int mFaceAuthUserId;

    /**
     * Short delay before restarting fingerprint authentication after a successful try. This should
@@ -993,6 +996,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

        // Error is always the end of authentication lifecycle
        mFaceCancelSignal = null;
        boolean cameraPrivacyEnabled = false;
        if (mSensorPrivacyManager != null) {
            cameraPrivacyEnabled = mSensorPrivacyManager
                    .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
                    mFaceAuthUserId);
        }

        if (msgId == FaceManager.FACE_ERROR_CANCELED
                && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
@@ -1002,7 +1011,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            setFaceRunningState(BIOMETRIC_STATE_STOPPED);
        }

        if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE
        final boolean isHwUnavailable = msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE;

        if (isHwUnavailable
                || msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) {
            if (mHardwareFaceUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
                mHardwareFaceUnavailableRetryCount++;
@@ -1018,6 +1029,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            requireStrongAuthIfAllLockedOut();
        }

        if (isHwUnavailable && cameraPrivacyEnabled) {
            errString = mContext.getString(R.string.kg_face_sensor_privacy_enabled);
        }

        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
@@ -1791,6 +1806,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        mLockPatternUtils = lockPatternUtils;
        mAuthController = authController;
        dumpManager.registerDumpable(getClass().getName(), this);
        mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);

        mHandler = new Handler(mainLooper) {
            @Override
@@ -2476,6 +2492,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            // This would need to be updated for multi-sensor devices
            final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
                    && mFaceSensorProperties.get(0).supportsFaceDetection;
            mFaceAuthUserId = userId;
            if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
                mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
            } else {
+13 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.app.NotificationManager;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants;
@@ -56,6 +57,7 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
    @NonNull private final LockoutCache mLockoutCache;
    @Nullable private final NotificationManager mNotificationManager;
    @Nullable private ICancellationSignal mCancellationSignal;
    @Nullable private SensorPrivacyManager mSensorPrivacyManager;

    private final int[] mBiometricPromptIgnoreList;
    private final int[] mBiometricPromptIgnoreListVendor;
@@ -81,6 +83,7 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
        mUsageStats = usageStats;
        mLockoutCache = lockoutCache;
        mNotificationManager = context.getSystemService(NotificationManager.class);
        mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);

        final Resources resources = getContext().getResources();
        mBiometricPromptIgnoreList = resources.getIntArray(
@@ -108,7 +111,16 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
    @Override
    protected void startHalOperation() {
        try {
            if (mSensorPrivacyManager != null
                    && mSensorPrivacyManager
                    .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
                    getTargetUserId())) {
                onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
                        0 /* vendorCode */);
                mCallback.onClientFinished(this, false /* success */);
            } else {
                mCancellationSignal = getFreshDaemon().authenticate(mOperationId);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Remote exception when requesting auth", e);
            onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
+12 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server.biometrics.sensors.face.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.face.ISession;
@@ -41,6 +43,7 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det

    private final boolean mIsStrongBiometric;
    @Nullable private ICancellationSignal mCancellationSignal;
    @Nullable private SensorPrivacyManager mSensorPrivacyManager;

    public FaceDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
            @NonNull IBinder token, long requestId,
@@ -51,6 +54,7 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det
                BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
        setRequestId(requestId);
        mIsStrongBiometric = isStrongBiometric;
        mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
    }

    @Override
@@ -73,6 +77,14 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det

    @Override
    protected void startHalOperation() {
        if (mSensorPrivacyManager != null
                && mSensorPrivacyManager
                .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, getTargetUserId())) {
            onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
            mCallback.onClientFinished(this, false /* success */);
            return;
        }

        try {
            mCancellationSignal = getFreshDaemon().detectInteraction();
        } catch (RemoteException e) {
Loading