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

Commit a623355e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "No biometric prompt for external display" into main

parents d54fdfe7 ea16a724
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.biometrics;

import static android.hardware.biometrics.BiometricAuthenticator.TYPE_ANY_BIOMETRIC;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_CREDENTIAL;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
@@ -35,6 +36,7 @@ import android.os.RemoteException;
import android.os.UserManager;
import android.util.Pair;
import android.util.Slog;
import android.view.Display;

import com.android.internal.R;
import com.android.server.biometrics.sensors.LockoutTracker;
@@ -397,7 +399,11 @@ class PreAuthInfo {
            cameraPrivacyEnabled = mBiometricCameraManager.isCameraPrivacyEnabled();
        }

        if (mBiometricRequested && credentialRequested) {
        if (com.android.server.biometrics.Flags.biometricPromptExternalDisplay()
                && isExternalDisplay()) {
            status = BIOMETRIC_HARDWARE_NOT_DETECTED;
            modality = TYPE_ANY_BIOMETRIC | TYPE_CREDENTIAL;
        } else if (mBiometricRequested && credentialRequested) {
            if (credentialAvailable || !eligibleSensors.isEmpty()) {
                for (BiometricSensor sensor : eligibleSensors) {
                    modality |= sensor.modality;
@@ -480,6 +486,15 @@ class PreAuthInfo {
                        getInternalStatus().second));
    }

    private boolean isExternalDisplay() {
        try {
            return context.getDisplay().getType() == Display.TYPE_EXTERNAL;
        } catch (UnsupportedOperationException e) {
            Slog.d(TAG, "Exception thrown when checking display type " + e);
            return false;
        }
    }

    /** Returns if mandatory biometrics authentication is in effect */
    boolean getIsMandatoryBiometricsAuthentication() {
        return mIsMandatoryBiometricsAuthentication;
+10 −0
Original line number Diff line number Diff line
@@ -51,3 +51,13 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
  name: "biometric_prompt_external_display"
  namespace: "biometrics_framework"
  description: "This flag returns error code when biometric prompt is requested on external display."
  bug: "421237594"
  metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+47 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.server.biometrics;

import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_ANY_BIOMETRIC;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_CREDENTIAL;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
@@ -40,6 +42,8 @@ import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.Flags;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.PromptInfo;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.IDisplayManager;
import android.os.RemoteException;
import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
@@ -47,6 +51,9 @@ import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.Pair;
import android.view.Display;
import android.view.DisplayInfo;

import androidx.test.filters.SmallTest;

@@ -92,6 +99,8 @@ public class PreAuthInfoTest {
    BiometricCameraManager mBiometricCameraManager;
    @Mock
    UserManager mUserManager;
    @Mock
    IDisplayManager mDisplayManager;

    @Before
    public void setup() throws RemoteException {
@@ -114,6 +123,35 @@ public class PreAuthInfoTest {
        when(mBiometricCameraManager.isAnyCameraUnavailable()).thenReturn(false);
        when(mContext.getResources()).thenReturn(mResources);
        when(mResources.getString(anyInt())).thenReturn(TEST_PACKAGE_NAME);
        setContextDisplayWithType(Display.TYPE_INTERNAL);
    }

    @Test
    @RequiresFlagsEnabled(
            com.android.server.biometrics.Flags.FLAG_BIOMETRIC_PROMPT_EXTERNAL_DISPLAY)
    public void testAuthentication_whenExternalDisplay() throws RemoteException {
        setContextDisplayWithType(Display.TYPE_EXTERNAL);

        final BiometricSensor faceSensor = getFaceSensor();
        final BiometricSensor fingerprintSensor = getFingerprintSensor();
        final PromptInfo promptInfo = new PromptInfo();

        promptInfo.setConfirmationRequested(false /* requireConfirmation */);
        promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
        promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */);
        final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
                mSettingObserver, List.of(faceSensor, fingerprintSensor), USER_ID, promptInfo,
                TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext,
                mBiometricCameraManager, mUserManager);
        final Pair<Integer, Integer> preAuthenticateStatus = preAuthInfo.getPreAuthenticateStatus();

        //Should return hardware unavailable even if there are eligible sensors
        assertThat(preAuthInfo.eligibleSensors).hasSize(2);
        assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo(
                BIOMETRIC_ERROR_HW_UNAVAILABLE);
        assertThat(preAuthenticateStatus.first).isEqualTo(
                TYPE_ANY_BIOMETRIC | TYPE_CREDENTIAL);
        assertThat(preAuthenticateStatus.second).isEqualTo(BIOMETRIC_ERROR_HW_UNAVAILABLE);
    }

    @Test
@@ -505,6 +543,15 @@ public class PreAuthInfoTest {
                .isEqualTo(BIOMETRIC_NOT_ENABLED_FOR_APPS);
    }

    private void setContextDisplayWithType(int type) {
        final DisplayInfo displayInfo = new DisplayInfo();
        displayInfo.type = type;
        final Display display = new Display(new DisplayManagerGlobal(mDisplayManager),
                0 /* displayId */, displayInfo, mResources);

        when(mContext.getDisplay()).thenReturn(display);
    }

    private BiometricSensor getFingerprintSensor() {
        BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT,
                TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG,