From 408d0a2a53b1f70d26f1fb43063bf1350978930f Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 2 Aug 2021 14:57:29 -0400 Subject: On devices with udfps supported, show auth ripple Show the auth ripple if the user enters the device via the unlock icon (where the udfps icon would normally be). Test: manual Fixes: 195162787 Change-Id: Ie65dce30c009f94a0472f566c3663a0de2bc063b --- .../src/com/android/keyguard/LockIconViewController.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'packages/SystemUI/src/com/android/keyguard/LockIconViewController.java') diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 509ac8a6d9fe..aa8cbd710e90 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -46,6 +46,7 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.biometrics.UdfpsController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; @@ -99,6 +100,7 @@ public class LockIconViewController extends ViewController impleme @NonNull private CharSequence mUnlockedLabel; @NonNull private CharSequence mLockedLabel; @Nullable private final Vibrator mVibrator; + @Nullable private final AuthRippleController mAuthRippleController; private boolean mIsDozing; private boolean mIsBouncerShowing; @@ -135,7 +137,8 @@ public class LockIconViewController extends ViewController impleme @NonNull AccessibilityManager accessibilityManager, @NonNull ConfigurationController configurationController, @NonNull @Main DelayableExecutor executor, - @Nullable Vibrator vibrator + @Nullable Vibrator vibrator, + @Nullable AuthRippleController authRippleController ) { super(view); mStatusBarStateController = statusBarStateController; @@ -148,6 +151,7 @@ public class LockIconViewController extends ViewController impleme mConfigurationController = configurationController; mExecutor = executor; mVibrator = vibrator; + mAuthRippleController = authRippleController; final Context context = view.getContext(); mUnlockIcon = mView.getContext().getResources().getDrawable( @@ -538,6 +542,9 @@ public class LockIconViewController extends ViewController impleme // pre-emptively set to true to hide view mIsBouncerShowing = true; + if (mUdfpsSupported && mShowUnlockIcon && mAuthRippleController != null) { + mAuthRippleController.showRipple(FINGERPRINT); + } updateVisibility(); mKeyguardViewController.showBouncer(/* scrim */ true); } -- cgit v1.2.3 From 199da10111ae543dd3ed6f7a098cbc458d1e39c5 Mon Sep 17 00:00:00 2001 From: Beverly Date: Thu, 19 Aug 2021 16:08:40 -0400 Subject: Update lock icon location if auth setup is delayed + Update javadoc Test: atest LockIconViewControllerTest Fixes: 196751321 Change-Id: I003bec46b26a2c8ac8bae6d1d26c91645c4ae72f --- .../com/android/keyguard/LockIconViewController.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'packages/SystemUI/src/com/android/keyguard/LockIconViewController.java') diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index aa8cbd710e90..47f0714af164 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -68,7 +68,8 @@ import javax.inject.Inject; /** * Controls when to show the LockIcon affordance (lock/unlocked icon or circle) on lock screen. * - * This view will only be shown if the user has UDFPS or FaceAuth enrolled + * For devices with UDFPS, the lock icon will show at the sensor location. Else, the lock + * icon will show a set distance from the bottom of the device. */ @StatusBarComponent.StatusBarScope public class LockIconViewController extends ViewController implements Dumpable { @@ -172,15 +173,14 @@ public class LockIconViewController extends ViewController impleme @Override protected void onInit() { + mAuthController.addCallback(mAuthControllerCallback); + mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; + mView.setAccessibilityDelegate(mAccessibilityDelegate); } @Override protected void onViewAttached() { - // we check this here instead of onInit since the FingerprintManager + FaceManager may not - // have started up yet onInit - mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; - updateConfiguration(); updateKeyguardShowing(); mUserUnlockedWithBiometric = false; @@ -584,4 +584,12 @@ public class LockIconViewController extends ViewController impleme public void setAlpha(float alpha) { mView.setAlpha(alpha); } + + private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() { + @Override + public void onAllAuthenticatorsRegistered() { + mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; + updateConfiguration(); + } + }; } -- cgit v1.2.3 From 374f321fca4572401911f1493122600140e918eb Mon Sep 17 00:00:00 2001 From: Beverly Date: Thu, 26 Aug 2021 12:19:57 -0400 Subject: Remove ZigZagClassifer from lock-icon longpress falsing algo If the touch leaves the lock icon area, we already drop the touch. Therefore, we don't also need to also take into consideration the ZigZagClassifier for the lock icon. Also, only play the longpress vibration if we will be bringing up the bouncer. If the FalsingManager think we're falsing, there's no reason to play the longpress vibration. Test: manually longpress lock icon on device with udfps capability (after lockdown or reboot) and observe longpress consistently brings up the bouncer Fixes: 197271526 Change-Id: Ic9fa82a549599e48d281b4db69c04627803c6c5a --- .../src/com/android/keyguard/LockIconViewController.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'packages/SystemUI/src/com/android/keyguard/LockIconViewController.java') diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 47f0714af164..2a4022ca57b6 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -501,8 +501,10 @@ public class LockIconViewController extends ViewController impleme if (!wasClickableOnDownEvent()) { return; } + mDetectedLongPress = true; - if (mVibrator != null) { + if (onAffordanceClick() && mVibrator != null) { + // only vibrate if the click went through and wasn't intercepted by falsing mVibrator.vibrate( Process.myUid(), getContext().getOpPackageName(), @@ -510,8 +512,6 @@ public class LockIconViewController extends ViewController impleme "lockIcon-onLongPress", VIBRATION_SONIFICATION_ATTRIBUTES); } - mDetectedLongPress = true; - onAffordanceClick(); } public boolean onSingleTapUp(MotionEvent e) { @@ -535,9 +535,14 @@ public class LockIconViewController extends ViewController impleme return mDownDetected; } - private void onAffordanceClick() { + /** + * Whether we tried to launch the affordance. + * + * If falsing intercepts the click, returns false. + */ + private boolean onAffordanceClick() { if (mFalsingManager.isFalseTouch(LOCK_ICON)) { - return; + return false; } // pre-emptively set to true to hide view @@ -547,6 +552,7 @@ public class LockIconViewController extends ViewController impleme } updateVisibility(); mKeyguardViewController.showBouncer(/* scrim */ true); + return true; } }); -- cgit v1.2.3 From e5be111dc4740db3fa624c2620fee09a40193974 Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 13 Sep 2021 17:25:00 -0400 Subject: [DO NOT MERGE] Show UDFPS icon on AOD even if fp auth isn't running * shows udfps if it's enrolled on AOD even if: * device requires strong auth (ie: after reboot, lockdown) * device is unlocked via smart lock On click of the udfps icon in the above cases: * If the device is locked, the bouncer will show. * If the device is unlocked, the user will enter the device. Fixes: 198315404 Test: manual Change-Id: Id766df8f77427ae1db672507716bd38dc3462452 --- .../android/keyguard/LockIconViewController.java | 106 ++++++++++++++++++--- 1 file changed, 95 insertions(+), 11 deletions(-) (limited to 'packages/SystemUI/src/com/android/keyguard/LockIconViewController.java') diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 2a4022ca57b6..aa79504ae7ca 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -19,6 +19,8 @@ package com.android.keyguard; import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT; import static com.android.systemui.classifier.Classifier.LOCK_ICON; +import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; +import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset; import android.content.Context; import android.content.res.Configuration; @@ -32,6 +34,7 @@ import android.media.AudioAttributes; import android.os.Process; import android.os.Vibrator; import android.util.DisplayMetrics; +import android.util.MathUtils; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; @@ -59,6 +62,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.ViewController; import com.android.systemui.util.concurrency.DelayableExecutor; +import com.airbnb.lottie.LottieAnimationView; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Objects; @@ -94,6 +99,8 @@ public class LockIconViewController extends ViewController impleme @NonNull private final DelayableExecutor mExecutor; private boolean mUdfpsEnrolled; + @NonNull private LottieAnimationView mAodFp; + @NonNull private final AnimatedVectorDrawable mFpToUnlockIcon; @NonNull private final AnimatedVectorDrawable mLockToUnlockIcon; @NonNull private final Drawable mLockIcon; @@ -112,6 +119,7 @@ public class LockIconViewController extends ViewController impleme private boolean mIsKeyguardShowing; private boolean mUserUnlockedWithBiometric; private Runnable mCancelDelayedUpdateVisibilityRunnable; + private Runnable mOnGestureDetectedRunnable; private boolean mUdfpsSupported; private float mHeightPixels; @@ -121,6 +129,12 @@ public class LockIconViewController extends ViewController impleme private boolean mShowUnlockIcon; private boolean mShowLockIcon; + // for udfps when strong auth is required or unlocked on AOD + private boolean mShowAODFpIcon; + private final int mMaxBurnInOffsetX; + private final int mMaxBurnInOffsetY; + private float mInterpolatedDarkAmount; + private boolean mDownDetected; private boolean mDetectedLongPress; private final Rect mSensorTouchLocation = new Rect(); @@ -155,6 +169,12 @@ public class LockIconViewController extends ViewController impleme mAuthRippleController = authRippleController; final Context context = view.getContext(); + mAodFp = mView.findViewById(R.id.lock_udfps_aod_fp); + mMaxBurnInOffsetX = context.getResources() + .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x); + mMaxBurnInOffsetY = context.getResources() + .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); + mUnlockIcon = mView.getContext().getResources().getDrawable( R.drawable.ic_unlock, mView.getContext().getTheme()); @@ -173,19 +193,19 @@ public class LockIconViewController extends ViewController impleme @Override protected void onInit() { - mAuthController.addCallback(mAuthControllerCallback); - mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; - mView.setAccessibilityDelegate(mAccessibilityDelegate); } @Override protected void onViewAttached() { + updateIsUdfpsEnrolled(); updateConfiguration(); updateKeyguardShowing(); mUserUnlockedWithBiometric = false; + mIsBouncerShowing = mKeyguardViewController.isBouncerShowing(); mIsDozing = mStatusBarStateController.isDozing(); + mInterpolatedDarkAmount = mStatusBarStateController.getDozeAmount(); mRunningFPS = mKeyguardUpdateMonitor.isFingerprintDetectionRunning(); mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen(); mStatusBarState = mStatusBarStateController.getState(); @@ -193,15 +213,18 @@ public class LockIconViewController extends ViewController impleme updateColors(); mConfigurationController.addCallback(mConfigurationListener); + mAuthController.addCallback(mAuthControllerCallback); mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); mStatusBarStateController.addCallback(mStatusBarStateListener); mKeyguardStateController.addCallback(mKeyguardStateCallback); mDownDetected = false; + updateBurnInOffsets(); updateVisibility(); } @Override protected void onViewDetached() { + mAuthController.removeCallback(mAuthControllerCallback); mConfigurationController.removeCallback(mConfigurationListener); mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback); mStatusBarStateController.removeCallback(mStatusBarStateListener); @@ -231,7 +254,7 @@ public class LockIconViewController extends ViewController impleme mCancelDelayedUpdateVisibilityRunnable = null; } - if (!mIsKeyguardShowing) { + if (!mIsKeyguardShowing && !mIsDozing) { mView.setVisibility(View.INVISIBLE); return; } @@ -242,6 +265,7 @@ public class LockIconViewController extends ViewController impleme mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen() && (!mUdfpsEnrolled || !mRunningFPS); mShowUnlockIcon = mCanDismissLockScreen && isLockScreen(); + mShowAODFpIcon = mIsDozing && mUdfpsEnrolled && !mRunningFPS; final CharSequence prevContentDescription = mView.getContentDescription(); if (mShowLockIcon) { @@ -264,10 +288,22 @@ public class LockIconViewController extends ViewController impleme } mView.setVisibility(View.VISIBLE); mView.setContentDescription(mUnlockedLabel); + } else if (mShowAODFpIcon) { + mView.setImageDrawable(null); + mView.setContentDescription(null); + mAodFp.setVisibility(View.VISIBLE); + mAodFp.setContentDescription(mCanDismissLockScreen ? mUnlockedLabel : mLockedLabel); + mView.setVisibility(View.VISIBLE); } else { mView.setVisibility(View.INVISIBLE); mView.setContentDescription(null); } + + if (!mShowAODFpIcon) { + mAodFp.setVisibility(View.INVISIBLE); + mAodFp.setContentDescription(null); + } + if (!Objects.equals(prevContentDescription, mView.getContentDescription()) && mView.getContentDescription() != null) { mView.announceForAccessibility(mView.getContentDescription()); @@ -344,10 +380,12 @@ public class LockIconViewController extends ViewController impleme @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { + pw.println("mUdfpsSupported: " + mUdfpsSupported); pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled); pw.println("mIsKeyguardShowing: " + mIsKeyguardShowing); pw.println(" mShowUnlockIcon: " + mShowUnlockIcon); pw.println(" mShowLockIcon: " + mShowLockIcon); + pw.println(" mShowAODFpIcon: " + mShowAODFpIcon); pw.println(" mIsDozing: " + mIsDozing); pw.println(" mIsBouncerShowing: " + mIsBouncerShowing); pw.println(" mUserUnlockedWithBiometric: " + mUserUnlockedWithBiometric); @@ -355,17 +393,57 @@ public class LockIconViewController extends ViewController impleme pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen); pw.println(" mStatusBarState: " + StatusBarState.toShortString(mStatusBarState)); pw.println(" mQsExpanded: " + mQsExpanded); + pw.println(" mInterpolatedDarkAmount: " + mInterpolatedDarkAmount); if (mView != null) { mView.dump(fd, pw, args); } } + /** Every minute, update the aod icon's burn in offset */ + public void dozeTimeTick() { + updateBurnInOffsets(); + } + + private void updateBurnInOffsets() { + float offsetX = MathUtils.lerp(0f, + getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */) + - mMaxBurnInOffsetX, mInterpolatedDarkAmount); + float offsetY = MathUtils.lerp(0f, + getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */) + - mMaxBurnInOffsetY, mInterpolatedDarkAmount); + float progress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount); + + mAodFp.setTranslationX(offsetX); + mAodFp.setTranslationY(offsetY); + mAodFp.setProgress(progress); + mAodFp.setAlpha(255 * mInterpolatedDarkAmount); + } + + private void updateIsUdfpsEnrolled() { + boolean wasUdfpsSupported = mUdfpsSupported; + boolean wasUdfpsEnrolled = mUdfpsEnrolled; + + mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; + mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled(); + if (wasUdfpsSupported != mUdfpsSupported || wasUdfpsEnrolled != mUdfpsEnrolled) { + updateVisibility(); + } + } + private StatusBarStateController.StateListener mStatusBarStateListener = new StatusBarStateController.StateListener() { + @Override + public void onDozeAmountChanged(float linear, float eased) { + mInterpolatedDarkAmount = eased; + updateBurnInOffsets(); + } + @Override public void onDozingChanged(boolean isDozing) { mIsDozing = isDozing; + updateBurnInOffsets(); + updateIsUdfpsEnrolled(); updateVisibility(); } @@ -439,7 +517,7 @@ public class LockIconViewController extends ViewController impleme mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( KeyguardUpdateMonitor.getCurrentUser()); } - mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled(); + updateIsUdfpsEnrolled(); updateVisibility(); } @@ -485,8 +563,7 @@ public class LockIconViewController extends ViewController impleme // intercept all following touches until we see MotionEvent.ACTION_CANCEL UP or // MotionEvent.ACTION_UP (see #onTouchEvent) - mDownDetected = true; - if (mVibrator != null) { + if (mVibrator != null && !mDownDetected) { mVibrator.vibrate( Process.myUid(), getContext().getOpPackageName(), @@ -494,6 +571,8 @@ public class LockIconViewController extends ViewController impleme "lockIcon-onDown", VIBRATION_SONIFICATION_ATTRIBUTES); } + + mDownDetected = true; return true; } @@ -551,6 +630,9 @@ public class LockIconViewController extends ViewController impleme mAuthRippleController.showRipple(FINGERPRINT); } updateVisibility(); + if (mOnGestureDetectedRunnable != null) { + mOnGestureDetectedRunnable.run(); + } mKeyguardViewController.showBouncer(/* scrim */ true); return true; } @@ -561,16 +643,18 @@ public class LockIconViewController extends ViewController impleme * in a 'clickable' state * @return whether to intercept the touch event */ - public boolean onTouchEvent(MotionEvent event) { + public boolean onTouchEvent(MotionEvent event, Runnable onGestureDetectedRunnable) { if (mSensorTouchLocation.contains((int) event.getX(), (int) event.getY()) - && mView.getVisibility() == View.VISIBLE) { + && (mView.getVisibility() == View.VISIBLE + || mAodFp.getVisibility() == View.VISIBLE)) { + mOnGestureDetectedRunnable = onGestureDetectedRunnable; mGestureDetector.onTouchEvent(event); } // we continue to intercept all following touches until we see MotionEvent.ACTION_CANCEL UP // or MotionEvent.ACTION_UP. this is to avoid passing the touch to NPV // after the lock icon disappears on device entry - if (mDownDetected && mDetectedLongPress) { + if (mDownDetected) { if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) { mDownDetected = false; @@ -594,7 +678,7 @@ public class LockIconViewController extends ViewController impleme private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() { @Override public void onAllAuthenticatorsRegistered() { - mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; + updateIsUdfpsEnrolled(); updateConfiguration(); } }; -- cgit v1.2.3 From ddfb4df1a83d6e51e23177790f0b0ecae207f764 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Thu, 23 Sep 2021 10:18:41 -0400 Subject: [DO NOT MERGE] Only show lock icon background with UDFPS Otherwise the background should remain hidden (View.GONE) for devices without the UDFPS sensor. Fixes: 200813382 Test: atest LockIconViewControllerTest Change-Id: I1ef3cef37de60e6968432869f4c946b6de414db4 --- .../SystemUI/src/com/android/keyguard/LockIconViewController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages/SystemUI/src/com/android/keyguard/LockIconViewController.java') diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index aa79504ae7ca..52ebf2fa09d0 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -345,7 +345,7 @@ public class LockIconViewController extends ViewController impleme } private void updateColors() { - mView.updateColorAndBackgroundVisibility(mUdfpsSupported); + mView.updateColorAndBackgroundVisibility(); } private void updateConfiguration() { @@ -425,6 +425,8 @@ public class LockIconViewController extends ViewController impleme boolean wasUdfpsEnrolled = mUdfpsEnrolled; mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; + mView.setUseBackground(mUdfpsSupported); + mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled(); if (wasUdfpsSupported != mUdfpsSupported || wasUdfpsEnrolled != mUdfpsEnrolled) { updateVisibility(); -- cgit v1.2.3