summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Beverly <beverlyt@google.com> 2023-08-02 17:06:43 +0000
committer Beverly Tai <beverlyt@google.com> 2023-08-08 13:52:26 +0000
commitcf5dace338e97cf8dd65bc33213a7f35f5c34c9d (patch)
tree1cc69820c837e9f800dd4c28e22f46d678bfc5b0
parente1f15885277fcd88db32e4e16701ffdc551eda41 (diff)
Immediately stop running face auth if the display is OFF
And prevent face auth from running if the display is OFF. Only prevent running face auth based on the display state if the feature flag 'flag_stop_face_auth_on_display_off" is enabled. In general, face auth relies on the "waking up" and "going to sleep" signals. That said, when the device starts "waking up", immediately update the allowedDisplayState to TRUE to pre-emptively prep for the display state changing to ON, since display state changes do not START face auth again. Also fixes out of order KeyguardFaceListenModel. Test: atest KeyguardUpdateMonitortest Test: manual Bug: 290077758 Bug: 294221702 Change-Id: Ie68db6a998fdff1c8b2b79d75650f999bcc55c13 Merged-In: Ie68db6a998fdff1c8b2b79d75650f999bcc55c13
-rw-r--r--packages/SystemUI/res/values/flags.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java109
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt10
9 files changed, 174 insertions, 14 deletions
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index 763930db1d55..c2dba6c41d12 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -38,4 +38,6 @@
protected. -->
<bool name="flag_battery_shield_icon">false</bool>
+ <!-- Whether face auth will immediately stop when the display state is OFF -->
+ <bool name="flag_stop_face_auth_on_display_off">false</bool>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
index 22cdb30376d0..2abb7a41ef08 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
@@ -33,6 +33,7 @@ import com.android.keyguard.InternalFaceAuthReasons.AUTH_REQUEST_DURING_CANCELLA
import com.android.keyguard.InternalFaceAuthReasons.BIOMETRIC_ENABLED
import com.android.keyguard.InternalFaceAuthReasons.CAMERA_LAUNCHED
import com.android.keyguard.InternalFaceAuthReasons.DEVICE_WOKEN_UP_ON_REACH_GESTURE
+import com.android.keyguard.InternalFaceAuthReasons.DISPLAY_OFF
import com.android.keyguard.InternalFaceAuthReasons.DREAM_STARTED
import com.android.keyguard.InternalFaceAuthReasons.DREAM_STOPPED
import com.android.keyguard.InternalFaceAuthReasons.ENROLLMENTS_CHANGED
@@ -131,6 +132,7 @@ private object InternalFaceAuthReasons {
const val NON_STRONG_BIOMETRIC_ALLOWED_CHANGED =
"Face auth stopped because non strong biometric allowed changed"
const val POSTURE_CHANGED = "Face auth started/stopped due to device posture changed."
+ const val DISPLAY_OFF = "Face auth stopped due to display state OFF."
}
/**
@@ -221,7 +223,8 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED(1255, STRONG_AUTH_ALLOWED_CHANGED),
@UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, NON_STRONG_BIOMETRIC_ALLOWED_CHANGED),
- @UiEvent(doc = ACCESSIBILITY_ACTION) FACE_AUTH_ACCESSIBILITY_ACTION(1454, ACCESSIBILITY_ACTION);
+ @UiEvent(doc = ACCESSIBILITY_ACTION) FACE_AUTH_ACCESSIBILITY_ACTION(1454, ACCESSIBILITY_ACTION),
+ @UiEvent(doc = DISPLAY_OFF) FACE_AUTH_DISPLAY_OFF(1461, DISPLAY_OFF);
override fun getId(): Int = this.id
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
index 461d390fd477..bb799fc55171 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
@@ -27,6 +27,7 @@ data class KeyguardFaceListenModel(
override var userId: Int = 0,
override var listening: Boolean = false,
// keep sorted
+ var allowedDisplayState: Boolean = false,
var alternateBouncerShowing: Boolean = false,
var authInterruptActive: Boolean = false,
var biometricSettingEnabledForUser: Boolean = false,
@@ -57,6 +58,8 @@ data class KeyguardFaceListenModel(
userId.toString(),
listening.toString(),
// keep sorted
+ allowedDisplayState.toString(),
+ alternateBouncerShowing.toString(),
authInterruptActive.toString(),
biometricSettingEnabledForUser.toString(),
bouncerFullyShown.toString(),
@@ -74,7 +77,6 @@ data class KeyguardFaceListenModel(
supportsDetect.toString(),
switchingUser.toString(),
systemUser.toString(),
- alternateBouncerShowing.toString(),
udfpsFingerDown.toString(),
userNotTrustedOrDetectionIsNeeded.toString(),
)
@@ -96,7 +98,9 @@ data class KeyguardFaceListenModel(
userId = model.userId
listening = model.listening
// keep sorted
+ allowedDisplayState = model.allowedDisplayState
alternateBouncerShowing = model.alternateBouncerShowing
+ authInterruptActive = model.authInterruptActive
biometricSettingEnabledForUser = model.biometricSettingEnabledForUser
bouncerFullyShown = model.bouncerFullyShown
faceAndFpNotAuthenticated = model.faceAndFpNotAuthenticated
@@ -105,7 +109,6 @@ data class KeyguardFaceListenModel(
faceLockedOut = model.faceLockedOut
goingToSleep = model.goingToSleep
keyguardAwake = model.keyguardAwake
- goingToSleep = model.goingToSleep
keyguardGoingAway = model.keyguardGoingAway
listeningForFaceAssistant = model.listeningForFaceAssistant
occludingAppRequestingFaceAuth = model.occludingAppRequestingFaceAuth
@@ -140,6 +143,8 @@ data class KeyguardFaceListenModel(
"userId",
"listening",
// keep sorted
+ "allowedDisplayState",
+ "alternateBouncerShowing",
"authInterruptActive",
"biometricSettingEnabledForUser",
"bouncerFullyShown",
@@ -157,7 +162,6 @@ data class KeyguardFaceListenModel(
"supportsDetect",
"switchingUser",
"systemUser",
- "udfpsBouncerShowing",
"udfpsFingerDown",
"userNotTrustedOrDetectionIsNeeded",
)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1def25fbd0f8..bd88b78b1bc9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -37,6 +37,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.keyguard.FaceAuthReasonKt.apiRequestReasonToUiEvent;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_DISPLAY_OFF;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_DREAM_STARTED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED;
@@ -131,6 +132,7 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.view.Display;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -155,6 +157,8 @@ 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.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.domain.interactor.FaceAuthenticationListener;
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
import com.android.systemui.keyguard.shared.constants.TrustAgentUiEvent;
@@ -169,6 +173,7 @@ 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;
+import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -327,6 +332,25 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
};
+ private final DisplayTracker.Callback mDisplayCallback = new DisplayTracker.Callback() {
+ @Override
+ public void onDisplayChanged(int displayId) {
+ if (displayId != Display.DEFAULT_DISPLAY) {
+ return;
+ }
+
+ if (mDisplayTracker.getDisplay(mDisplayTracker.getDefaultDisplayId()).getState()
+ == Display.STATE_OFF) {
+ mAllowedDisplayStateForFaceAuth = false;
+ updateFaceListeningState(
+ BIOMETRIC_ACTION_STOP,
+ FACE_AUTH_DISPLAY_OFF
+ );
+ } else {
+ mAllowedDisplayStateForFaceAuth = true;
+ }
+ }
+ };
private final FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;
HashMap<Integer, SimData> mSimDatas = new HashMap<>();
@@ -347,6 +371,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private boolean mOccludingAppRequestingFp;
private boolean mOccludingAppRequestingFace;
private boolean mSecureCameraLaunched;
+ private boolean mAllowedDisplayStateForFaceAuth = true;
@VisibleForTesting
protected boolean mTelephonyCapable;
@@ -391,6 +416,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final FaceManager mFaceManager;
@Nullable
private KeyguardFaceAuthInteractor mFaceAuthInteractor;
+ private final DisplayTracker mDisplayTracker;
private final LockPatternUtils mLockPatternUtils;
@VisibleForTesting
@DevicePostureInt
@@ -2186,6 +2212,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Assert.isMainThread();
+ mAllowedDisplayStateForFaceAuth = true;
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
if (mFaceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(pmWakeReason)) {
FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason);
@@ -2338,7 +2365,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Nullable BiometricManager biometricManager,
FaceWakeUpTriggersConfig faceWakeUpTriggersConfig,
DevicePostureController devicePostureController,
- Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider) {
+ Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider,
+ FeatureFlags featureFlags,
+ DisplayTracker displayTracker) {
mContext = context;
mSubscriptionManager = subscriptionManager;
mUserTracker = userTracker;
@@ -2379,6 +2408,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mConfigFaceAuthSupportedPosture = mContext.getResources().getInteger(
R.integer.config_face_auth_supported_posture);
mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig;
+ mDisplayTracker = displayTracker;
+ if (featureFlags.isEnabled(Flags.STOP_FACE_AUTH_ON_DISPLAY_OFF)) {
+ mDisplayTracker.addDisplayChangeCallback(mDisplayCallback, mainExecutor);
+ }
mHandler = new Handler(mainLooper) {
@Override
@@ -3185,7 +3218,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& (!mSecureCameraLaunched || mAlternateBouncerShowing)
&& faceAndFpNotAuthenticated
&& !mGoingToSleep
- && isPostureAllowedForFaceAuth;
+ && isPostureAllowedForFaceAuth
+ && mAllowedDisplayStateForFaceAuth;
// Aggregate relevant fields for debug logging.
logListenerModelData(
@@ -3193,6 +3227,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
System.currentTimeMillis(),
user,
shouldListen,
+ mAllowedDisplayStateForFaceAuth,
mAlternateBouncerShowing,
mAuthInterruptActive,
biometricEnabledForUser,
@@ -4337,6 +4372,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mLockPatternUtils.unregisterStrongAuthTracker(mStrongAuthTracker);
mTrustManager.unregisterTrustListener(this);
+ mDisplayTracker.removeCallback(mDisplayCallback);
mHandler.removeCallbacksAndMessages(null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 5087b8bd18c9..ee9482c730af 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -268,6 +268,11 @@ object Flags {
@JvmField
val KEYGUARD_TALKBACK_FIX = releasedFlag(238, "keyguard_talkback_fix")
+ /** Stop running face auth when the display state changes to OFF. */
+ // TODO(b/294221702): Tracking bug.
+ @JvmField val STOP_FACE_AUTH_ON_DISPLAY_OFF = resourceBooleanFlag(245,
+ R.bool.flag_stop_face_auth_on_display_off, "stop_face_auth_on_display_off")
+
// 300 - power menu
// TODO(b/254512600): Tracking Bug
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
diff --git a/packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt
index bb7f721ad61f..d5571d41d505 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt
@@ -48,6 +48,9 @@ interface DisplayTracker {
/** Remove a [Callback] previously added. */
fun removeCallback(callback: Callback)
+ /** Gets the Display with the given displayId */
+ fun getDisplay(displayId: Int): Display
+
/** Ćallback for notifying of changes. */
interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
index 5169f88c373c..68cc483fbe80 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
@@ -115,6 +115,10 @@ internal constructor(
}
}
+ override fun getDisplay(displayId: Int): Display {
+ return displayManager.getDisplay(displayId)
+ }
+
@WorkerThread
private fun onDisplayAdded(displayId: Int, list: List<DisplayTrackerDataItem>) {
Assert.isNotMainThread()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 3cb4c0c51252..1a9ac0b7b0a6 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -38,6 +38,7 @@ import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELL
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
+import static com.android.systemui.flags.Flags.STOP_FACE_AUTH_ON_DISPLAY_OFF;
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED;
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED;
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
@@ -84,6 +85,7 @@ import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
+import android.hardware.display.DisplayManagerGlobal;
import android.hardware.face.FaceAuthenticateOptions;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorProperties;
@@ -115,6 +117,9 @@ import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.view.Display;
+import android.view.DisplayAdjustments;
+import android.view.DisplayInfo;
import androidx.annotation.NonNull;
@@ -134,8 +139,10 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -288,10 +295,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mFingerprintAuthenticatorsRegisteredCallback;
private IFaceAuthenticatorsRegisteredCallback mFaceAuthenticatorsRegisteredCallback;
private final InstanceId mKeyguardInstanceId = InstanceId.fakeInstanceId(999);
+ private FakeFeatureFlags mFeatureFlags;
+ private FakeDisplayTracker mDisplayTracker;
@Before
public void setup() throws RemoteException {
MockitoAnnotations.initMocks(this);
+ mDisplayTracker = new FakeDisplayTracker(mContext);
when(mSessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(mKeyguardInstanceId);
when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true);
@@ -326,6 +336,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mTestableLooper = TestableLooper.get(this);
allowTestableLooperAsMainThread();
+ mFeatureFlags = new FakeFeatureFlags();
+ mFeatureFlags.set(STOP_FACE_AUTH_ON_DISPLAY_OFF, false);
when(mSecureSettings.getUriFor(anyString())).thenReturn(mURI);
@@ -336,6 +348,11 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
anyInt());
mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mContext);
+ setupBiometrics(mKeyguardUpdateMonitor);
+ }
+
+ private void setupBiometrics(KeyguardUpdateMonitor keyguardUpdateMonitor)
+ throws RemoteException {
captureAuthenticatorsRegisteredCallbacks();
setupFaceAuth(/* isClass3 */ false);
setupFingerprintAuth(/* isClass3 */ true);
@@ -345,9 +362,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mBiometricEnabledOnKeyguardCallback = mBiometricEnabledCallbackArgCaptor.getValue();
biometricsEnabledForCurrentUser();
- mHandler = spy(mKeyguardUpdateMonitor.getHandler());
+ mHandler = spy(keyguardUpdateMonitor.getHandler());
try {
- FieldSetter.setField(mKeyguardUpdateMonitor,
+ FieldSetter.setField(keyguardUpdateMonitor,
KeyguardUpdateMonitor.class.getDeclaredField("mHandler"), mHandler);
} catch (NoSuchFieldException e) {
@@ -2945,6 +2962,79 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
TelephonyManager.SIM_STATE_NOT_READY);
}
+ @Test
+ public void stopFaceAuthOnDisplayOffFlagNotEnabled_doNotRegisterForDisplayCallback() {
+ assertThat(mDisplayTracker.getDisplayCallbacks().size()).isEqualTo(0);
+ }
+
+ @Test
+ public void onDisplayOn_nothingHappens() throws RemoteException {
+ // GIVEN
+ keyguardIsVisible();
+ enableStopFaceAuthOnDisplayOff();
+
+ // WHEN the default display state changes to ON
+ triggerDefaultDisplayStateChangeToOn();
+
+ // THEN face auth is NOT started since we rely on STARTED_WAKING_UP to start face auth,
+ // NOT the display on event
+ verifyFaceAuthenticateNeverCalled();
+ verifyFaceDetectNeverCalled();
+ }
+
+ @Test
+ public void onDisplayOff_stopFaceAuth() throws RemoteException {
+ enableStopFaceAuthOnDisplayOff();
+
+ // GIVEN device is listening for face
+ mKeyguardUpdateMonitor.setKeyguardShowing(true, false);
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
+ mTestableLooper.processAllMessages();
+ verifyFaceAuthenticateCall();
+
+ final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
+ mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
+ KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
+ mKeyguardUpdateMonitor.registerCallback(callback);
+
+ // WHEN the default display state changes to OFF
+ triggerDefaultDisplayStateChangeToOff();
+
+ // THEN face listening is stopped.
+ verify(faceCancel).cancel();
+ verify(callback).onBiometricRunningStateChanged(
+ eq(false), eq(BiometricSourceType.FACE)); // beverlyt
+
+ }
+
+ private void triggerDefaultDisplayStateChangeToOn() {
+ triggerDefaultDisplayStateChangeTo(true);
+ }
+
+ private void triggerDefaultDisplayStateChangeToOff() {
+ triggerDefaultDisplayStateChangeTo(false);
+ }
+
+ /**
+ * @param on true for Display.STATE_ON, else Display.STATE_OFF
+ */
+ private void triggerDefaultDisplayStateChangeTo(boolean on) {
+ DisplayManagerGlobal displayManagerGlobal = mock(DisplayManagerGlobal.class);
+ DisplayInfo displayInfoWithDisplayState = new DisplayInfo();
+ displayInfoWithDisplayState.state = on ? Display.STATE_ON : Display.STATE_OFF;
+ when(displayManagerGlobal.getDisplayInfo(mDisplayTracker.getDefaultDisplayId()))
+ .thenReturn(displayInfoWithDisplayState);
+ mDisplayTracker.setAllDisplays(new Display[]{
+ new Display(
+ displayManagerGlobal,
+ mDisplayTracker.getDefaultDisplayId(),
+ displayInfoWithDisplayState,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
+ )
+ });
+ mDisplayTracker.triggerOnDisplayChanged(mDisplayTracker.getDefaultDisplayId());
+ }
+
private void verifyFingerprintAuthenticateNeverCalled() {
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
@@ -3213,6 +3303,18 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mTestableLooper.processAllMessages();
}
+ private void enableStopFaceAuthOnDisplayOff() throws RemoteException {
+ cleanupKeyguardUpdateMonitor();
+ clearInvocations(mFaceManager);
+ clearInvocations(mFingerprintManager);
+ clearInvocations(mBiometricManager);
+ clearInvocations(mStatusBarStateController);
+ mFeatureFlags.set(STOP_FACE_AUTH_ON_DISPLAY_OFF, true);
+ mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mContext);
+ setupBiometrics(mKeyguardUpdateMonitor);
+ assertThat(mDisplayTracker.getDisplayCallbacks().size()).isEqualTo(1);
+ }
+
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
int subscription = simInited
? 1/* mock subid=1 */ : SubscriptionManager.PLACEHOLDER_SUBSCRIPTION_ID_BASE;
@@ -3272,7 +3374,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
mFaceWakeUpTriggersConfig, mDevicePostureController,
- Optional.of(mInteractiveToAuthProvider));
+ Optional.of(mInteractiveToAuthProvider), mFeatureFlags,
+ mDisplayTracker);
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt
index 1403cea1c625..3fd11a1db96f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt
@@ -26,7 +26,7 @@ class FakeDisplayTracker constructor(val context: Context) : DisplayTracker {
override var defaultDisplayId: Int = Display.DEFAULT_DISPLAY
override var allDisplays: Array<Display> = displayManager.displays
- private val displayCallbacks: MutableList<DisplayTracker.Callback> = ArrayList()
+ val displayCallbacks: MutableList<DisplayTracker.Callback> = ArrayList()
private val brightnessCallbacks: MutableList<DisplayTracker.Callback> = ArrayList()
override fun addDisplayChangeCallback(callback: DisplayTracker.Callback, executor: Executor) {
displayCallbacks.add(callback)
@@ -43,12 +43,12 @@ class FakeDisplayTracker constructor(val context: Context) : DisplayTracker {
brightnessCallbacks.remove(callback)
}
- fun setDefaultDisplay(displayId: Int) {
- defaultDisplayId = displayId
+ override fun getDisplay(displayId: Int): Display {
+ return allDisplays.filter { display -> display.displayId == displayId }[0]
}
- fun setDisplays(displays: Array<Display>) {
- allDisplays = displays
+ fun setDefaultDisplay(displayId: Int) {
+ defaultDisplayId = displayId
}
fun triggerOnDisplayAdded(displayId: Int) {