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

Commit 3460c48b authored by Diya Bera's avatar Diya Bera Committed by Android Build Cherrypicker Worker
Browse files

Face auth not eligible if camera in use

Test: atest PreAuthInfoTest
Bug: 287422904
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e6f6fc99b0d3beeac22e8d3106c4eaa5c611ebcf)
Merged-In: Ie06600fa9c0ba58a058dac24c7fe0bda226e9aba
Change-Id: Ie06600fa9c0ba58a058dac24c7fe0bda226e9aba
parent 7770222f
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -17,9 +17,16 @@
package com.android.server.biometrics;

/**
 * Interface for biometric operations to get camera privacy state.
 * Interface for biometrics to get camera status.
 */
public interface BiometricCameraManager {
    /**
     * Returns true if any camera is in use.
     */
    boolean isAnyCameraUnavailable();

    /**
     * Returns true if privacy is enabled and camera access is disabled.
     */
public interface BiometricSensorPrivacy {
    /* Returns true if privacy is enabled and camera access is disabled. */
    boolean isCameraPrivacyEnabled();
}
+68 −0
Original line number Diff line number Diff line
@@ -18,15 +18,46 @@ package com.android.server.biometrics;

import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;

import android.annotation.Nullable;
import android.annotation.NonNull;
import android.hardware.SensorPrivacyManager;
import android.hardware.camera2.CameraManager;

public class BiometricSensorPrivacyImpl implements
        BiometricSensorPrivacy {
import java.util.concurrent.ConcurrentHashMap;

public class BiometricCameraManagerImpl implements BiometricCameraManager {

    private final CameraManager mCameraManager;
    private final SensorPrivacyManager mSensorPrivacyManager;
    private final ConcurrentHashMap<String, Boolean> mIsCameraAvailable = new ConcurrentHashMap<>();

    public BiometricSensorPrivacyImpl(@Nullable SensorPrivacyManager sensorPrivacyManager) {
    private final CameraManager.AvailabilityCallback mCameraAvailabilityCallback =
            new CameraManager.AvailabilityCallback() {
                @Override
                public void onCameraAvailable(@NonNull String cameraId) {
                    mIsCameraAvailable.put(cameraId, true);
                }

                @Override
                public void onCameraUnavailable(@NonNull String cameraId) {
                    mIsCameraAvailable.put(cameraId, false);
                }
            };

    public BiometricCameraManagerImpl(@NonNull CameraManager cameraManager,
            @NonNull SensorPrivacyManager sensorPrivacyManager) {
        mCameraManager = cameraManager;
        mSensorPrivacyManager = sensorPrivacyManager;
        mCameraManager.registerAvailabilityCallback(mCameraAvailabilityCallback, null);
    }

    @Override
    public boolean isAnyCameraUnavailable() {
        for (String cameraId : mIsCameraAvailable.keySet()) {
            if (!mIsCameraAvailable.get(cameraId)) {
                return true;
            }
        }
        return false;
    }

    @Override
+8 −7
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.camera2.CameraManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.net.Uri;
@@ -125,7 +126,7 @@ public class BiometricService extends SystemService {
    AuthSession mAuthSession;
    private final Handler mHandler = new Handler(Looper.getMainLooper());

    private final BiometricSensorPrivacy mBiometricSensorPrivacy;
    private final BiometricCameraManager mBiometricCameraManager;

    /**
     * Tracks authenticatorId invalidation. For more details, see
@@ -936,7 +937,7 @@ public class BiometricService extends SystemService {

        return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors,
                userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */,
                getContext(), mBiometricSensorPrivacy);
                getContext(), mBiometricCameraManager);
    }

    /**
@@ -1030,9 +1031,9 @@ public class BiometricService extends SystemService {
            return context.getSystemService(UserManager.class);
        }

        public BiometricSensorPrivacy getBiometricSensorPrivacy(Context context) {
            return new BiometricSensorPrivacyImpl(context.getSystemService(
                    SensorPrivacyManager.class));
        public BiometricCameraManager getBiometricCameraManager(Context context) {
            return new BiometricCameraManagerImpl(context.getSystemService(CameraManager.class),
                    context.getSystemService(SensorPrivacyManager.class));
        }
    }

@@ -1062,7 +1063,7 @@ public class BiometricService extends SystemService {
        mRequestCounter = mInjector.getRequestGenerator();
        mBiometricContext = injector.getBiometricContext(context);
        mUserManager = injector.getUserManager(context);
        mBiometricSensorPrivacy = injector.getBiometricSensorPrivacy(context);
        mBiometricCameraManager = injector.getBiometricCameraManager(context);

        try {
            injector.getActivityManagerService().registerUserSwitchObserver(
@@ -1299,7 +1300,7 @@ public class BiometricService extends SystemService {
                final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager,
                        mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo,
                        opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(),
                        getContext(), mBiometricSensorPrivacy);
                        getContext(), mBiometricCameraManager);

                final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus();

+15 −11
Original line number Diff line number Diff line
@@ -72,16 +72,16 @@ class PreAuthInfo {
    final Context context;
    private final boolean mBiometricRequested;
    private final int mBiometricStrengthRequested;
    private final BiometricSensorPrivacy mBiometricSensorPrivacy;
    private final BiometricCameraManager mBiometricCameraManager;

    private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested,
            boolean credentialRequested, List<BiometricSensor> eligibleSensors,
            List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable,
            boolean confirmationRequested, boolean ignoreEnrollmentState, int userId,
            Context context, BiometricSensorPrivacy biometricSensorPrivacy) {
            Context context, BiometricCameraManager biometricCameraManager) {
        mBiometricRequested = biometricRequested;
        mBiometricStrengthRequested = biometricStrengthRequested;
        mBiometricSensorPrivacy = biometricSensorPrivacy;
        mBiometricCameraManager = biometricCameraManager;
        this.credentialRequested = credentialRequested;

        this.eligibleSensors = eligibleSensors;
@@ -99,7 +99,7 @@ class PreAuthInfo {
            List<BiometricSensor> sensors,
            int userId, PromptInfo promptInfo, String opPackageName,
            boolean checkDevicePolicyManager, Context context,
            BiometricSensorPrivacy biometricSensorPrivacy)
            BiometricCameraManager biometricCameraManager)
            throws RemoteException {

        final boolean confirmationRequested = promptInfo.isConfirmationRequested();
@@ -127,7 +127,7 @@ class PreAuthInfo {
                        checkDevicePolicyManager, requestedStrength,
                        promptInfo.getAllowedSensorIds(),
                        promptInfo.isIgnoreEnrollmentState(),
                        biometricSensorPrivacy);
                        biometricCameraManager);

                Slog.d(TAG, "Package: " + opPackageName
                        + " Sensor ID: " + sensor.id
@@ -151,7 +151,7 @@ class PreAuthInfo {

        return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested,
                eligibleSensors, ineligibleSensors, credentialAvailable, confirmationRequested,
                promptInfo.isIgnoreEnrollmentState(), userId, context, biometricSensorPrivacy);
                promptInfo.isIgnoreEnrollmentState(), userId, context, biometricCameraManager);
    }

    /**
@@ -168,12 +168,16 @@ class PreAuthInfo {
            BiometricSensor sensor, int userId, String opPackageName,
            boolean checkDevicePolicyManager, int requestedStrength,
            @NonNull List<Integer> requestedSensorIds,
            boolean ignoreEnrollmentState, BiometricSensorPrivacy biometricSensorPrivacy) {
            boolean ignoreEnrollmentState, BiometricCameraManager biometricCameraManager) {

        if (!requestedSensorIds.isEmpty() && !requestedSensorIds.contains(sensor.id)) {
            return BIOMETRIC_NO_HARDWARE;
        }

        if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) {
            return BIOMETRIC_HARDWARE_NOT_DETECTED;
        }

        final boolean wasStrongEnough =
                Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength);
        final boolean isStrongEnough =
@@ -195,8 +199,8 @@ class PreAuthInfo {
                return BIOMETRIC_NOT_ENROLLED;
            }

            if (biometricSensorPrivacy != null && sensor.modality == TYPE_FACE) {
                if (biometricSensorPrivacy.isCameraPrivacyEnabled()) {
            if (biometricCameraManager != null && sensor.modality == TYPE_FACE) {
                if (biometricCameraManager.isCameraPrivacyEnabled()) {
                    //Camera privacy is enabled as the access is disabled
                    return BIOMETRIC_SENSOR_PRIVACY_ENABLED;
                }
@@ -294,8 +298,8 @@ class PreAuthInfo {
        @BiometricAuthenticator.Modality int modality = TYPE_NONE;

        boolean cameraPrivacyEnabled = false;
        if (mBiometricSensorPrivacy != null) {
            cameraPrivacyEnabled = mBiometricSensorPrivacy.isCameraPrivacyEnabled();
        if (mBiometricCameraManager != null) {
            cameraPrivacyEnabled = mBiometricCameraManager.isCameraPrivacyEnabled();
        }

        if (mBiometricRequested && credentialRequested) {
+2 −2
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ public class AuthSessionTest {
    @Mock private KeyStore mKeyStore;
    @Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver;
    @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger;
    @Mock BiometricSensorPrivacy mBiometricSensorPrivacy;
    @Mock private BiometricCameraManager mBiometricCameraManager;

    private Random mRandom;
    private IBinder mToken;
@@ -573,7 +573,7 @@ public class AuthSessionTest {
                TEST_PACKAGE,
                checkDevicePolicyManager,
                mContext,
                mBiometricSensorPrivacy);
                mBiometricCameraManager);
    }

    private AuthSession createAuthSession(List<BiometricSensor> sensors,
Loading