summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2021-04-07 19:58:19 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-04-07 19:58:19 +0000
commit9a5967ffefd540e7c69b587e7d925d16a237f1e1 (patch)
treed6dff5fac6630bf413fd9982fb03101b9ad0aecd
parentdcc1a906cf98dc008073b73f95a849dc223ba02c (diff)
parent1951b0b366f20ae86a0fee2e4eade8a34a3572a2 (diff)
Merge changes from topics "face_auth_ripple", "udfps_falsing" into sc-dev
* changes: Add falsing checks to udfps affordance Support face auth ripple animation
-rw-r--r--packages/SystemUI/res/layout/super_notification_shade.xml8
-rw-r--r--packages/SystemUI/res/values/config.xml7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt165
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/Classifier.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt88
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java2
22 files changed, 386 insertions, 150 deletions
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index 1630244468e5..e46c6701684f 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -100,4 +100,12 @@
android:ellipsize="marquee"
android:focusable="true" />
</LinearLayout>
+
+ <com.android.systemui.biometrics.AuthRippleView
+ android:id="@+id/auth_ripple"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:importantForAccessibility="no"
+ sysui:ignoreRightInset="true"
+ />
</com.android.systemui.statusbar.phone.NotificationShadeWindowView>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index bd92299f38cf..0125144581aa 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -642,4 +642,11 @@
<!-- Whether to use window background blur for the volume dialog. -->
<bool name="config_volumeDialogUseBackgroundBlur">false</bool>
+
+ <!-- The properties of the face auth camera in pixels -->
+ <integer-array name="config_face_auth_props">
+ <!-- sensorLocationX -->
+ <!-- sensorLocationY -->
+ <!--sensorRadius -->
+ </integer-array>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java b/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java
index 15312ad9dfd1..c9dea46c2f95 100644
--- a/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java
+++ b/packages/SystemUI/src/com/android/keyguard/DisabledUdfpsController.java
@@ -18,11 +18,12 @@ package com.android.keyguard;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
+import static com.android.systemui.classifier.Classifier.DISABLED_UDFPS_AFFORDANCE;
+
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.hardware.biometrics.BiometricSourceType;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -33,7 +34,9 @@ import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
@@ -53,14 +56,16 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
@NonNull private final KeyguardViewController mKeyguardViewController;
@NonNull private final StatusBarStateController mStatusBarStateController;
@NonNull private final KeyguardStateController mKeyguardStateController;
+ @NonNull private final FalsingManager mFalsingManager;
@NonNull private final Drawable mButton;
@NonNull private final Drawable mUnlockIcon;
private boolean mIsDozing;
private boolean mIsBouncerShowing;
- private boolean mIsKeyguardShowing;
private boolean mRunningFPS;
private boolean mCanDismissLockScreen;
+ private boolean mQsExpanded;
+ private int mStatusBarState;
private boolean mShowButton;
private boolean mShowUnlockIcon;
@@ -71,16 +76,19 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
@NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
@NonNull AuthController authController,
@NonNull KeyguardViewController keyguardViewController,
- @NonNull KeyguardStateController keyguardStateController
+ @NonNull KeyguardStateController keyguardStateController,
+ @NonNull FalsingManager falsingManager
) {
super(view);
- mView.setOnTouchListener(mOnTouchListener);
+ mView.setOnClickListener(v -> onAffordanceClick());
+ mView.setOnLongClickListener(v -> onAffordanceClick());
mView.setSensorProperties(authController.getUdfpsProps().get(0));
mStatusBarStateController = statusBarStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mKeyguardViewController = keyguardViewController;
mKeyguardStateController = keyguardStateController;
+ mFalsingManager = falsingManager;
final Context context = view.getContext();
mButton = context.getResources().getDrawable(
@@ -94,10 +102,10 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
@Override
protected void onViewAttached() {
mIsBouncerShowing = mKeyguardViewController.isBouncerShowing();
- mIsKeyguardShowing = mKeyguardStateController.isShowing();
mIsDozing = mStatusBarStateController.isDozing();
mRunningFPS = mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen();
+ mStatusBarState = mStatusBarStateController.getState();
mUnlockIcon.setTint(Utils.getColorAttrDefaultColor(mView.getContext(),
R.attr.wallpaperTextColorAccent));
updateVisibility();
@@ -114,6 +122,15 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
mKeyguardStateController.removeCallback(mKeyguardStateCallback);
}
+ private boolean onAffordanceClick() {
+ if (mFalsingManager.isFalseTouch(DISABLED_UDFPS_AFFORDANCE)) {
+ return false;
+ }
+ mView.setVisibility(View.INVISIBLE);
+ mKeyguardViewController.showBouncer(/* scrim */ true);
+ return true;
+ }
+
/**
* Call when this controller is no longer needed. This will remove the view from its parent.
*/
@@ -123,6 +140,14 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
}
}
+ /**
+ * Set whether qs is expanded. When QS is expanded, don't show a DisabledUdfps affordance.
+ */
+ public void setQsExpanded(boolean expanded) {
+ mQsExpanded = expanded;
+ updateVisibility();
+ }
+
private void updateVisibility() {
mShowButton = !mCanDismissLockScreen && !mRunningFPS && isLockScreen();
mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
@@ -139,7 +164,10 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
}
private boolean isLockScreen() {
- return mIsKeyguardShowing && !mIsDozing && !mIsBouncerShowing;
+ return !mIsDozing
+ && !mIsBouncerShowing
+ && !mQsExpanded
+ && mStatusBarState == StatusBarState.KEYGUARD;
}
@Override
@@ -148,20 +176,13 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
pw.println(" mShowBouncerButton: " + mShowButton);
pw.println(" mShowUnlockIcon: " + mShowUnlockIcon);
pw.println(" mIsDozing: " + mIsDozing);
- pw.println(" mIsKeyguardShowing: " + mIsKeyguardShowing);
pw.println(" mIsBouncerShowing: " + mIsBouncerShowing);
pw.println(" mRunningFPS: " + mRunningFPS);
pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen);
+ pw.println(" mStatusBarState: " + StatusBarState.toShortString(mStatusBarState));
+ pw.println(" mQsExpanded: " + mQsExpanded);
}
- private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- mKeyguardViewController.showBouncer(/* scrim */ true);
- return true;
- }
- };
-
private StatusBarStateController.StateListener mStatusBarStateListener =
new StatusBarStateController.StateListener() {
@Override
@@ -169,6 +190,12 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
mIsDozing = isDozing;
updateVisibility();
}
+
+ @Override
+ public void onStateChanged(int statusBarState) {
+ mStatusBarState = statusBarState;
+ updateVisibility();
+ }
};
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
@@ -193,21 +220,9 @@ public class DisabledUdfpsController extends ViewController<DisabledUdfpsView> i
private final KeyguardStateController.Callback mKeyguardStateCallback =
new KeyguardStateController.Callback() {
@Override
- public void onKeyguardShowingChanged() {
- updateIsKeyguardShowing();
- updateVisibility();
- }
-
- @Override
public void onUnlockedChanged() {
- updateIsKeyguardShowing();
mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen();
updateVisibility();
}
-
- private void updateIsKeyguardShowing() {
- mIsKeyguardShowing = mKeyguardStateController.isShowing()
- && !mKeyguardStateController.isKeyguardGoingAway();
- }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 94b4c5f87b16..28027427e245 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -29,6 +29,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
+import android.graphics.PointF;
import android.graphics.RectF;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
@@ -82,6 +83,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
@Nullable private final List<FingerprintSensorPropertiesInternal> mFpProps;
@Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
@Nullable private final List<FingerprintSensorPropertiesInternal> mUdfpsProps;
+ @Nullable private final PointF mFaceAuthSensorLocation;
// TODO: These should just be saved from onSaveState
private SomeArgs mCurrentDialogArgs;
@@ -261,10 +263,34 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
}
/**
- * @return where the UDFPS exists on the screen in pixels.
+ * @return where the UDFPS exists on the screen in pixels in portrait mode.
*/
public RectF getUdfpsRegion() {
- return mUdfpsController == null ? null : mUdfpsController.getSensorLocation();
+ return mUdfpsController == null
+ ? null
+ : mUdfpsController.getSensorLocation();
+ }
+
+ /**
+ * @return where the UDFPS exists on the screen in pixels in portrait mode.
+ */
+ public PointF getUdfpsSensorLocation() {
+ if (mUdfpsController == null) {
+ return null;
+ }
+ return new PointF(mUdfpsController.getSensorLocation().centerX(),
+ mUdfpsController.getSensorLocation().centerY());
+ }
+
+ /**
+ * @return where the face authentication sensor exists relative to the screen in pixels in
+ * portrait mode.
+ */
+ public PointF getFaceAuthSensorLocation() {
+ if (mFaceProps == null || mFaceAuthSensorLocation == null) {
+ return null;
+ }
+ return new PointF(mFaceAuthSensorLocation.x, mFaceAuthSensorLocation.y);
}
/**
@@ -339,6 +365,15 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
}
}
mUdfpsProps = !udfpsProps.isEmpty() ? udfpsProps : null;
+ int[] faceAuthLocation = context.getResources().getIntArray(
+ com.android.systemui.R.array.config_face_auth_props);
+ if (faceAuthLocation == null || faceAuthLocation.length < 2) {
+ mFaceAuthSensorLocation = null;
+ } else {
+ mFaceAuthSensorLocation = new PointF(
+ (float) faceAuthLocation[0],
+ (float) faceAuthLocation[1]);
+ }
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index a1149fd2a447..110351ebdd7d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -17,17 +17,19 @@
package com.android.systemui.biometrics
import android.content.Context
+import android.content.res.Configuration
+import android.graphics.PointF
import android.hardware.biometrics.BiometricSourceType
-import android.view.View
-import android.view.ViewGroup
-import com.android.internal.annotations.VisibleForTesting
+import androidx.annotation.VisibleForTesting
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.settingslib.Utils
-import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.ViewController
import java.io.PrintWriter
import javax.inject.Inject
@@ -35,76 +37,135 @@ import javax.inject.Inject
* Controls the ripple effect that shows when authentication is successful.
* The ripple uses the accent color of the current theme.
*/
-@SysUISingleton
+@StatusBarScope
class AuthRippleController @Inject constructor(
- commandRegistry: CommandRegistry,
- configurationController: ConfigurationController,
- private val context: Context,
- private val keyguardUpdateMonitor: KeyguardUpdateMonitor
-) {
+ private val sysuiContext: Context,
+ private val authController: AuthController,
+ private val configurationController: ConfigurationController,
+ private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+ private val commandRegistry: CommandRegistry,
+ private val notificationShadeWindowController: NotificationShadeWindowController,
+ rippleView: AuthRippleView?
+) : ViewController<AuthRippleView>(rippleView) {
+ private var fingerprintSensorLocation: PointF? = null
+ private var faceSensorLocation: PointF? = null
+
@VisibleForTesting
- var rippleView: AuthRippleView = AuthRippleView(context, attrs = null)
+ public override fun onViewAttached() {
+ updateRippleColor()
+ updateSensorLocation()
+ configurationController.addCallback(configurationChangedListener)
+ keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
+ commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() }
+ }
- val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
- override fun onBiometricAuthenticated(
- userId: Int,
- biometricSourceType: BiometricSourceType?,
- isStrongBiometric: Boolean
- ) {
- if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
- rippleView.startRipple()
- }
- }
+ @VisibleForTesting
+ public override fun onViewDetached() {
+ keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
+ configurationController.removeCallback(configurationChangedListener)
+ commandRegistry.unregisterCommand("auth-ripple")
+
+ notificationShadeWindowController.setForcePluginOpen(false, this)
}
- init {
- val configurationChangedListener = object : ConfigurationController.ConfigurationListener {
- override fun onUiModeChanged() {
- updateRippleColor()
- }
- override fun onThemeChanged() {
- updateRippleColor()
- }
- override fun onOverlayChanged() {
- updateRippleColor()
- }
+ private fun showRipple(biometricSourceType: BiometricSourceType?) {
+ if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
+ fingerprintSensorLocation != null) {
+ mView.setSensorLocation(fingerprintSensorLocation!!)
+ showRipple()
+ } else if (biometricSourceType == BiometricSourceType.FACE &&
+ faceSensorLocation != null) {
+ mView.setSensorLocation(faceSensorLocation!!)
+ showRipple()
}
- configurationController.addCallback(configurationChangedListener)
+ }
- commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() }
+ private fun showRipple() {
+ notificationShadeWindowController.setForcePluginOpen(true, this)
+ mView.startRipple(Runnable {
+ notificationShadeWindowController.setForcePluginOpen(false, this)
+ })
}
- fun setSensorLocation(x: Float, y: Float) {
- rippleView.setSensorLocation(x, y)
+ private fun updateSensorLocation() {
+ fingerprintSensorLocation = authController.udfpsSensorLocation
+ faceSensorLocation = authController.faceAuthSensorLocation
}
- fun setViewHost(viewHost: View) {
- // Add the ripple view to its host layout
- viewHost.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
- override fun onViewDetachedFromWindow(view: View?) {}
+ private fun updateRippleColor() {
+ mView.setColor(
+ Utils.getColorAttr(sysuiContext, android.R.attr.colorAccent).defaultColor)
+ }
- override fun onViewAttachedToWindow(view: View?) {
- (viewHost as ViewGroup).addView(rippleView)
- keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
- viewHost.removeOnAttachStateChangeListener(this)
+ val keyguardUpdateMonitorCallback =
+ object : KeyguardUpdateMonitorCallback() {
+ override fun onBiometricAuthenticated(
+ userId: Int,
+ biometricSourceType: BiometricSourceType?,
+ isStrongBiometric: Boolean
+ ) {
+ showRipple(biometricSourceType)
}
- })
-
- updateRippleColor()
}
- private fun updateRippleColor() {
- rippleView.setColor(
- Utils.getColorAttr(context, android.R.attr.colorAccent).defaultColor)
+ val configurationChangedListener =
+ object : ConfigurationController.ConfigurationListener {
+ override fun onConfigChanged(newConfig: Configuration?) {
+ updateSensorLocation()
+ }
+ override fun onUiModeChanged() {
+ updateRippleColor()
+ }
+ override fun onThemeChanged() {
+ updateRippleColor()
+ }
+ override fun onOverlayChanged() {
+ updateRippleColor()
+ }
}
inner class AuthRippleCommand : Command {
override fun execute(pw: PrintWriter, args: List<String>) {
- rippleView.startRipple()
+ if (args.isEmpty()) {
+ invalidCommand(pw)
+ } else {
+ when (args[0]) {
+ "fingerprint" -> {
+ pw.println("fingerprint ripple sensorLocation=$fingerprintSensorLocation")
+ showRipple(BiometricSourceType.FINGERPRINT)
+ }
+ "face" -> {
+ pw.println("face ripple sensorLocation=$faceSensorLocation")
+ showRipple(BiometricSourceType.FACE)
+ }
+ "custom" -> {
+ if (args.size != 3 ||
+ args[1].toFloatOrNull() == null ||
+ args[2].toFloatOrNull() == null) {
+ invalidCommand(pw)
+ return
+ }
+ pw.println("custom ripple sensorLocation=" + args[1].toFloat() + ", " +
+ args[2].toFloat())
+ mView.setSensorLocation(PointF(args[1].toFloat(), args[2].toFloat()))
+ showRipple()
+ }
+ else -> invalidCommand(pw)
+ }
+ }
}
override fun help(pw: PrintWriter) {
- pw.println("Usage: adb shell cmd statusbar auth-ripple")
+ pw.println("Usage: adb shell cmd statusbar auth-ripple <command>")
+ pw.println("Available commands:")
+ pw.println(" fingerprint")
+ pw.println(" face")
+ pw.println(" custom <x-location: int> <y-location: int>")
+ }
+
+ fun invalidCommand(pw: PrintWriter) {
+ pw.println("invalid command")
+ help(pw)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
index 1270677ccbc3..374ddaedb405 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -17,6 +17,7 @@ package com.android.systemui.biometrics
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
@@ -24,9 +25,11 @@ import android.graphics.Paint
import android.graphics.PointF
import android.util.AttributeSet
import android.view.View
+import android.view.animation.PathInterpolator
+import com.android.internal.graphics.ColorUtils
import com.android.systemui.statusbar.charging.RippleShader
-private const val RIPPLE_ANIMATION_DURATION: Long = 950
+private const val RIPPLE_ANIMATION_DURATION: Long = 1533
private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
/**
@@ -36,42 +39,64 @@ private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
private var rippleInProgress: Boolean = false
private val rippleShader = RippleShader()
- private val defaultColor: Int = 0xffffffff.toInt()
private val ripplePaint = Paint()
init {
- rippleShader.color = defaultColor
+ rippleShader.color = 0xffffffff.toInt() // default color
rippleShader.progress = 0f
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
ripplePaint.shader = rippleShader
- visibility = View.GONE
+ visibility = GONE
}
- fun setSensorLocation(x: Float, y: Float) {
- rippleShader.origin = PointF(x, y)
- rippleShader.radius = maxOf(x, y, width - x, height - y).toFloat()
+ fun setSensorLocation(location: PointF) {
+ rippleShader.origin = location
+ rippleShader.radius = maxOf(location.x, location.y, width - location.x, height - location.y)
+ .toFloat()
}
- fun startRipple() {
+ fun startRipple(onAnimationEnd: Runnable?) {
if (rippleInProgress) {
return // Ignore if ripple effect is already playing
}
+
val animator = ValueAnimator.ofFloat(0f, 1f)
+ animator.interpolator = PathInterpolator(0.4f, 0f, 0f, 1f)
animator.duration = RIPPLE_ANIMATION_DURATION
animator.addUpdateListener { animator ->
val now = animator.currentPlayTime
rippleShader.progress = animator.animatedValue as Float
rippleShader.time = now.toFloat()
+ rippleShader.distortionStrength = 1 - rippleShader.progress
+ invalidate()
+ }
+ val alphaInAnimator = ValueAnimator.ofInt(0, 127)
+ alphaInAnimator.duration = 167
+ alphaInAnimator.addUpdateListener { alphaInAnimator ->
+ rippleShader.color = ColorUtils.setAlphaComponent(rippleShader.color,
+ alphaInAnimator.animatedValue as Int)
invalidate()
}
- animator.addListener(object : AnimatorListenerAdapter() {
+ val alphaOutAnimator = ValueAnimator.ofInt(127, 0)
+ alphaOutAnimator.startDelay = 417
+ alphaOutAnimator.duration = 1116
+ alphaOutAnimator.addUpdateListener { alphaOutAnimator ->
+ rippleShader.color = ColorUtils.setAlphaComponent(rippleShader.color,
+ alphaOutAnimator.animatedValue as Int)
+ invalidate()
+ }
+
+ val animatorSet = AnimatorSet()
+ animatorSet.playTogether(animator, alphaInAnimator, alphaOutAnimator)
+ animatorSet.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
+ onAnimationEnd?.run()
rippleInProgress = false
- visibility = View.GONE
+ visibility = GONE
}
})
- animator.start()
- visibility = View.VISIBLE
+ animatorSet.start()
+ visibility = VISIBLE
rippleInProgress = true
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
index f4993f46bf1d..d9e1b501e1e1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
@@ -23,7 +23,6 @@ import android.graphics.RectF;
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.ViewController;
@@ -47,7 +46,6 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
@NonNull final DumpManager mDumpManger;
private boolean mNotificationShadeExpanded;
- private int mStatusBarState;
protected UdfpsAnimationViewController(
T view,
@@ -86,7 +84,6 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("mStatusBarState=" + StatusBarState.toShortString(mStatusBarState));
pw.println("mNotificationShadeExpanded=" + mNotificationShadeExpanded);
pw.println("shouldPauseAuth()=" + shouldPauseAuth());
pw.println("isPauseAuth=" + mView.isPauseAuth());
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 2bdbf518e203..405151d6b39d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -18,6 +18,7 @@ package com.android.systemui.biometrics;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -53,6 +54,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -89,9 +91,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@NonNull private final StatusBarStateController mStatusBarStateController;
@NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
@NonNull private final DumpManager mDumpManager;
- @NonNull private final AuthRippleController mAuthRippleController;
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@NonNull private final KeyguardViewMediator mKeyguardViewMediator;
+ @NonNull private FalsingManager mFalsingManager;
// 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;
@@ -292,6 +294,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
Log.v(TAG, "onTouch | finger up");
onFingerUp();
}
+ mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
+
break;
default:
@@ -311,9 +315,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@NonNull StatusBar statusBar,
@NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@NonNull DumpManager dumpManager,
- @NonNull AuthRippleController authRippleController,
@NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
- @NonNull KeyguardViewMediator keyguardViewMediator) {
+ @NonNull KeyguardViewMediator keyguardViewMediator,
+ @NonNull FalsingManager falsingManager) {
mContext = context;
mInflater = inflater;
// The fingerprint manager is queried for UDFPS before this class is constructed, so the
@@ -325,9 +329,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mStatusBarStateController = statusBarStateController;
mKeyguardViewManager = statusBarKeyguardViewManager;
mDumpManager = dumpManager;
- mAuthRippleController = authRippleController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mKeyguardViewMediator = keyguardViewMediator;
+ mFalsingManager = falsingManager;
mSensorProps = findFirstUdfps();
// At least one UDFPS sensor exists
@@ -353,10 +357,6 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.registerReceiver(mBroadcastReceiver, filter);
-
- mAuthRippleController.setViewHost(mStatusBar.getNotificationShadeWindowView());
- mAuthRippleController.setSensorLocation(getSensorLocation().centerX(),
- getSensorLocation().centerY());
}
@Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index dc0c685bf01e..35678e6773d5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -91,6 +91,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mStatusBarStateController.addCallback(mStateListener);
mStateListener.onDozeAmountChanged(dozeAmount, dozeAmount);
mStateListener.onStateChanged(mStatusBarStateController.getState());
+ mAlternateAuthInterceptor.setQsExpanded(mKeyguardViewManager.isQsExpanded());
mKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
}
@@ -117,6 +118,8 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
pw.println("mShowBouncer=" + mShowBouncer);
pw.println("mFaceDetectRunning=" + mFaceDetectRunning);
pw.println("mTransitioningFromHomeToKeyguard=" + mTransitioningFromHome);
+ pw.println("mStatusBarState" + StatusBarState.toShortString(mStatusBarState));
+ pw.println("mQsExpanded=" + mQsExpanded);
}
/**
@@ -215,6 +218,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
public void onStateChanged(int statusBarState) {
mStatusBarState = statusBarState;
mView.setStatusBarState(statusBarState);
+ updatePauseAuth();
}
};
@@ -283,7 +287,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@Override
public void dump(PrintWriter pw) {
- pw.print(getTag());
+ pw.println(getTag());
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
index 47b41f504644..4dd8780eb7ab 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
@@ -38,6 +38,8 @@ public abstract class Classifier {
public static final int BOUNCER_UNLOCK = 8;
public static final int PULSE_EXPAND = 9;
public static final int BRIGHTNESS_SLIDER = 10;
+ public static final int UDFPS_AUTHENTICATION = 11;
+ public static final int DISABLED_UDFPS_AFFORDANCE = 12;
@IntDef({
QUICK_SETTINGS,
@@ -50,7 +52,9 @@ public abstract class Classifier {
GENERIC,
BOUNCER_UNLOCK,
PULSE_EXPAND,
- BRIGHTNESS_SLIDER
+ BRIGHTNESS_SLIDER,
+ UDFPS_AUTHENTICATION,
+ DISABLED_UDFPS_AFFORDANCE
})
@Retention(RetentionPolicy.SOURCE)
public @interface InteractionType {}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
index 80d78637f9e2..6a7062224756 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
@@ -148,7 +148,9 @@ class DistanceClassifier extends FalsingClassifier {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
- if (interactionType == Classifier.BRIGHTNESS_SLIDER) {
+ if (interactionType == Classifier.BRIGHTNESS_SLIDER
+ || interactionType == Classifier.UDFPS_AUTHENTICATION
+ || interactionType == Classifier.DISABLED_UDFPS_AFFORDANCE) {
return Result.passed(0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
index f665565c069a..50e94b3e03c2 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
@@ -42,6 +42,11 @@ public class TypeClassifier extends FalsingClassifier {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
+ if (interactionType == Classifier.UDFPS_AUTHENTICATION
+ || interactionType == Classifier.DISABLED_UDFPS_AFFORDANCE) {
+ return Result.passed(0);
+ }
+
boolean vertical = isVertical();
boolean up = isUp();
boolean right = isRight();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
index 737167e8ed0c..b6357b8dbd8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
@@ -142,7 +142,7 @@ public interface NotificationShadeWindowController extends RemoteInputController
default void setDozing(boolean dozing) {}
/** Sets the state of whether plugin open is forced or not. */
- default void setForcePluginOpen(boolean forcePluginOpen) {}
+ default void setForcePluginOpen(boolean forcePluginOpen, Object token) {}
/** Gets whether we are forcing plugin open or not. */
default boolean getForcePluginOpen() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 18511d46b7b4..606658910232 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1851,6 +1851,10 @@ public class NotificationPanelViewController extends PanelViewController {
mPulseExpansionHandler.setQsExpanded(expanded);
mKeyguardBypassController.setQSExpanded(expanded);
mStatusBarKeyguardViewManager.setQsExpanded(expanded);
+
+ if (mDisabledUdfpsController != null) {
+ mDisabledUdfpsController.setQsExpanded(expanded);
+ }
}
}
@@ -3551,7 +3555,8 @@ public class NotificationPanelViewController extends PanelViewController {
mUpdateMonitor,
mAuthController,
mStatusBarKeyguardViewManager,
- mKeyguardStateController);
+ mKeyguardStateController,
+ mFalsingManager);
mDisabledUdfpsController.init();
} else if (mDisabledUdfpsController != null && !udfpsEnrolled) {
mDisabledUdfpsController.destroy();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index ee78c004c168..5aecb727517f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -611,12 +611,21 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
apply(mCurrentState);
}
+ private final Set<Object> mForceOpenTokens = new HashSet<>();
@Override
- public void setForcePluginOpen(boolean forcePluginOpen) {
- mCurrentState.mForcePluginOpen = forcePluginOpen;
- apply(mCurrentState);
- if (mForcePluginOpenListener != null) {
- mForcePluginOpenListener.onChange(forcePluginOpen);
+ public void setForcePluginOpen(boolean forceOpen, Object token) {
+ if (forceOpen) {
+ mForceOpenTokens.add(token);
+ } else {
+ mForceOpenTokens.remove(token);
+ }
+ final boolean previousForceOpenState = mCurrentState.mForcePluginOpen;
+ mCurrentState.mForcePluginOpen = !mForceOpenTokens.isEmpty();
+ if (previousForceOpenState != mCurrentState.mForcePluginOpen) {
+ apply(mCurrentState);
+ if (mForcePluginOpenListener != null) {
+ mForcePluginOpenListener.onChange(mCurrentState.mForcePluginOpen);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index b76abae088a8..f66b7a898950 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -207,7 +207,6 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.charging.ChargingRippleView;
import com.android.systemui.statusbar.charging.WiredChargingRippleController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -386,7 +385,6 @@ public class StatusBar extends SystemUI implements DemoMode,
private boolean mWakeUpComingFromTouch;
private PointF mWakeUpTouchLocation;
private LightRevealScrim mLightRevealScrim;
- private ChargingRippleView mChargingRipple;
private WiredChargingRippleController mChargingRippleAnimationController;
private PowerButtonReveal mPowerButtonReveal;
private CircleReveal mCircleReveal;
@@ -1060,7 +1058,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mMainThreadHandler.post(() -> {
mOverlays.remove(plugin);
mNotificationShadeWindowController
- .setForcePluginOpen(mOverlays.size() != 0);
+ .setForcePluginOpen(mOverlays.size() != 0, this);
});
}
@@ -1083,7 +1081,7 @@ public class StatusBar extends SystemUI implements DemoMode,
.setStateListener(b -> mOverlays.forEach(
o -> o.setCollapseDesired(b)));
mNotificationShadeWindowController
- .setForcePluginOpen(mOverlays.size() != 0);
+ .setForcePluginOpen(mOverlays.size() != 0, this);
});
}
}
@@ -1523,6 +1521,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController();
mLockscreenLockIconController = statusBarComponent.getLockscreenLockIconController();
mLockscreenLockIconController.init();
+ statusBarComponent.getAuthRippleController().init();
mNotificationPanelViewController.setLaunchAffordanceListener(
mLockscreenLockIconController::onShowingLaunchAffordanceChanged);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index ef2444eba814..2815ce7002d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -187,6 +187,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private int mLastBiometricMode;
private boolean mLastLockVisible;
private boolean mLastLockOrientationIsPortrait;
+ private boolean mQsExpanded;
private OnDismissAction mAfterKeyguardGoneAction;
private Runnable mKeyguardGoneCancelAction;
@@ -1128,9 +1129,16 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
/**
+ * Whether qs is currently expanded.
+ */
+ public boolean isQsExpanded() {
+ return mQsExpanded;
+ }
+ /**
* Set whether qs is currently expanded
*/
public void setQsExpanded(boolean expanded) {
+ mQsExpanded = expanded;
if (mAlternateAuthInterceptor != null) {
mAlternateAuthInterceptor.setQsExpanded(expanded);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
index ecd9613f84b2..e0cbbf0e0824 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
@@ -79,4 +80,10 @@ public interface StatusBarComponent {
*/
@StatusBarScope
LockscreenLockIconController getLockscreenLockIconController();
+
+ /**
+ * Creates an AuthRippleController
+ */
+ @StatusBarScope
+ AuthRippleController getAuthRippleController();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 781abe6cef3e..0ce7538a6566 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone.dagger;
import android.annotation.Nullable;
import com.android.systemui.R;
+import com.android.systemui.biometrics.AuthRippleView;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
@@ -44,4 +45,13 @@ public abstract class StatusBarViewModule {
NotificationShadeWindowView notificationShadeWindowView) {
return notificationShadeWindowView.findViewById(R.id.lock_icon);
}
+
+ /** */
+ @Provides
+ @StatusBarComponent.StatusBarScope
+ @Nullable
+ public static AuthRippleView getAuthRippleView(
+ NotificationShadeWindowView notificationShadeWindowView) {
+ return notificationShadeWindowView.findViewById(R.id.auth_ripple);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index 02ba304f8c37..d39507541ce5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -16,14 +16,14 @@
package com.android.systemui.biometrics
+import android.graphics.PointF
import android.hardware.biometrics.BiometricSourceType
import android.testing.AndroidTestingRunner
-import android.view.View
-import android.view.ViewGroup
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.policy.ConfigurationController
import org.junit.Before
@@ -32,6 +32,8 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.any
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
@@ -41,38 +43,66 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
class AuthRippleControllerTest : SysuiTestCase() {
private lateinit var controller: AuthRippleController
+ @Mock private lateinit var rippleView: AuthRippleView
@Mock private lateinit var commandRegistry: CommandRegistry
@Mock private lateinit var configurationController: ConfigurationController
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
- @Mock private lateinit var rippleView: AuthRippleView
- @Mock private lateinit var viewHost: ViewGroup
+ @Mock private lateinit var authController: AuthController
+ @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@Before
-
fun setUp() {
MockitoAnnotations.initMocks(this)
controller = AuthRippleController(
- commandRegistry, configurationController, context, keyguardUpdateMonitor)
- controller.rippleView = rippleView // Replace the real ripple view with a mock instance
- controller.setViewHost(viewHost)
+ context,
+ authController,
+ configurationController,
+ keyguardUpdateMonitor,
+ commandRegistry,
+ notificationShadeWindowController,
+ rippleView
+ )
+ controller.init()
}
@Test
- fun testAddRippleView() {
- val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
- verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture())
+ fun testFingerprintTriggerRipple() {
+ val fpsLocation = PointF(5f, 5f)
+ `when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
+ controller.onViewAttached()
+
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FINGERPRINT /* type */,
+ false /* isStrongBiometric */)
+ verify(rippleView).setSensorLocation(fpsLocation)
+ verify(rippleView).startRipple(any())
+ }
+
+ @Test
+ fun testFaceTriggerRipple() {
+ val faceLocation = PointF(5f, 5f)
+ `when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
+ controller.onViewAttached()
+
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
- // Fake attach to window
- listenerCaptor.value.onViewAttachedToWindow(viewHost)
- verify(viewHost).addView(rippleView)
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FACE /* type */,
+ false /* isStrongBiometric */)
+ verify(rippleView).setSensorLocation(faceLocation)
+ verify(rippleView).startRipple(any())
}
@Test
- fun testTriggerRipple() {
- // Fake attach to window
- val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
- verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture())
- listenerCaptor.value.onViewAttachedToWindow(viewHost)
+ fun testNullFaceSensorLocationDoesNothing() {
+ `when`(authController.faceAuthSensorLocation).thenReturn(null)
+ controller.onViewAttached()
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
@@ -81,17 +111,27 @@ class AuthRippleControllerTest : SysuiTestCase() {
0 /* userId */,
BiometricSourceType.FACE /* type */,
false /* isStrongBiometric */)
- verify(rippleView, never()).startRipple()
+ verify(rippleView, never()).startRipple(any())
+ }
+
+ @Test
+ fun testNullFingerprintSensorLocationDoesNothing() {
+ `when`(authController.udfpsSensorLocation).thenReturn(null)
+ controller.onViewAttached()
+
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
captor.value.onBiometricAuthenticated(
0 /* userId */,
BiometricSourceType.FINGERPRINT /* type */,
false /* isStrongBiometric */)
- verify(rippleView).startRipple()
+ verify(rippleView, never()).startRipple(any())
}
@Test
fun testUpdateRippleColor() {
+ controller.onViewAttached()
val captor = ArgumentCaptor
.forClass(ConfigurationController.ConfigurationListener::class.java)
verify(configurationController).addCallback(captor.capture())
@@ -104,10 +144,4 @@ class AuthRippleControllerTest : SysuiTestCase() {
captor.value.onUiModeChanged()
verify(rippleView).setColor(ArgumentMatchers.anyInt())
}
-
- @Test
- fun testForwardsSensorLocation() {
- controller.setSensorLocation(5f, 5f)
- verify(rippleView).setSensorLocation(5f, 5f)
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 9504970af19c..bbd3ce89b997 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -48,6 +48,7 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -100,13 +101,13 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private DumpManager mDumpManager;
@Mock
- private AuthRippleController mAuthRippleController;
- @Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
private KeyguardViewMediator mKeyguardViewMediator;
@Mock
private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback;
+ @Mock
+ private FalsingManager mFalsingManager;
private FakeExecutor mFgExecutor;
@@ -157,9 +158,9 @@ public class UdfpsControllerTest extends SysuiTestCase {
mStatusBar,
mStatusBarKeyguardViewManager,
mDumpManager,
- mAuthRippleController,
mKeyguardUpdateMonitor,
- mKeyguardViewMediator);
+ mKeyguardViewMediator,
+ mFalsingManager);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index fcea17c5a6b5..4b8eec44ef4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -119,7 +119,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
@Test
public void testSetForcePluginOpen_beforeStatusBarInitialization() {
- mNotificationShadeWindowController.setForcePluginOpen(true);
+ mNotificationShadeWindowController.setForcePluginOpen(true, this);
}
@Test