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
This commit is contained in:
@@ -38,4 +38,6 @@
|
|||||||
protected. -->
|
protected. -->
|
||||||
<bool name="flag_battery_shield_icon">false</bool>
|
<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>
|
</resources>
|
||||||
|
|||||||
@@ -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.BIOMETRIC_ENABLED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.CAMERA_LAUNCHED
|
import com.android.keyguard.InternalFaceAuthReasons.CAMERA_LAUNCHED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.DEVICE_WOKEN_UP_ON_REACH_GESTURE
|
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_STARTED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.DREAM_STOPPED
|
import com.android.keyguard.InternalFaceAuthReasons.DREAM_STOPPED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.ENROLLMENTS_CHANGED
|
import com.android.keyguard.InternalFaceAuthReasons.ENROLLMENTS_CHANGED
|
||||||
@@ -131,6 +132,7 @@ private object InternalFaceAuthReasons {
|
|||||||
const val NON_STRONG_BIOMETRIC_ALLOWED_CHANGED =
|
const val NON_STRONG_BIOMETRIC_ALLOWED_CHANGED =
|
||||||
"Face auth stopped because 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 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),
|
FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED(1255, STRONG_AUTH_ALLOWED_CHANGED),
|
||||||
@UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
|
@UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
|
||||||
FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, 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
|
override fun getId(): Int = this.id
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ data class KeyguardFaceListenModel(
|
|||||||
override var userId: Int = 0,
|
override var userId: Int = 0,
|
||||||
override var listening: Boolean = false,
|
override var listening: Boolean = false,
|
||||||
// keep sorted
|
// keep sorted
|
||||||
|
var allowedDisplayState: Boolean = false,
|
||||||
var alternateBouncerShowing: Boolean = false,
|
var alternateBouncerShowing: Boolean = false,
|
||||||
var authInterruptActive: Boolean = false,
|
var authInterruptActive: Boolean = false,
|
||||||
var biometricSettingEnabledForUser: Boolean = false,
|
var biometricSettingEnabledForUser: Boolean = false,
|
||||||
@@ -57,6 +58,8 @@ data class KeyguardFaceListenModel(
|
|||||||
userId.toString(),
|
userId.toString(),
|
||||||
listening.toString(),
|
listening.toString(),
|
||||||
// keep sorted
|
// keep sorted
|
||||||
|
allowedDisplayState.toString(),
|
||||||
|
alternateBouncerShowing.toString(),
|
||||||
authInterruptActive.toString(),
|
authInterruptActive.toString(),
|
||||||
biometricSettingEnabledForUser.toString(),
|
biometricSettingEnabledForUser.toString(),
|
||||||
bouncerFullyShown.toString(),
|
bouncerFullyShown.toString(),
|
||||||
@@ -74,7 +77,6 @@ data class KeyguardFaceListenModel(
|
|||||||
supportsDetect.toString(),
|
supportsDetect.toString(),
|
||||||
switchingUser.toString(),
|
switchingUser.toString(),
|
||||||
systemUser.toString(),
|
systemUser.toString(),
|
||||||
alternateBouncerShowing.toString(),
|
|
||||||
udfpsFingerDown.toString(),
|
udfpsFingerDown.toString(),
|
||||||
userNotTrustedOrDetectionIsNeeded.toString(),
|
userNotTrustedOrDetectionIsNeeded.toString(),
|
||||||
)
|
)
|
||||||
@@ -96,7 +98,9 @@ data class KeyguardFaceListenModel(
|
|||||||
userId = model.userId
|
userId = model.userId
|
||||||
listening = model.listening
|
listening = model.listening
|
||||||
// keep sorted
|
// keep sorted
|
||||||
|
allowedDisplayState = model.allowedDisplayState
|
||||||
alternateBouncerShowing = model.alternateBouncerShowing
|
alternateBouncerShowing = model.alternateBouncerShowing
|
||||||
|
authInterruptActive = model.authInterruptActive
|
||||||
biometricSettingEnabledForUser = model.biometricSettingEnabledForUser
|
biometricSettingEnabledForUser = model.biometricSettingEnabledForUser
|
||||||
bouncerFullyShown = model.bouncerFullyShown
|
bouncerFullyShown = model.bouncerFullyShown
|
||||||
faceAndFpNotAuthenticated = model.faceAndFpNotAuthenticated
|
faceAndFpNotAuthenticated = model.faceAndFpNotAuthenticated
|
||||||
@@ -105,7 +109,6 @@ data class KeyguardFaceListenModel(
|
|||||||
faceLockedOut = model.faceLockedOut
|
faceLockedOut = model.faceLockedOut
|
||||||
goingToSleep = model.goingToSleep
|
goingToSleep = model.goingToSleep
|
||||||
keyguardAwake = model.keyguardAwake
|
keyguardAwake = model.keyguardAwake
|
||||||
goingToSleep = model.goingToSleep
|
|
||||||
keyguardGoingAway = model.keyguardGoingAway
|
keyguardGoingAway = model.keyguardGoingAway
|
||||||
listeningForFaceAssistant = model.listeningForFaceAssistant
|
listeningForFaceAssistant = model.listeningForFaceAssistant
|
||||||
occludingAppRequestingFaceAuth = model.occludingAppRequestingFaceAuth
|
occludingAppRequestingFaceAuth = model.occludingAppRequestingFaceAuth
|
||||||
@@ -140,6 +143,8 @@ data class KeyguardFaceListenModel(
|
|||||||
"userId",
|
"userId",
|
||||||
"listening",
|
"listening",
|
||||||
// keep sorted
|
// keep sorted
|
||||||
|
"allowedDisplayState",
|
||||||
|
"alternateBouncerShowing",
|
||||||
"authInterruptActive",
|
"authInterruptActive",
|
||||||
"biometricSettingEnabledForUser",
|
"biometricSettingEnabledForUser",
|
||||||
"bouncerFullyShown",
|
"bouncerFullyShown",
|
||||||
@@ -157,7 +162,6 @@ data class KeyguardFaceListenModel(
|
|||||||
"supportsDetect",
|
"supportsDetect",
|
||||||
"switchingUser",
|
"switchingUser",
|
||||||
"systemUser",
|
"systemUser",
|
||||||
"udfpsBouncerShowing",
|
|
||||||
"udfpsFingerDown",
|
"udfpsFingerDown",
|
||||||
"userNotTrustedOrDetectionIsNeeded",
|
"userNotTrustedOrDetectionIsNeeded",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -41,6 +41,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_LOCKOUT;
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
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.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_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_DREAM_STARTED;
|
||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED;
|
||||||
@@ -135,6 +136,7 @@ import android.telephony.TelephonyManager;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
|
import android.view.Display;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -175,6 +177,7 @@ import com.android.systemui.keyguard.shared.model.SysUiFaceAuthenticateOptions;
|
|||||||
import com.android.systemui.log.SessionTracker;
|
import com.android.systemui.log.SessionTracker;
|
||||||
import com.android.systemui.plugins.WeatherData;
|
import com.android.systemui.plugins.WeatherData;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
|
import com.android.systemui.settings.DisplayTracker;
|
||||||
import com.android.systemui.settings.UserTracker;
|
import com.android.systemui.settings.UserTracker;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListeners;
|
import com.android.systemui.shared.system.TaskStackChangeListeners;
|
||||||
@@ -335,6 +338,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;
|
private final FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;
|
||||||
|
|
||||||
HashMap<Integer, SimData> mSimDatas = new HashMap<>();
|
HashMap<Integer, SimData> mSimDatas = new HashMap<>();
|
||||||
@@ -355,6 +377,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
private boolean mOccludingAppRequestingFp;
|
private boolean mOccludingAppRequestingFp;
|
||||||
private boolean mOccludingAppRequestingFace;
|
private boolean mOccludingAppRequestingFace;
|
||||||
private boolean mSecureCameraLaunched;
|
private boolean mSecureCameraLaunched;
|
||||||
|
private boolean mAllowedDisplayStateForFaceAuth = true;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected boolean mTelephonyCapable;
|
protected boolean mTelephonyCapable;
|
||||||
private boolean mAllowFingerprintOnCurrentOccludingActivity;
|
private boolean mAllowFingerprintOnCurrentOccludingActivity;
|
||||||
@@ -403,6 +426,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
private KeyguardFaceAuthInteractor mFaceAuthInteractor;
|
private KeyguardFaceAuthInteractor mFaceAuthInteractor;
|
||||||
private final TaskStackChangeListeners mTaskStackChangeListeners;
|
private final TaskStackChangeListeners mTaskStackChangeListeners;
|
||||||
private final IActivityTaskManager mActivityTaskManager;
|
private final IActivityTaskManager mActivityTaskManager;
|
||||||
|
private final DisplayTracker mDisplayTracker;
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
private final LockPatternUtils mLockPatternUtils;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@DevicePostureInt
|
@DevicePostureInt
|
||||||
@@ -2187,6 +2211,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
|
Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
|
|
||||||
|
mAllowedDisplayStateForFaceAuth = true;
|
||||||
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
|
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
|
||||||
if (mFaceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(pmWakeReason)) {
|
if (mFaceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(pmWakeReason)) {
|
||||||
FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason);
|
FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason);
|
||||||
@@ -2342,7 +2367,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider,
|
Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider,
|
||||||
FeatureFlags featureFlags,
|
FeatureFlags featureFlags,
|
||||||
TaskStackChangeListeners taskStackChangeListeners,
|
TaskStackChangeListeners taskStackChangeListeners,
|
||||||
IActivityTaskManager activityTaskManagerService) {
|
IActivityTaskManager activityTaskManagerService,
|
||||||
|
DisplayTracker displayTracker) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSubscriptionManager = subscriptionManager;
|
mSubscriptionManager = subscriptionManager;
|
||||||
mUserTracker = userTracker;
|
mUserTracker = userTracker;
|
||||||
@@ -2390,6 +2416,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
mTaskStackChangeListeners = taskStackChangeListeners;
|
mTaskStackChangeListeners = taskStackChangeListeners;
|
||||||
mActivityTaskManager = activityTaskManagerService;
|
mActivityTaskManager = activityTaskManagerService;
|
||||||
|
mDisplayTracker = displayTracker;
|
||||||
|
if (mFeatureFlags.isEnabled(Flags.STOP_FACE_AUTH_ON_DISPLAY_OFF)) {
|
||||||
|
mDisplayTracker.addDisplayChangeCallback(mDisplayCallback, mainExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
mHandler = new Handler(mainLooper) {
|
mHandler = new Handler(mainLooper) {
|
||||||
@Override
|
@Override
|
||||||
@@ -3199,7 +3229,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
&& (!mSecureCameraLaunched || mAlternateBouncerShowing)
|
&& (!mSecureCameraLaunched || mAlternateBouncerShowing)
|
||||||
&& faceAndFpNotAuthenticated
|
&& faceAndFpNotAuthenticated
|
||||||
&& !mGoingToSleep
|
&& !mGoingToSleep
|
||||||
&& isPostureAllowedForFaceAuth;
|
&& isPostureAllowedForFaceAuth
|
||||||
|
&& mAllowedDisplayStateForFaceAuth;
|
||||||
|
|
||||||
// Aggregate relevant fields for debug logging.
|
// Aggregate relevant fields for debug logging.
|
||||||
logListenerModelData(
|
logListenerModelData(
|
||||||
@@ -3207,6 +3238,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
user,
|
user,
|
||||||
shouldListen,
|
shouldListen,
|
||||||
|
mAllowedDisplayStateForFaceAuth,
|
||||||
mAlternateBouncerShowing,
|
mAlternateBouncerShowing,
|
||||||
mAuthInterruptActive,
|
mAuthInterruptActive,
|
||||||
biometricEnabledForUser,
|
biometricEnabledForUser,
|
||||||
@@ -4400,6 +4432,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|
|
||||||
mLockPatternUtils.unregisterStrongAuthTracker(mStrongAuthTracker);
|
mLockPatternUtils.unregisterStrongAuthTracker(mStrongAuthTracker);
|
||||||
mTrustManager.unregisterTrustListener(this);
|
mTrustManager.unregisterTrustListener(this);
|
||||||
|
mDisplayTracker.removeCallback(mDisplayCallback);
|
||||||
|
|
||||||
mHandler.removeCallbacksAndMessages(null);
|
mHandler.removeCallbacksAndMessages(null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,6 +293,11 @@ object Flags {
|
|||||||
"wallpaper_picker_preview_animation"
|
"wallpaper_picker_preview_animation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** 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
|
// 300 - power menu
|
||||||
// TODO(b/254512600): Tracking Bug
|
// TODO(b/254512600): Tracking Bug
|
||||||
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
|
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ interface DisplayTracker {
|
|||||||
/** Remove a [Callback] previously added. */
|
/** Remove a [Callback] previously added. */
|
||||||
fun removeCallback(callback: Callback)
|
fun removeCallback(callback: Callback)
|
||||||
|
|
||||||
|
/** Gets the Display with the given displayId */
|
||||||
|
fun getDisplay(displayId: Int): Display
|
||||||
|
|
||||||
/** Ćallback for notifying of changes. */
|
/** Ćallback for notifying of changes. */
|
||||||
interface Callback {
|
interface Callback {
|
||||||
|
|
||||||
|
|||||||
@@ -115,6 +115,10 @@ internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getDisplay(displayId: Int): Display {
|
||||||
|
return displayManager.getDisplay(displayId)
|
||||||
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private fun onDisplayAdded(displayId: Int, list: List<DisplayTrackerDataItem>) {
|
private fun onDisplayAdded(displayId: Int, list: List<DisplayTrackerDataItem>) {
|
||||||
Assert.isNotMainThread()
|
Assert.isNotMainThread()
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_T
|
|||||||
import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
|
import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
|
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
|
||||||
import static com.android.systemui.flags.Flags.FP_LISTEN_OCCLUDING_APPS;
|
import static com.android.systemui.flags.Flags.FP_LISTEN_OCCLUDING_APPS;
|
||||||
|
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_CLOSED;
|
||||||
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED;
|
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED;
|
||||||
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
|
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
|
||||||
@@ -89,6 +90,7 @@ import android.hardware.biometrics.BiometricManager;
|
|||||||
import android.hardware.biometrics.BiometricSourceType;
|
import android.hardware.biometrics.BiometricSourceType;
|
||||||
import android.hardware.biometrics.ComponentInfoInternal;
|
import android.hardware.biometrics.ComponentInfoInternal;
|
||||||
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
|
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
|
||||||
|
import android.hardware.display.DisplayManagerGlobal;
|
||||||
import android.hardware.face.FaceAuthenticateOptions;
|
import android.hardware.face.FaceAuthenticateOptions;
|
||||||
import android.hardware.face.FaceManager;
|
import android.hardware.face.FaceManager;
|
||||||
import android.hardware.face.FaceSensorProperties;
|
import android.hardware.face.FaceSensorProperties;
|
||||||
@@ -121,6 +123,9 @@ import android.test.suitebuilder.annotation.SmallTest;
|
|||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.DisplayAdjustments;
|
||||||
|
import android.view.DisplayInfo;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
@@ -143,6 +148,7 @@ import com.android.systemui.dump.DumpManager;
|
|||||||
import com.android.systemui.flags.FakeFeatureFlags;
|
import com.android.systemui.flags.FakeFeatureFlags;
|
||||||
import com.android.systemui.log.SessionTracker;
|
import com.android.systemui.log.SessionTracker;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
|
import com.android.systemui.settings.FakeDisplayTracker;
|
||||||
import com.android.systemui.settings.UserTracker;
|
import com.android.systemui.settings.UserTracker;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListeners;
|
import com.android.systemui.shared.system.TaskStackChangeListeners;
|
||||||
@@ -304,10 +310,12 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mFingerprintAuthenticatorsRegisteredCallback;
|
mFingerprintAuthenticatorsRegisteredCallback;
|
||||||
private IFaceAuthenticatorsRegisteredCallback mFaceAuthenticatorsRegisteredCallback;
|
private IFaceAuthenticatorsRegisteredCallback mFaceAuthenticatorsRegisteredCallback;
|
||||||
private final InstanceId mKeyguardInstanceId = InstanceId.fakeInstanceId(999);
|
private final InstanceId mKeyguardInstanceId = InstanceId.fakeInstanceId(999);
|
||||||
|
private FakeDisplayTracker mDisplayTracker;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws RemoteException {
|
public void setup() throws RemoteException {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mDisplayTracker = new FakeDisplayTracker(mContext);
|
||||||
when(mSessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(mKeyguardInstanceId);
|
when(mSessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(mKeyguardInstanceId);
|
||||||
|
|
||||||
when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true);
|
when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true);
|
||||||
@@ -348,6 +356,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
allowTestableLooperAsMainThread();
|
allowTestableLooperAsMainThread();
|
||||||
mFeatureFlags = new FakeFeatureFlags();
|
mFeatureFlags = new FakeFeatureFlags();
|
||||||
mFeatureFlags.set(FP_LISTEN_OCCLUDING_APPS, false);
|
mFeatureFlags.set(FP_LISTEN_OCCLUDING_APPS, false);
|
||||||
|
mFeatureFlags.set(STOP_FACE_AUTH_ON_DISPLAY_OFF, false);
|
||||||
|
|
||||||
when(mSecureSettings.getUriFor(anyString())).thenReturn(mURI);
|
when(mSecureSettings.getUriFor(anyString())).thenReturn(mURI);
|
||||||
|
|
||||||
@@ -358,6 +367,11 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
anyInt());
|
anyInt());
|
||||||
|
|
||||||
mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mContext);
|
mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mContext);
|
||||||
|
setupBiometrics(mKeyguardUpdateMonitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupBiometrics(KeyguardUpdateMonitor keyguardUpdateMonitor)
|
||||||
|
throws RemoteException {
|
||||||
captureAuthenticatorsRegisteredCallbacks();
|
captureAuthenticatorsRegisteredCallbacks();
|
||||||
setupFaceAuth(/* isClass3 */ false);
|
setupFaceAuth(/* isClass3 */ false);
|
||||||
setupFingerprintAuth(/* isClass3 */ true);
|
setupFingerprintAuth(/* isClass3 */ true);
|
||||||
@@ -367,9 +381,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mBiometricEnabledOnKeyguardCallback = mBiometricEnabledCallbackArgCaptor.getValue();
|
mBiometricEnabledOnKeyguardCallback = mBiometricEnabledCallbackArgCaptor.getValue();
|
||||||
biometricsEnabledForCurrentUser();
|
biometricsEnabledForCurrentUser();
|
||||||
|
|
||||||
mHandler = spy(mKeyguardUpdateMonitor.getHandler());
|
mHandler = spy(keyguardUpdateMonitor.getHandler());
|
||||||
try {
|
try {
|
||||||
FieldSetter.setField(mKeyguardUpdateMonitor,
|
FieldSetter.setField(keyguardUpdateMonitor,
|
||||||
KeyguardUpdateMonitor.class.getDeclaredField("mHandler"), mHandler);
|
KeyguardUpdateMonitor.class.getDeclaredField("mHandler"), mHandler);
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
|
|
||||||
@@ -3029,6 +3043,79 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
verify(callback).onBiometricEnrollmentStateChanged(BiometricSourceType.FACE);
|
verify(callback).onBiometricEnrollmentStateChanged(BiometricSourceType.FACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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() {
|
private void verifyFingerprintAuthenticateNeverCalled() {
|
||||||
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
|
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
|
||||||
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||||
@@ -3297,6 +3384,18 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mTestableLooper.processAllMessages();
|
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) {
|
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
|
||||||
int subscription = simInited
|
int subscription = simInited
|
||||||
? 1/* mock subid=1 */ : SubscriptionManager.PLACEHOLDER_SUBSCRIPTION_ID_BASE;
|
? 1/* mock subid=1 */ : SubscriptionManager.PLACEHOLDER_SUBSCRIPTION_ID_BASE;
|
||||||
@@ -3374,7 +3473,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
|
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
|
||||||
mFaceWakeUpTriggersConfig, mDevicePostureController,
|
mFaceWakeUpTriggersConfig, mDevicePostureController,
|
||||||
Optional.of(mInteractiveToAuthProvider), mFeatureFlags,
|
Optional.of(mInteractiveToAuthProvider), mFeatureFlags,
|
||||||
mTaskStackChangeListeners, mActivityTaskManager);
|
mTaskStackChangeListeners, mActivityTaskManager, mDisplayTracker);
|
||||||
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
|
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class FakeDisplayTracker constructor(val context: Context) : DisplayTracker {
|
|||||||
override var defaultDisplayId: Int = Display.DEFAULT_DISPLAY
|
override var defaultDisplayId: Int = Display.DEFAULT_DISPLAY
|
||||||
override var allDisplays: Array<Display> = displayManager.displays
|
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()
|
private val brightnessCallbacks: MutableList<DisplayTracker.Callback> = ArrayList()
|
||||||
override fun addDisplayChangeCallback(callback: DisplayTracker.Callback, executor: Executor) {
|
override fun addDisplayChangeCallback(callback: DisplayTracker.Callback, executor: Executor) {
|
||||||
displayCallbacks.add(callback)
|
displayCallbacks.add(callback)
|
||||||
@@ -43,12 +43,12 @@ class FakeDisplayTracker constructor(val context: Context) : DisplayTracker {
|
|||||||
brightnessCallbacks.remove(callback)
|
brightnessCallbacks.remove(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDefaultDisplay(displayId: Int) {
|
override fun getDisplay(displayId: Int): Display {
|
||||||
defaultDisplayId = displayId
|
return allDisplays.filter { display -> display.displayId == displayId }[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDisplays(displays: Array<Display>) {
|
fun setDefaultDisplay(displayId: Int) {
|
||||||
allDisplays = displays
|
defaultDisplayId = displayId
|
||||||
}
|
}
|
||||||
|
|
||||||
fun triggerOnDisplayAdded(displayId: Int) {
|
fun triggerOnDisplayAdded(displayId: Int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user