From eb5fe1d31c4d0b17b39206b38e28e054a0ed5dc6 Mon Sep 17 00:00:00 2001 From: Beverly Date: Thu, 15 Apr 2021 13:57:03 -0400 Subject: [PATCH] If enrolled show udfps bouncer on camera roll auth - Add PowerManager.userActivity when user uses udfps to authenticate so the screen won't turn off prematurely - When the udfps-bouncer is showing, tapping outside the udfps view will show the regular pin/pattern/password bouncer Fixes: 184927116 Fixes: 182500156 Test: atest SystemUITests Test: manual 1. enroll udfps 2. go to locked lock screen 3. double tap power button to bring up camera 4. tap on camera gallery (lock icon on image, bottom right) Observe: udfps is highlighted; tapping outside udfps area brings up regular bouncer Change-Id: If01ee16647499fc2cf73afe527053cd6830a50ed --- .../keyguard/KeyguardUpdateMonitor.java | 51 +++++++----- .../UdfpsAnimationViewController.java | 12 +++ .../systemui/biometrics/UdfpsController.java | 28 +++++-- .../UdfpsKeyguardViewController.java | 81 +++++++++++++------ .../systemui/biometrics/UdfpsView.java | 4 + .../phone/BiometricUnlockController.java | 1 + .../NotificationPanelViewController.java | 8 +- .../phone/StatusBarKeyguardViewManager.java | 17 +++- .../keyguard/KeyguardUpdateMonitorTest.java | 12 +-- .../biometrics/UdfpsControllerTest.java | 5 +- .../UdfpsKeyguardViewControllerTest.java | 28 +++++-- 11 files changed, 171 insertions(+), 76 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 138dd15b33b75..68a4194e113db 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -2009,9 +2009,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab // TODO: Add support for multiple fingerprint sensors, b/173730729 updateUdfpsEnrolled(getCurrentUser()); - boolean shouldListenForFingerprint = - isUdfpsEnrolled() ? shouldListenForUdfps() : shouldListenForFingerprint(); - boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING + final boolean shouldListenForFingerprint = shouldListenForFingerprint(isUdfpsEnrolled()); + final boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING; if (runningOrRestarting && !shouldListenForFingerprint) { stopListeningForFingerprint(); @@ -2092,28 +2091,36 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab && !mUserHasTrust.get(getCurrentUser(), false); } - private boolean shouldListenForFingerprint() { - final boolean allowedOnBouncer = - !(mFingerprintLockedOut && mBouncer && mCredentialAttempted); + @VisibleForTesting + protected boolean shouldListenForFingerprint(boolean isUdfps) { + final boolean shouldListenKeyguardState = + mKeyguardIsVisible + || !mDeviceInteractive + || (mBouncer && !mKeyguardGoingAway) + || mGoingToSleep + || shouldListenForFingerprintAssistant() + || (mKeyguardOccluded && mIsDreaming) + || (isUdfps && mKeyguardOccluded); // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware. - final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive || - (mBouncer && !mKeyguardGoingAway) || mGoingToSleep || - shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming)) - && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser()) - && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser - && allowedOnBouncer && mBiometricEnabledForUser.get(getCurrentUser()); - return shouldListen; - } + final boolean shouldListenUserState = + !mSwitchingUser + && !isFingerprintDisabled(getCurrentUser()) + && (!mKeyguardGoingAway || !mDeviceInteractive) + && mIsPrimaryUser + && mBiometricEnabledForUser.get(getCurrentUser()); - @VisibleForTesting - boolean shouldListenForUdfps() { - return shouldListenForFingerprint() - && !mBouncer - && !getUserCanSkipBouncer(getCurrentUser()) + final boolean shouldListenBouncerState = + isUdfps ? !mBouncer + : !(mFingerprintLockedOut && mBouncer && mCredentialAttempted); + + final boolean shouldListenUdfpsState = !isUdfps + || (!getUserCanSkipBouncer(getCurrentUser()) && !isEncryptedOrLockdown(getCurrentUser()) - && mStrongAuthTracker.hasUserAuthenticatedSinceBoot(); + && mStrongAuthTracker.hasUserAuthenticatedSinceBoot()); + return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState + && shouldListenUdfpsState; } /** @@ -3235,13 +3242,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId)); pw.println(" possible=" + isUnlockWithFingerprintPossible(userId)); pw.println(" listening: actual=" + mFingerprintRunningState - + " expected=" + (shouldListenForFingerprint() ? 1 : 0)); + + " expected=" + (shouldListenForFingerprint(false) ? 1 : 0)); pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags)); pw.println(" trustManaged=" + getUserTrustIsManaged(userId)); pw.println(" udfpsEnrolled=" + isUdfpsEnrolled()); pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId)); if (isUdfpsEnrolled()) { - pw.println(" shouldListenForUdfps=" + shouldListenForUdfps()); + pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true)); pw.println(" bouncerVisible=" + mBouncer); pw.println(" mStatusBarState=" + StatusBarState.toShortString(mStatusBarState)); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java index d9e1b501e1e11..195d006066933 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java @@ -165,6 +165,18 @@ abstract class UdfpsAnimationViewController mView.postInvalidate(); } + /** + * Whether to listen for touches outside of the view. + */ + boolean listenForTouchesOutsideView() { + return false; + } + + /** + * Called on touches outside of the view if listenForTouchesOutsideView returns true + */ + void onTouchOutsideView() { } + private final StatusBar.ExpansionChangedListener mStatusBarExpansionChangedListener = new StatusBar.ExpansionChangedListener() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 9239a8ade6155..47c4a63b4a8c1 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -39,6 +39,7 @@ import android.hardware.fingerprint.IUdfpsOverlayControllerCallback; import android.media.AudioAttributes; import android.os.Handler; import android.os.Looper; +import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; @@ -106,6 +107,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @NonNull private final Vibrator mVibrator; @NonNull private final Handler mMainHandler; @NonNull private final FalsingManager mFalsingManager; + @NonNull private final PowerManager mPowerManager; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // sensors, this, in addition to a lot of the code here, will be updated. @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps; @@ -266,6 +268,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback { final boolean isFingerDown = udfpsView.isIlluminationRequested(); boolean handled = false; switch (event.getActionMasked()) { + case MotionEvent.ACTION_OUTSIDE: + udfpsView.onTouchOutsideView(); + break; case MotionEvent.ACTION_DOWN: // To simplify the lifecycle of the velocity tracker, make sure it's never null // after ACTION_DOWN, and always null after ACTION_CANCEL or ACTION_UP. @@ -332,6 +337,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback { onFingerDown((int) x, (int) y, minor, major); Log.v(TAG, "onTouch | finger down: " + touchInfo); mTouchLogTime = SystemClock.elapsedRealtime(); + mPowerManager.userActivity(SystemClock.uptimeMillis(), + PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); handled = true; } else if (sinceLastLog >= MIN_TOUCH_LOG_INTERVAL) { Log.v(TAG, "onTouch | finger move: " + touchInfo); @@ -377,7 +384,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @NonNull DumpManager dumpManager, @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor, @NonNull KeyguardViewMediator keyguardViewMediator, - @NonNull FalsingManager falsingManager) { + @NonNull FalsingManager falsingManager, + @NonNull PowerManager powerManager) { mContext = context; // TODO (b/185124905): inject main handler and vibrator once done prototyping mMainHandler = new Handler(Looper.getMainLooper()); @@ -395,6 +403,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardViewMediator = keyguardViewMediator; mFalsingManager = falsingManager; + mPowerManager = powerManager; mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists @@ -403,10 +412,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { mCoreLayoutParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, + getCoreLayoutParamFlags(), PixelFormat.TRANSLUCENT); mCoreLayoutParams.setTitle(TAG); mCoreLayoutParams.setFitInsetsTypes(0); @@ -422,6 +428,13 @@ public class UdfpsController implements DozeReceiver, HbmCallback { context.registerReceiver(mBroadcastReceiver, filter); } + private int getCoreLayoutParamFlags() { + return WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; + } + @Nullable private FingerprintSensorPropertiesInternal findFirstUdfps() { for (FingerprintSensorPropertiesInternal props : @@ -467,6 +480,11 @@ public class UdfpsController implements DozeReceiver, HbmCallback { final int paddingX = animation != null ? animation.getPaddingX() : 0; final int paddingY = animation != null ? animation.getPaddingY() : 0; + mCoreLayoutParams.flags = getCoreLayoutParamFlags(); + if (animation.listenForTouchesOutsideView()) { + mCoreLayoutParams.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; + } + // Default dimensions assume portrait mode. mCoreLayoutParams.x = mSensorProps.sensorLocationX - mSensorProps.sensorRadius - paddingX; mCoreLayoutParams.y = mSensorProps.sensorLocationY - mSensorProps.sensorRadius - paddingY; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java index 35678e6773d5e..63af6aac30b3e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java @@ -52,12 +52,13 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController