From 897dcdb85a339f1e77f1dcc84ef51e2329f76657 Mon Sep 17 00:00:00 2001 From: Beverly Date: Wed, 19 Oct 2022 19:17:34 +0000 Subject: [PATCH] Gate & metrics log WakeReason for face auth run Include the PowerManager#WakeReason in the metrics log for FaceAuth being triggered by the device waking up. Add config that only allows some wakeups to trigger face auth. For example. we don't need to start running face authentication when the device wakes-up when the user starts charging their device. Also, update KeyguardUpdateMonitor face auth triggers to exclude dream stopping as a signal to run face auth. Since Dozing and AoD are dreams, this meant that any state changes that left the dream would trigger face auth. Test: atest KeyguardUpdateMonitorTest Test: atest FaceWakeUpTriggersConfigTest Test: check sysui logs Bug: 232882273 Bug: 242628816 Change-Id: I3794b7eda7f5e4cf550d9e4a813a28e6c5322d68 --- packages/SystemUI/res/values/config.xml | 12 +++ .../com/android/keyguard/FaceAuthReason.kt | 96 +++++++------------ .../keyguard/FaceWakeUpTriggersConfig.kt | 76 +++++++++++++++ .../keyguard/KeyguardUpdateMonitor.java | 48 +++++++--- .../logging/KeyguardUpdateMonitorLogger.kt | 23 ++++- .../systemui/keyguard/KeyguardService.java | 2 +- .../keyguard/KeyguardViewMediator.java | 5 +- .../keyguard/FaceWakeUpTriggersConfigTest.kt | 76 +++++++++++++++ .../keyguard/KeyguardUpdateMonitorTest.java | 85 ++++++++++++---- 9 files changed, 322 insertions(+), 101 deletions(-) create mode 100644 packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt create mode 100644 packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 9188ce091a3bd..93982cb2c5b98 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -643,6 +643,18 @@ 26 + + + 1 + 4 + 6 + 7 + 9 + 10 + 12 + + false diff --git a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt index 6fcb6f55dc205..4a41b3fe2589a 100644 --- a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt +++ b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt @@ -17,6 +17,7 @@ package com.android.keyguard import android.annotation.StringDef +import android.os.PowerManager import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger import com.android.keyguard.FaceAuthApiRequestReason.Companion.NOTIFICATION_PANEL_CLICKED @@ -122,122 +123,93 @@ private object InternalFaceAuthReasons { "Face auth started/stopped because biometric is enabled on keyguard" } -/** UiEvents that are logged to identify why face auth is being triggered. */ -enum class FaceAuthUiEvent constructor(private val id: Int, val reason: String) : +/** + * UiEvents that are logged to identify why face auth is being triggered. + * @param extraInfo is logged as the position. See [UiEventLogger#logWithInstanceIdAndPosition] + */ +enum class FaceAuthUiEvent +constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) : UiEventLogger.UiEventEnum { @UiEvent(doc = OCCLUDING_APP_REQUESTED) FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED(1146, OCCLUDING_APP_REQUESTED), - @UiEvent(doc = UDFPS_POINTER_DOWN) FACE_AUTH_TRIGGERED_UDFPS_POINTER_DOWN(1147, UDFPS_POINTER_DOWN), - @UiEvent(doc = SWIPE_UP_ON_BOUNCER) FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER(1148, SWIPE_UP_ON_BOUNCER), - @UiEvent(doc = DEVICE_WOKEN_UP_ON_REACH_GESTURE) FACE_AUTH_TRIGGERED_ON_REACH_GESTURE_ON_AOD(1149, DEVICE_WOKEN_UP_ON_REACH_GESTURE), - @UiEvent(doc = FACE_LOCKOUT_RESET) FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET(1150, FACE_LOCKOUT_RESET), - - @UiEvent(doc = QS_EXPANDED) - FACE_AUTH_TRIGGERED_QS_EXPANDED(1151, QS_EXPANDED), - + @UiEvent(doc = QS_EXPANDED) FACE_AUTH_TRIGGERED_QS_EXPANDED(1151, QS_EXPANDED), @UiEvent(doc = NOTIFICATION_PANEL_CLICKED) FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED(1152, NOTIFICATION_PANEL_CLICKED), - @UiEvent(doc = PICK_UP_GESTURE_TRIGGERED) FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED(1153, PICK_UP_GESTURE_TRIGGERED), - @UiEvent(doc = ALTERNATE_BIOMETRIC_BOUNCER_SHOWN) - FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(1154, - ALTERNATE_BIOMETRIC_BOUNCER_SHOWN), - + FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(1154, ALTERNATE_BIOMETRIC_BOUNCER_SHOWN), @UiEvent(doc = PRIMARY_BOUNCER_SHOWN) FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN(1155, PRIMARY_BOUNCER_SHOWN), - @UiEvent(doc = PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN) FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN( 1197, PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN ), - @UiEvent(doc = RETRY_AFTER_HW_UNAVAILABLE) FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE(1156, RETRY_AFTER_HW_UNAVAILABLE), - - @UiEvent(doc = TRUST_DISABLED) - FACE_AUTH_TRIGGERED_TRUST_DISABLED(1158, TRUST_DISABLED), - - @UiEvent(doc = TRUST_ENABLED) - FACE_AUTH_STOPPED_TRUST_ENABLED(1173, TRUST_ENABLED), - + @UiEvent(doc = TRUST_DISABLED) FACE_AUTH_TRIGGERED_TRUST_DISABLED(1158, TRUST_DISABLED), + @UiEvent(doc = TRUST_ENABLED) FACE_AUTH_STOPPED_TRUST_ENABLED(1173, TRUST_ENABLED), @UiEvent(doc = KEYGUARD_OCCLUSION_CHANGED) FACE_AUTH_UPDATED_KEYGUARD_OCCLUSION_CHANGED(1159, KEYGUARD_OCCLUSION_CHANGED), - @UiEvent(doc = ASSISTANT_VISIBILITY_CHANGED) FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED(1160, ASSISTANT_VISIBILITY_CHANGED), - @UiEvent(doc = STARTED_WAKING_UP) - FACE_AUTH_UPDATED_STARTED_WAKING_UP(1161, STARTED_WAKING_UP), - + FACE_AUTH_UPDATED_STARTED_WAKING_UP(1161, STARTED_WAKING_UP) { + override fun extraInfoToString(): String { + return PowerManager.wakeReasonToString(extraInfo) + } + }, + @Deprecated( + "Not a face auth trigger.", + ReplaceWith( + "FACE_AUTH_UPDATED_STARTED_WAKING_UP, " + + "extraInfo=PowerManager.WAKE_REASON_DREAM_FINISHED" + ) + ) @UiEvent(doc = DREAM_STOPPED) FACE_AUTH_TRIGGERED_DREAM_STOPPED(1162, DREAM_STOPPED), - @UiEvent(doc = ALL_AUTHENTICATORS_REGISTERED) FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED(1163, ALL_AUTHENTICATORS_REGISTERED), - @UiEvent(doc = ENROLLMENTS_CHANGED) FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED(1164, ENROLLMENTS_CHANGED), - @UiEvent(doc = KEYGUARD_VISIBILITY_CHANGED) FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED(1165, KEYGUARD_VISIBILITY_CHANGED), - @UiEvent(doc = FACE_CANCEL_NOT_RECEIVED) FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED(1174, FACE_CANCEL_NOT_RECEIVED), - @UiEvent(doc = AUTH_REQUEST_DURING_CANCELLATION) FACE_AUTH_TRIGGERED_DURING_CANCELLATION(1175, AUTH_REQUEST_DURING_CANCELLATION), - - @UiEvent(doc = DREAM_STARTED) - FACE_AUTH_STOPPED_DREAM_STARTED(1176, DREAM_STARTED), - - @UiEvent(doc = FP_LOCKED_OUT) - FACE_AUTH_STOPPED_FP_LOCKED_OUT(1177, FP_LOCKED_OUT), - + @UiEvent(doc = DREAM_STARTED) FACE_AUTH_STOPPED_DREAM_STARTED(1176, DREAM_STARTED), + @UiEvent(doc = FP_LOCKED_OUT) FACE_AUTH_STOPPED_FP_LOCKED_OUT(1177, FP_LOCKED_OUT), @UiEvent(doc = FACE_AUTH_STOPPED_ON_USER_INPUT) FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER(1178, FACE_AUTH_STOPPED_ON_USER_INPUT), - @UiEvent(doc = KEYGUARD_GOING_AWAY) FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY(1179, KEYGUARD_GOING_AWAY), - - @UiEvent(doc = CAMERA_LAUNCHED) - FACE_AUTH_UPDATED_CAMERA_LAUNCHED(1180, CAMERA_LAUNCHED), - - @UiEvent(doc = FP_AUTHENTICATED) - FACE_AUTH_UPDATED_FP_AUTHENTICATED(1181, FP_AUTHENTICATED), - - @UiEvent(doc = GOING_TO_SLEEP) - FACE_AUTH_UPDATED_GOING_TO_SLEEP(1182, GOING_TO_SLEEP), - + @UiEvent(doc = CAMERA_LAUNCHED) FACE_AUTH_UPDATED_CAMERA_LAUNCHED(1180, CAMERA_LAUNCHED), + @UiEvent(doc = FP_AUTHENTICATED) FACE_AUTH_UPDATED_FP_AUTHENTICATED(1181, FP_AUTHENTICATED), + @UiEvent(doc = GOING_TO_SLEEP) FACE_AUTH_UPDATED_GOING_TO_SLEEP(1182, GOING_TO_SLEEP), @UiEvent(doc = FINISHED_GOING_TO_SLEEP) FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP(1183, FINISHED_GOING_TO_SLEEP), - - @UiEvent(doc = KEYGUARD_INIT) - FACE_AUTH_UPDATED_ON_KEYGUARD_INIT(1189, KEYGUARD_INIT), - - @UiEvent(doc = KEYGUARD_RESET) - FACE_AUTH_UPDATED_KEYGUARD_RESET(1185, KEYGUARD_RESET), - - @UiEvent(doc = USER_SWITCHING) - FACE_AUTH_UPDATED_USER_SWITCHING(1186, USER_SWITCHING), - + @UiEvent(doc = KEYGUARD_INIT) FACE_AUTH_UPDATED_ON_KEYGUARD_INIT(1189, KEYGUARD_INIT), + @UiEvent(doc = KEYGUARD_RESET) FACE_AUTH_UPDATED_KEYGUARD_RESET(1185, KEYGUARD_RESET), + @UiEvent(doc = USER_SWITCHING) FACE_AUTH_UPDATED_USER_SWITCHING(1186, USER_SWITCHING), @UiEvent(doc = FACE_AUTHENTICATED) FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED(1187, FACE_AUTHENTICATED), - @UiEvent(doc = BIOMETRIC_ENABLED) FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD(1188, BIOMETRIC_ENABLED); override fun getId(): Int = this.id + + /** Convert [extraInfo] to a human-readable string. By default, this is empty. */ + open fun extraInfoToString(): String = "" } private val apiRequestReasonToUiEvent = diff --git a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt new file mode 100644 index 0000000000000..a0c43fba4bc1d --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2022 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.keyguard + +import android.content.res.Resources +import android.os.Build +import android.os.PowerManager +import com.android.systemui.Dumpable +import com.android.systemui.R +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dump.DumpManager +import com.android.systemui.util.settings.GlobalSettings +import java.io.PrintWriter +import java.util.stream.Collectors +import javax.inject.Inject + +/** Determines which device wake-ups should trigger face authentication. */ +@SysUISingleton +class FaceWakeUpTriggersConfig +@Inject +constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpManager: DumpManager) : + Dumpable { + private val defaultTriggerFaceAuthOnWakeUpFrom: Set = + resources.getIntArray(R.array.config_face_auth_wake_up_triggers).toSet() + private val triggerFaceAuthOnWakeUpFrom: Set + + init { + triggerFaceAuthOnWakeUpFrom = + if (Build.IS_DEBUGGABLE) { + // Update face wake triggers via adb on debuggable builds: + // ie: adb shell settings put global face_wake_triggers "1\|4" && + // adb shell am crash com.android.systemui + processStringArray( + globalSettings.getString("face_wake_triggers"), + defaultTriggerFaceAuthOnWakeUpFrom + ) + } else { + defaultTriggerFaceAuthOnWakeUpFrom + } + dumpManager.registerDumpable(this) + } + + fun shouldTriggerFaceAuthOnWakeUpFrom(@PowerManager.WakeReason pmWakeReason: Int): Boolean { + return triggerFaceAuthOnWakeUpFrom.contains(pmWakeReason) + } + + override fun dump(pw: PrintWriter, args: Array) { + pw.println("FaceWakeUpTriggers:") + for (pmWakeReason in triggerFaceAuthOnWakeUpFrom) { + pw.println(" ${PowerManager.wakeReasonToString(pmWakeReason)}") + } + } + + /** Convert a pipe-separated set of integers into a set of ints. */ + private fun processStringArray(stringSetting: String?, default: Set): Set { + return stringSetting?.let { + stringSetting.split("|").stream().map(Integer::parseInt).collect(Collectors.toSet()) + } + ?: default + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 46e187e041e47..ca0ffb14f6373 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -44,7 +44,6 @@ import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_TRUST_ENABL import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER; import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED; import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN; -import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_DREAM_STOPPED; import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_DURING_CANCELLATION; import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED; import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET; @@ -303,6 +302,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } }; + private final FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig; HashMap mSimDatas = new HashMap<>(); HashMap mServiceStates = new HashMap<>(); @@ -1823,11 +1823,21 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - protected void handleStartedWakingUp() { + protected void handleStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) { Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp"); Assert.isMainThread(); - updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_STARTED_WAKING_UP); - requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "wakingUp"); + + updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); + if (mFaceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(pmWakeReason)) { + FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason); + updateFaceListeningState(BIOMETRIC_ACTION_UPDATE, + FACE_AUTH_UPDATED_STARTED_WAKING_UP); + requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "wakingUp - " + + PowerManager.wakeReasonToString(pmWakeReason)); + } else { + mLogger.logSkipUpdateFaceListeningOnWakeup(pmWakeReason); + } + for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { @@ -1879,12 +1889,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab cb.onDreamingStateChanged(mIsDreaming); } } + updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); if (mIsDreaming) { - updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); updateFaceListeningState(BIOMETRIC_ACTION_STOP, FACE_AUTH_STOPPED_DREAM_STARTED); - } else { - updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, - FACE_AUTH_TRIGGERED_DREAM_STOPPED); } } @@ -1964,7 +1971,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab PackageManager packageManager, @Nullable FaceManager faceManager, @Nullable FingerprintManager fingerprintManager, - @Nullable BiometricManager biometricManager) { + @Nullable BiometricManager biometricManager, + FaceWakeUpTriggersConfig faceWakeUpTriggersConfig) { mContext = context; mSubscriptionManager = subscriptionManager; mTelephonyListenerManager = telephonyListenerManager; @@ -2003,6 +2011,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab R.array.config_face_acquire_device_entry_ignorelist)) .boxed() .collect(Collectors.toSet()); + mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig; mHandler = new Handler(mainLooper) { @Override @@ -2052,7 +2061,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab break; case MSG_STARTED_WAKING_UP: Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP"); - handleStartedWakingUp(); + handleStartedWakingUp(msg.arg1); Trace.endSection(); break; case MSG_SIM_SUBSCRIPTION_INFO_CHANGED: @@ -2801,8 +2810,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab // Waiting for ERROR_CANCELED before requesting auth again return; } - mLogger.logStartedListeningForFace(mFaceRunningState, faceAuthUiEvent.getReason()); - mUiEventLogger.log(faceAuthUiEvent, getKeyguardSessionId()); + mLogger.logStartedListeningForFace(mFaceRunningState, faceAuthUiEvent); + mUiEventLogger.logWithInstanceIdAndPosition( + faceAuthUiEvent, + 0, + null, + getKeyguardSessionId(), + faceAuthUiEvent.getExtraInfo() + ); if (unlockPossible) { mFaceCancelSignal = new CancellationSignal(); @@ -3581,11 +3596,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab // TODO: use these callbacks elsewhere in place of the existing notifyScreen*() // (KeyguardViewMediator, KeyguardHostView) - public void dispatchStartedWakingUp() { + /** + * Dispatch wakeup events to: + * - update biometric listening states + * - send to registered KeyguardUpdateMonitorCallbacks + */ + public void dispatchStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) { synchronized (this) { mDeviceInteractive = true; } - mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP); + mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_WAKING_UP, pmWakeReason, 0)); } public void dispatchStartedGoingToSleep(int why) { diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt index 82b32cf616ecb..9c2d966ec06ff 100644 --- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt +++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt @@ -17,9 +17,12 @@ package com.android.keyguard.logging import android.hardware.biometrics.BiometricConstants.LockoutMode +import android.os.PowerManager +import android.os.PowerManager.WakeReason import android.telephony.ServiceState import android.telephony.SubscriptionInfo import com.android.keyguard.ActiveUnlockConfig +import com.android.keyguard.FaceAuthUiEvent import com.android.keyguard.KeyguardListenModel import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.plugins.log.LogBuffer @@ -269,11 +272,19 @@ class KeyguardUpdateMonitorLogger @Inject constructor( logBuffer.log(TAG, VERBOSE, { int1 = subId }, { "reportSimUnlocked(subId=$int1)" }) } - fun logStartedListeningForFace(faceRunningState: Int, faceAuthReason: String) { + fun logStartedListeningForFace(faceRunningState: Int, faceAuthUiEvent: FaceAuthUiEvent) { logBuffer.log(TAG, VERBOSE, { int1 = faceRunningState - str1 = faceAuthReason - }, { "startListeningForFace(): $int1, reason: $str1" }) + str1 = faceAuthUiEvent.reason + str2 = faceAuthUiEvent.extraInfoToString() + }, { "startListeningForFace(): $int1, reason: $str1 $str2" }) + } + + fun logStartedListeningForFaceFromWakeUp(faceRunningState: Int, @WakeReason pmWakeReason: Int) { + logBuffer.log(TAG, VERBOSE, { + int1 = faceRunningState + str1 = PowerManager.wakeReasonToString(pmWakeReason) + }, { "startListeningForFace(): $int1, reason: wakeUp-$str1" }) } fun logStoppedListeningForFace(faceRunningState: Int, faceAuthReason: String) { @@ -383,4 +394,10 @@ class KeyguardUpdateMonitorLogger @Inject constructor( }, { "#update secure=$bool1 canDismissKeyguard=$bool2" + " trusted=$bool3 trustManaged=$bool4" }) } + + fun logSkipUpdateFaceListeningOnWakeup(@WakeReason pmWakeReason: Int) { + logBuffer.log(TAG, VERBOSE, { + str1 = PowerManager.wakeReasonToString(pmWakeReason) + }, { "Skip updating face listening state on wakeup from $str1"}) + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index ddcd0533c5883..8846bbd4754da 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -554,7 +554,7 @@ public class KeyguardService extends Service { @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) { Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp"); checkPermission(); - mKeyguardViewMediator.onStartedWakingUp(cameraGestureTriggered); + mKeyguardViewMediator.onStartedWakingUp(pmWakeReason, cameraGestureTriggered); mKeyguardLifecyclesDispatcher.dispatch( KeyguardLifecyclesDispatcher.STARTED_WAKING_UP, pmWakeReason); Trace.endSection(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index a3632705d865d..692af2e2e80e3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1567,7 +1567,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, /** * It will let us know when the device is waking up. */ - public void onStartedWakingUp(boolean cameraGestureTriggered) { + public void onStartedWakingUp(@PowerManager.WakeReason int pmWakeReason, + boolean cameraGestureTriggered) { Trace.beginSection("KeyguardViewMediator#onStartedWakingUp"); // TODO: Rename all screen off/on references to interactive/sleeping @@ -1582,7 +1583,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence); notifyStartedWakingUp(); } - mUpdateMonitor.dispatchStartedWakingUp(); + mUpdateMonitor.dispatchStartedWakingUp(pmWakeReason); maybeSendUserPresentBroadcast(); Trace.endSection(); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt new file mode 100644 index 0000000000000..6c5620d42abb2 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2022 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.keyguard + +import android.os.PowerManager +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.dump.DumpManager +import com.android.systemui.util.settings.GlobalSettings +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class FaceWakeUpTriggersConfigTest : SysuiTestCase() { + @Mock lateinit var globalSettings: GlobalSettings + @Mock lateinit var dumpManager: DumpManager + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + } + + @Test + fun testShouldTriggerFaceAuthOnWakeUpFrom_inConfig_returnsTrue() { + val faceWakeUpTriggersConfig = + createFaceWakeUpTriggersConfig( + intArrayOf(PowerManager.WAKE_REASON_POWER_BUTTON, PowerManager.WAKE_REASON_GESTURE) + ) + + assertTrue( + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom( + PowerManager.WAKE_REASON_POWER_BUTTON + ) + ) + assertTrue( + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom( + PowerManager.WAKE_REASON_GESTURE + ) + ) + assertFalse( + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom( + PowerManager.WAKE_REASON_APPLICATION + ) + ) + } + + private fun createFaceWakeUpTriggersConfig(wakeUpTriggers: IntArray): FaceWakeUpTriggersConfig { + overrideResource( + com.android.systemui.R.array.config_face_auth_wake_up_triggers, + wakeUpTriggers + ) + + return FaceWakeUpTriggersConfig(mContext.getResources(), globalSettings, dumpManager) + } +} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 784e7ddb6d06f..cba0e800a21c6 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -108,6 +108,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.telephony.TelephonyListenerManager; +import com.android.systemui.util.settings.GlobalSettings; import org.junit.After; import org.junit.Assert; @@ -208,6 +209,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private UiEventLogger mUiEventLogger; @Mock private PowerManager mPowerManager; + @Mock + private GlobalSettings mGlobalSettings; + private FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig; private final int mCurrentUserId = 100; private final UserInfo mCurrentUserInfo = new UserInfo(mCurrentUserId, "Test user", 0); @@ -292,6 +296,12 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { .when(ActivityManager::getCurrentUser); ExtendedMockito.doReturn(mActivityService).when(ActivityManager::getService); + mFaceWakeUpTriggersConfig = new FaceWakeUpTriggersConfig( + mContext.getResources(), + mGlobalSettings, + mDumpManager + ); + mTestableLooper = TestableLooper.get(this); allowTestableLooperAsMainThread(); mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mContext); @@ -605,16 +615,22 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testTriesToAuthenticate_whenKeyguard() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); - mTestableLooper.processAllMessages(); keyguardIsVisible(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); + mTestableLooper.processAllMessages(); verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); + verify(mUiEventLogger).logWithInstanceIdAndPosition( + eq(FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP), + eq(0), + eq(null), + any(), + eq(PowerManager.WAKE_REASON_POWER_BUTTON)); } @Test public void skipsAuthentication_whenStatusBarShadeLocked() { mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED); - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); @@ -628,7 +644,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { STRONG_AUTH_REQUIRED_AFTER_BOOT); mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController); - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(), @@ -652,7 +668,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController); when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth); - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); @@ -677,7 +693,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testTriesToAuthenticate_whenTrustOnAgentKeyguard_ifBypass() { mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController); - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); when(mKeyguardBypassController.canBypass()).thenReturn(true); mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, @@ -689,7 +705,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testIgnoresAuth_whenTrustAgentOnKeyguard_withoutBypass() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */, new ArrayList<>()); @@ -700,7 +716,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testIgnoresAuth_whenLockdown() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn( KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); @@ -712,7 +728,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testTriesToAuthenticate_whenLockout() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn( KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT); @@ -736,7 +752,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testFaceAndFingerprintLockout_onlyFace() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); @@ -747,7 +763,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testFaceAndFingerprintLockout_onlyFingerprint() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); @@ -759,7 +775,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testFaceAndFingerprintLockout() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); @@ -858,7 +874,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { when(mFaceManager.getLockoutModeForUser(eq(FACE_SENSOR_ID), eq(newUser))) .thenReturn(faceLockoutMode); - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); @@ -1032,7 +1048,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testOccludingAppFingerprintListeningState() { // GIVEN keyguard isn't visible (app occluding) - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mKeyguardUpdateMonitor.setKeyguardShowing(true, true); when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true); @@ -1047,7 +1063,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testOccludingAppRequestsFingerprint() { // GIVEN keyguard isn't visible (app occluding) - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mKeyguardUpdateMonitor.setKeyguardShowing(true, true); // WHEN an occluding app requests fp @@ -1138,7 +1154,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { biometricsNotDisabledThroughDevicePolicyManager(); mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED); setKeyguardBouncerVisibility(false /* isVisible */); - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); when(mKeyguardBypassController.canBypass()).thenReturn(true); keyguardIsVisible(); @@ -1517,7 +1533,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testFingerprintCanAuth_whenCancellationNotReceivedAndAuthFailed() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); mTestableLooper.processAllMessages(); keyguardIsVisible(); @@ -1566,6 +1582,36 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString()); } + @Test + public void testDreamingStopped_faceDoesNotRun() { + mKeyguardUpdateMonitor.dispatchDreamingStopped(); + mTestableLooper.processAllMessages(); + + verify(mFaceManager, never()).authenticate( + any(), any(), any(), any(), anyInt(), anyBoolean()); + } + + @Test + public void testFaceWakeupTrigger_runFaceAuth_onlyOnConfiguredTriggers() { + // keyguard is visible + keyguardIsVisible(); + + // WHEN device wakes up from an application + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_APPLICATION); + mTestableLooper.processAllMessages(); + + // THEN face auth isn't triggered + verify(mFaceManager, never()).authenticate( + any(), any(), any(), any(), anyInt(), anyBoolean()); + + // WHEN device wakes up from the power button + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); + mTestableLooper.processAllMessages(); + + // THEN face auth is triggered + verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean()); + } + private void cleanupKeyguardUpdateMonitor() { if (mKeyguardUpdateMonitor != null) { mKeyguardUpdateMonitor.removeCallback(mTestCallback); @@ -1686,7 +1732,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } private void deviceIsInteractive() { - mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON); } private void bouncerFullyVisible() { @@ -1736,7 +1782,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitorLogger, mUiEventLogger, () -> mSessionTracker, mPowerManager, mTrustManager, mSubscriptionManager, mUserManager, mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager, - mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager); + mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager, + mFaceWakeUpTriggersConfig); setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker); }