Send FaceAuthReason & wakeup reason to FaceManager

Each time authenticate or detect is called, send
FaceManager the reason face auth/detect was triggered.

Test: atest KeyguardUpdateMonitorTest
Bug: 259980077
Change-Id: I81633705687bbb91ff853df59498bfa8403fb503
This commit is contained in:
Beverly
2023-02-23 17:16:38 +00:00
parent 11ff6387d5
commit 69512eb314
3 changed files with 157 additions and 6 deletions

View File

@@ -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);
}

View File

@@ -0,0 +1,99 @@
/*
* 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()
}
}

View File

@@ -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));