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 Original line Diff line number Diff line
@@ -17,9 +17,16 @@
package com.android.server.biometrics;
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();
    boolean isCameraPrivacyEnabled();
}
}
+68 −0
Original line number Original line Diff line number Diff line
@@ -18,15 +18,46 @@ package com.android.server.biometrics;


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


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


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

public class BiometricCameraManagerImpl implements BiometricCameraManager {

    private final CameraManager mCameraManager;
    private final SensorPrivacyManager mSensorPrivacyManager;
    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;
        mSensorPrivacyManager = sensorPrivacyManager;
        mCameraManager.registerAvailabilityCallback(mCameraAvailabilityCallback, null);
    }

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


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


    private final BiometricSensorPrivacy mBiometricSensorPrivacy;
    private final BiometricCameraManager mBiometricCameraManager;


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


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


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


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


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


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


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


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


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


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


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


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


        return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested,
        return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested,
                eligibleSensors, ineligibleSensors, credentialAvailable, confirmationRequested,
                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,
            BiometricSensor sensor, int userId, String opPackageName,
            boolean checkDevicePolicyManager, int requestedStrength,
            boolean checkDevicePolicyManager, int requestedStrength,
            @NonNull List<Integer> requestedSensorIds,
            @NonNull List<Integer> requestedSensorIds,
            boolean ignoreEnrollmentState, BiometricSensorPrivacy biometricSensorPrivacy) {
            boolean ignoreEnrollmentState, BiometricCameraManager biometricCameraManager) {


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


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

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


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


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


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


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


    private AuthSession createAuthSession(List<BiometricSensor> sensors,
    private AuthSession createAuthSession(List<BiometricSensor> sensors,
Loading