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
This commit is contained in:
Beverly
2022-10-19 19:17:34 +00:00
parent 5acc7d2615
commit 897dcdb85a
9 changed files with 322 additions and 101 deletions

View File

@@ -643,6 +643,18 @@
<item>26</item> <!-- MOUTH_COVERING_DETECTED -->
</integer-array>
<!-- Which device wake-ups will trigger face auth. These values correspond with
PowerManager#WakeReason. -->
<integer-array name="config_face_auth_wake_up_triggers">
<item>1</item> <!-- WAKE_REASON_POWER_BUTTON -->
<item>4</item> <!-- WAKE_REASON_GESTURE -->
<item>6</item> <!-- WAKE_REASON_WAKE_KEY -->
<item>7</item> <!-- WAKE_REASON_WAKE_MOTION -->
<item>9</item> <!-- WAKE_REASON_LID -->
<item>10</item> <!-- WAKE_REASON_DISPLAY_GROUP_ADDED -->
<item>12</item> <!-- WAKE_REASON_UNFOLD_DEVICE -->
</integer-array>
<!-- Whether the communal service should be enabled -->
<bool name="config_communalServiceEnabled">false</bool>

View File

@@ -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 =

View File

@@ -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<Int> =
resources.getIntArray(R.array.config_face_auth_wake_up_triggers).toSet()
private val triggerFaceAuthOnWakeUpFrom: Set<Int>
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<out String>) {
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<Int>): Set<Int> {
return stringSetting?.let {
stringSetting.split("|").stream().map(Integer::parseInt).collect(Collectors.toSet())
}
?: default
}
}

View File

@@ -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<Integer, SimData> mSimDatas = new HashMap<>();
HashMap<Integer, ServiceState> 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) {

View File

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

View File

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

View File

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

View File

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

View File

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