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

Commit 35240b38 authored by Beverly Tai's avatar Beverly Tai Committed by Automerger Merge Worker
Browse files

Merge "Send FaceAuthReason & wakeup reason to FaceManager" into udc-dev am: d2b02597

parents 352b423b d2b02597
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.hardware.biometrics.BiometricConstants.LockoutMode;
import static android.hardware.biometrics.BiometricSourceType.FACE;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
import static android.os.PowerManager.WAKE_REASON_UNKNOWN;

import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
@@ -152,6 +153,7 @@ import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.dump.DumpsysTableLogger;
import com.android.systemui.keyguard.shared.model.SysUiFaceAuthenticateOptions;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.WeatherData;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -3023,6 +3025,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        if (unlockPossible) {
            mFaceCancelSignal = new CancellationSignal();

            final FaceAuthenticateOptions faceAuthenticateOptions =
                    new SysUiFaceAuthenticateOptions(
                            userId,
                            faceAuthUiEvent,
                            faceAuthUiEvent == FACE_AUTH_UPDATED_STARTED_WAKING_UP
                                    ? faceAuthUiEvent.getExtraInfo()
                                    : WAKE_REASON_UNKNOWN
                    ).toFaceAuthenticateOptions();
            // This would need to be updated for multi-sensor devices
            final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
                    && mFaceSensorProperties.get(0).supportsFaceDetection;
@@ -3033,9 +3043,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                    // Run face detection. (If a face is detected, show the bouncer.)
                    mLogger.v("startListeningForFace - detect");
                    mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback,
                            new FaceAuthenticateOptions.Builder()
                                    .setUserId(userId)
                                    .build());
                            faceAuthenticateOptions);
                } else {
                    // Don't run face detection. Instead, inform the user
                    // face auth is unavailable and how to proceed.
@@ -3054,7 +3062,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                final boolean isBypassEnabled = mKeyguardBypassController != null
                        && mKeyguardBypassController.isBypassEnabled();
                mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal,
                        mFaceAuthenticationCallback, null /* handler */, userId);
                        mFaceAuthenticationCallback, null /* handler */,
                        faceAuthenticateOptions);
            }
            setFaceRunningState(BIOMETRIC_STATE_RUNNING);
        }
+99 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.keyguard.shared.model

import android.hardware.face.FaceAuthenticateOptions
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_ASSISTANT_VISIBLE
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_STARTED_WAKING_UP
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_UDFPS_POINTER_DOWN
import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_UNKNOWN
import android.hardware.face.FaceAuthenticateOptions.AuthenticateReason
import android.os.PowerManager
import android.os.PowerManager.WAKE_REASON_UNKNOWN
import android.util.Log
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.keyguard.FaceAuthUiEvent

/**
 * Wrapper for [FaceAuthenticateOptions] to convert SystemUI values to their corresponding value in
 * [FaceAuthenticateOptions].
 */
data class SysUiFaceAuthenticateOptions(
        val userId: Int,
        private val faceAuthUiEvent: UiEventLogger.UiEventEnum,
        @PowerManager.WakeReason val wakeReason: Int = WAKE_REASON_UNKNOWN
) {
    val authenticateReason = setAuthenticateReason(faceAuthUiEvent)

    /**
     * The [FaceAuthUiEvent] for this operation. This method converts the UiEvent to the framework
     * [AuthenticateReason].
     */
    @AuthenticateReason
    fun setAuthenticateReason(uiEvent: UiEventLogger.UiEventEnum): Int {
        return when (uiEvent) {
            FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP -> {
                AUTHENTICATE_REASON_STARTED_WAKING_UP
            }
            FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN,
            FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN -> {
                AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN
            }
            FaceAuthUiEvent.FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED -> {
                AUTHENTICATE_REASON_ASSISTANT_VISIBLE
            }
            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN -> {
                AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN
            }
            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED -> {
                AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED
            }
            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED -> {
                AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED
            }
            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED -> {
                AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED
            }
            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER -> {
                AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER
            }
            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_UDFPS_POINTER_DOWN -> {
                AUTHENTICATE_REASON_UDFPS_POINTER_DOWN
            }
            else -> {
                Log.e("FaceAuthenticateOptions", " unmapped FaceAuthUiEvent $uiEvent")
                AUTHENTICATE_REASON_UNKNOWN
            }
        }
    }

    /** Builds the instance. */
    fun toFaceAuthenticateOptions(): FaceAuthenticateOptions {
        return FaceAuthenticateOptions.Builder()
            .setUserId(userId)
            .setAuthenticateReason(authenticateReason)
            .setWakeReason(wakeReason)
            .build()
    }
}
+45 −2
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.app.StatusBarManager.SESSION_KEYGUARD;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
import static android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN;
import static android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_STARTED_WAKING_UP;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
@@ -80,6 +82,7 @@ import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.SensorProperties;
import android.hardware.face.FaceAuthenticateOptions;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
@@ -2500,7 +2503,46 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
                .isEqualTo(BIOMETRIC_STATE_CANCELLING_RESTARTING);
    }

    @Test
    public void faceAuthenticateOptions_bouncerAuthenticateReason() {
        // GIVEN the bouncer is fully visible
        bouncerFullyVisible();

        // WHEN authenticate is called
        ArgumentCaptor<FaceAuthenticateOptions> captor =
                ArgumentCaptor.forClass(FaceAuthenticateOptions.class);
        verify(mFaceManager).authenticate(any(), any(), any(), any(), captor.capture());

        // THEN the authenticate reason is attributed to the bouncer
        assertThat(captor.getValue().getAuthenticateReason())
                .isEqualTo(AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN);
    }

    @Test
    public void faceAuthenticateOptions_wakingUpAuthenticateReason_powerButtonWakeReason() {
        // GIVEN keyguard is visible
        keyguardIsVisible();

        // WHEN device wakes up from the power button
        mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
        mTestableLooper.processAllMessages();

        // THEN face auth is triggered
        ArgumentCaptor<FaceAuthenticateOptions> captor =
                ArgumentCaptor.forClass(FaceAuthenticateOptions.class);
        verify(mFaceManager).authenticate(any(), any(), any(), any(), captor.capture());

        // THEN the authenticate reason is attributed to the waking
        assertThat(captor.getValue().getAuthenticateReason())
                .isEqualTo(AUTHENTICATE_REASON_STARTED_WAKING_UP);

        // THEN the wake reason is attributed to the power button
        assertThat(captor.getValue().getWakeReason())
                .isEqualTo(PowerManager.WAKE_REASON_POWER_BUTTON);
    }

    private void verifyFingerprintAuthenticateNeverCalled() {
        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
                anyInt(), anyInt());
    }
@@ -2519,11 +2561,12 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    }

    private void verifyFaceAuthenticateNeverCalled() {
        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), any());
        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
    }

    private void verifyFaceAuthenticateCall() {
        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
        verify(mFaceManager).authenticate(any(), any(), any(), any(), any());
    }

    private void verifyFaceDetectNeverCalled() {
@@ -2631,7 +2674,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
                any(),
                mAuthenticationCallbackCaptor.capture(),
                any(),
                anyInt());
                any());
        mAuthenticationCallbackCaptor.getValue()
                .onAuthenticationSucceeded(
                        new FaceManager.AuthenticationResult(null, null, mCurrentUserId, false));