Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +42 −4 Original line number Diff line number Diff line Loading @@ -24,9 +24,13 @@ import androidx.annotation.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.settingslib.Utils import com.android.systemui.statusbar.CircleReveal import com.android.systemui.statusbar.LiftReveal import com.android.systemui.statusbar.LightRevealEffect 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.BiometricUnlockController import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.StatusBar import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope Loading @@ -49,10 +53,12 @@ class AuthRippleController @Inject constructor( private val commandRegistry: CommandRegistry, private val notificationShadeWindowController: NotificationShadeWindowController, private val bypassController: KeyguardBypassController, private val biometricUnlockController: BiometricUnlockController, rippleView: AuthRippleView? ) : ViewController<AuthRippleView>(rippleView) { var fingerprintSensorLocation: PointF? = null private var faceSensorLocation: PointF? = null private var circleReveal: LightRevealEffect? = null @VisibleForTesting public override fun onViewAttached() { Loading Loading @@ -96,15 +102,47 @@ class AuthRippleController @Inject constructor( private fun showRipple() { notificationShadeWindowController.setForcePluginOpen(true, this) mView.startRipple(Runnable { val biometricUnlockMode = biometricUnlockController.mode val useCircleReveal = circleReveal != null && (biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK || biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING || biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM) val lightRevealScrim = statusBar.lightRevealScrim if (useCircleReveal) { lightRevealScrim?.revealEffect = circleReveal!! } mView.startRipple( /* end runnable */ Runnable { notificationShadeWindowController.setForcePluginOpen(false, this) }) if (useCircleReveal) { lightRevealScrim?.revealEffect = LiftReveal } }, /* circleReveal */ if (useCircleReveal) { lightRevealScrim } else { null } ) } fun updateSensorLocation() { fingerprintSensorLocation = authController.fingerprintSensorLocation faceSensorLocation = authController.faceAuthSensorLocation statusBar.updateCircleReveal() fingerprintSensorLocation?.let { circleReveal = CircleReveal( it.x, it.y, 0f, Math.max( Math.max(it.x, statusBar.displayWidth - it.x), Math.max(it.y, statusBar.displayHeight - it.y) ) ) } } private fun updateRippleColor() { Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +62 −33 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.util.MathUtils import android.view.View import android.view.animation.PathInterpolator import com.android.internal.graphics.ColorUtils import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.charging.RippleShader private const val RIPPLE_ANIMATION_DURATION: Long = 1533 Loading Loading @@ -70,51 +71,79 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at .toFloat() } fun startRipple(onAnimationEnd: Runnable?) { fun startRipple(onAnimationEnd: Runnable?, lightReveal: LightRevealScrim?) { 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 rippleAnimator = ValueAnimator.ofFloat(0f, 1f).apply { interpolator = PathInterpolator(0.4f, 0f, 0f, 1f) duration = RIPPLE_ANIMATION_DURATION addUpdateListener { animator -> val now = animator.currentPlayTime rippleShader.progress = animator.animatedValue as Float rippleShader.time = now.toFloat() rippleShader.distortionStrength = 1 - rippleShader.progress lightReveal?.revealAmount = animator.animatedValue as Float invalidate() } val alphaInAnimator = ValueAnimator.ofInt(0, 127) alphaInAnimator.duration = 167 alphaInAnimator.addUpdateListener { alphaInAnimator -> rippleShader.color = ColorUtils.setAlphaComponent(rippleShader.color, alphaInAnimator.animatedValue as Int) } val revealAnimator = ValueAnimator.ofFloat(0f, 1f).apply { interpolator = rippleAnimator.interpolator startDelay = 10 duration = rippleAnimator.duration addUpdateListener { animator -> lightReveal?.revealAmount = animator.animatedValue as Float } } val alphaInAnimator = ValueAnimator.ofInt(0, 127).apply { duration = 167 addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, animator.animatedValue as Int ) invalidate() } 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) } val alphaOutAnimator = ValueAnimator.ofInt(127, 0).apply { startDelay = 417 duration = 1116 addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, animator.animatedValue as Int ) invalidate() } } val animatorSet = AnimatorSet().apply { playTogether( rippleAnimator, revealAnimator, alphaInAnimator, alphaOutAnimator ) addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { rippleInProgress = true visibility = VISIBLE } val animatorSet = AnimatorSet() animatorSet.playTogether(animator, alphaInAnimator, alphaOutAnimator) animatorSet.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { onAnimationEnd?.run() rippleInProgress = false visibility = GONE } }) } // TODO (b/185124905): custom haptic TBD // vibrate() animatorSet.start() visibility = VISIBLE rippleInProgress = true } fun setColor(color: Int) { Loading packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +4 −4 Original line number Diff line number Diff line Loading @@ -93,10 +93,10 @@ class CircleReveal( val endRadius: Float ) : LightRevealEffect { override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) { val interpolatedAmount = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(amount) val fadeAmount = LightRevealEffect.getPercentPastThreshold(interpolatedAmount, 0.75f) val radius = startRadius + ((endRadius - startRadius) * interpolatedAmount) // reveal amount updates already have an interpolator, so we intentionally use the // non-interpolated amount val fadeAmount = LightRevealEffect.getPercentPastThreshold(amount, 0.5f) val radius = startRadius + ((endRadius - startRadius) * amount) scrim.revealGradientEndColorAlpha = 1f - fadeAmount scrim.setRevealGradientBounds( centerX - radius /* left */, Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +7 −42 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.WindowType; import static android.app.StatusBarManager.WindowVisibleState; import static android.app.StatusBarManager.windowStateToString; import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.containsType; import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; Loading @@ -46,8 +45,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING; import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import static com.android.wm.shell.bubbles.BubbleController.TASKBAR_CHANGED_BROADCAST; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityOptions; Loading Loading @@ -121,6 +118,7 @@ import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; import android.widget.DateTimeView; import androidx.annotation.NonNull; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleRegistry; Loading Loading @@ -402,8 +400,6 @@ public class StatusBar extends SystemUI implements DemoMode, private LightRevealScrim mLightRevealScrim; private WiredChargingRippleController mChargingRippleAnimationController; private PowerButtonReveal mPowerButtonReveal; private CircleReveal mCircleReveal; private ValueAnimator mCircleRevealAnimator = ValueAnimator.ofFloat(0f, 1f); private final Object mQueueLock = new Object(); Loading Loading @@ -2808,11 +2804,11 @@ public class StatusBar extends SystemUI implements DemoMode, return mDisplayMetrics.density; } float getDisplayWidth() { public float getDisplayWidth() { return mDisplayMetrics.widthPixels; } float getDisplayHeight() { public float getDisplayHeight() { return mDisplayMetrics.heightPixels; } Loading Loading @@ -3542,9 +3538,6 @@ public class StatusBar extends SystemUI implements DemoMode, public void fadeKeyguardWhilePulsing() { mNotificationPanelViewController.fadeOut(0, FADE_KEYGUARD_DURATION_PULSING, ()-> { if (shouldShowCircleReveal()) { startCircleReveal(); } hideKeyguard(); mStatusBarKeyguardViewManager.onKeyguardFadedAway(); }).start(); Loading Loading @@ -3885,7 +3878,7 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onDozeAmountChanged(float linear, float eased) { if (mFeatureFlags.useNewLockscreenAnimations() && !mCircleRevealAnimator.isRunning()) { && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) { mLightRevealScrim.setRevealAmount(1f - linear); } } Loading @@ -3908,7 +3901,7 @@ public class StatusBar extends SystemUI implements DemoMode, || (!isDozing && mWakefulnessLifecycle.getLastWakeReason() == PowerManager.WAKE_REASON_POWER_BUTTON)) { mLightRevealScrim.setRevealEffect(mPowerButtonReveal); } else if (!mCircleRevealAnimator.isRunning()) { } else if (!(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) { mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE); } Loading @@ -3920,36 +3913,8 @@ public class StatusBar extends SystemUI implements DemoMode, Trace.endSection(); } /** * Update the parameters for the dozing circle reveal that animates when the user authenticates * from AOD using the fingerprint sensor. */ public void updateCircleReveal() { final PointF fpLocation = mAuthRippleController.getFingerprintSensorLocation(); if (fpLocation != null) { mCircleReveal = new CircleReveal( fpLocation.x, fpLocation.y, 0, Math.max(Math.max(fpLocation.x, getDisplayWidth() - fpLocation.x), Math.max(fpLocation.y, getDisplayHeight() - fpLocation.y))); } } private void startCircleReveal() { mLightRevealScrim.setRevealEffect(mCircleReveal); mCircleRevealAnimator.cancel(); mCircleRevealAnimator.addUpdateListener(animation -> mLightRevealScrim.setRevealAmount( (float) mCircleRevealAnimator.getAnimatedValue())); mCircleRevealAnimator.setDuration(900); mCircleRevealAnimator.start(); } private boolean shouldShowCircleReveal() { return mCircleReveal != null && !mCircleRevealAnimator.isRunning() && mBiometricUnlockController.getBiometricType() == FINGERPRINT; public LightRevealScrim getLightRevealScrim() { return mLightRevealScrim; } private void updateKeyguardState() { Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +10 −7 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ 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.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.StatusBar import com.android.systemui.statusbar.policy.ConfigurationController Loading Loading @@ -53,6 +54,7 @@ class AuthRippleControllerTest : SysuiTestCase() { @Mock private lateinit var authController: AuthController @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController @Mock private lateinit var bypassController: KeyguardBypassController @Mock private lateinit var biometricUnlockController: BiometricUnlockController @Before fun setUp() { Loading @@ -66,6 +68,7 @@ class AuthRippleControllerTest : SysuiTestCase() { commandRegistry, notificationShadeWindowController, bypassController, biometricUnlockController, rippleView ) controller.init() Loading @@ -90,7 +93,7 @@ class AuthRippleControllerTest : SysuiTestCase() { // THEN update sensor location and show ripple verify(rippleView).setSensorLocation(fpsLocation) verify(rippleView).startRipple(any()) verify(rippleView).startRipple(any(), any()) } @Test Loading @@ -111,7 +114,7 @@ class AuthRippleControllerTest : SysuiTestCase() { false /* isStrongBiometric */) // THEN no ripple verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -132,7 +135,7 @@ class AuthRippleControllerTest : SysuiTestCase() { false /* isStrongBiometric */) // THEN no ripple verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -156,7 +159,7 @@ class AuthRippleControllerTest : SysuiTestCase() { // THEN show ripple verify(rippleView).setSensorLocation(faceLocation) verify(rippleView).startRipple(any()) verify(rippleView).startRipple(any(), any()) } @Test Loading @@ -176,7 +179,7 @@ class AuthRippleControllerTest : SysuiTestCase() { false /* isStrongBiometric */) // THEN no ripple verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -191,7 +194,7 @@ class AuthRippleControllerTest : SysuiTestCase() { 0 /* userId */, BiometricSourceType.FACE /* type */, false /* isStrongBiometric */) verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -206,7 +209,7 @@ class AuthRippleControllerTest : SysuiTestCase() { 0 /* userId */, BiometricSourceType.FINGERPRINT /* type */, false /* isStrongBiometric */) verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +42 −4 Original line number Diff line number Diff line Loading @@ -24,9 +24,13 @@ import androidx.annotation.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.settingslib.Utils import com.android.systemui.statusbar.CircleReveal import com.android.systemui.statusbar.LiftReveal import com.android.systemui.statusbar.LightRevealEffect 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.BiometricUnlockController import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.StatusBar import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope Loading @@ -49,10 +53,12 @@ class AuthRippleController @Inject constructor( private val commandRegistry: CommandRegistry, private val notificationShadeWindowController: NotificationShadeWindowController, private val bypassController: KeyguardBypassController, private val biometricUnlockController: BiometricUnlockController, rippleView: AuthRippleView? ) : ViewController<AuthRippleView>(rippleView) { var fingerprintSensorLocation: PointF? = null private var faceSensorLocation: PointF? = null private var circleReveal: LightRevealEffect? = null @VisibleForTesting public override fun onViewAttached() { Loading Loading @@ -96,15 +102,47 @@ class AuthRippleController @Inject constructor( private fun showRipple() { notificationShadeWindowController.setForcePluginOpen(true, this) mView.startRipple(Runnable { val biometricUnlockMode = biometricUnlockController.mode val useCircleReveal = circleReveal != null && (biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK || biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING || biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM) val lightRevealScrim = statusBar.lightRevealScrim if (useCircleReveal) { lightRevealScrim?.revealEffect = circleReveal!! } mView.startRipple( /* end runnable */ Runnable { notificationShadeWindowController.setForcePluginOpen(false, this) }) if (useCircleReveal) { lightRevealScrim?.revealEffect = LiftReveal } }, /* circleReveal */ if (useCircleReveal) { lightRevealScrim } else { null } ) } fun updateSensorLocation() { fingerprintSensorLocation = authController.fingerprintSensorLocation faceSensorLocation = authController.faceAuthSensorLocation statusBar.updateCircleReveal() fingerprintSensorLocation?.let { circleReveal = CircleReveal( it.x, it.y, 0f, Math.max( Math.max(it.x, statusBar.displayWidth - it.x), Math.max(it.y, statusBar.displayHeight - it.y) ) ) } } private fun updateRippleColor() { Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +62 −33 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.util.MathUtils import android.view.View import android.view.animation.PathInterpolator import com.android.internal.graphics.ColorUtils import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.charging.RippleShader private const val RIPPLE_ANIMATION_DURATION: Long = 1533 Loading Loading @@ -70,51 +71,79 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at .toFloat() } fun startRipple(onAnimationEnd: Runnable?) { fun startRipple(onAnimationEnd: Runnable?, lightReveal: LightRevealScrim?) { 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 rippleAnimator = ValueAnimator.ofFloat(0f, 1f).apply { interpolator = PathInterpolator(0.4f, 0f, 0f, 1f) duration = RIPPLE_ANIMATION_DURATION addUpdateListener { animator -> val now = animator.currentPlayTime rippleShader.progress = animator.animatedValue as Float rippleShader.time = now.toFloat() rippleShader.distortionStrength = 1 - rippleShader.progress lightReveal?.revealAmount = animator.animatedValue as Float invalidate() } val alphaInAnimator = ValueAnimator.ofInt(0, 127) alphaInAnimator.duration = 167 alphaInAnimator.addUpdateListener { alphaInAnimator -> rippleShader.color = ColorUtils.setAlphaComponent(rippleShader.color, alphaInAnimator.animatedValue as Int) } val revealAnimator = ValueAnimator.ofFloat(0f, 1f).apply { interpolator = rippleAnimator.interpolator startDelay = 10 duration = rippleAnimator.duration addUpdateListener { animator -> lightReveal?.revealAmount = animator.animatedValue as Float } } val alphaInAnimator = ValueAnimator.ofInt(0, 127).apply { duration = 167 addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, animator.animatedValue as Int ) invalidate() } 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) } val alphaOutAnimator = ValueAnimator.ofInt(127, 0).apply { startDelay = 417 duration = 1116 addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, animator.animatedValue as Int ) invalidate() } } val animatorSet = AnimatorSet().apply { playTogether( rippleAnimator, revealAnimator, alphaInAnimator, alphaOutAnimator ) addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { rippleInProgress = true visibility = VISIBLE } val animatorSet = AnimatorSet() animatorSet.playTogether(animator, alphaInAnimator, alphaOutAnimator) animatorSet.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { onAnimationEnd?.run() rippleInProgress = false visibility = GONE } }) } // TODO (b/185124905): custom haptic TBD // vibrate() animatorSet.start() visibility = VISIBLE rippleInProgress = true } fun setColor(color: Int) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +4 −4 Original line number Diff line number Diff line Loading @@ -93,10 +93,10 @@ class CircleReveal( val endRadius: Float ) : LightRevealEffect { override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) { val interpolatedAmount = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(amount) val fadeAmount = LightRevealEffect.getPercentPastThreshold(interpolatedAmount, 0.75f) val radius = startRadius + ((endRadius - startRadius) * interpolatedAmount) // reveal amount updates already have an interpolator, so we intentionally use the // non-interpolated amount val fadeAmount = LightRevealEffect.getPercentPastThreshold(amount, 0.5f) val radius = startRadius + ((endRadius - startRadius) * amount) scrim.revealGradientEndColorAlpha = 1f - fadeAmount scrim.setRevealGradientBounds( centerX - radius /* left */, Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +7 −42 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.WindowType; import static android.app.StatusBarManager.WindowVisibleState; import static android.app.StatusBarManager.windowStateToString; import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.containsType; import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; Loading @@ -46,8 +45,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING; import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import static com.android.wm.shell.bubbles.BubbleController.TASKBAR_CHANGED_BROADCAST; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityOptions; Loading Loading @@ -121,6 +118,7 @@ import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; import android.widget.DateTimeView; import androidx.annotation.NonNull; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleRegistry; Loading Loading @@ -402,8 +400,6 @@ public class StatusBar extends SystemUI implements DemoMode, private LightRevealScrim mLightRevealScrim; private WiredChargingRippleController mChargingRippleAnimationController; private PowerButtonReveal mPowerButtonReveal; private CircleReveal mCircleReveal; private ValueAnimator mCircleRevealAnimator = ValueAnimator.ofFloat(0f, 1f); private final Object mQueueLock = new Object(); Loading Loading @@ -2808,11 +2804,11 @@ public class StatusBar extends SystemUI implements DemoMode, return mDisplayMetrics.density; } float getDisplayWidth() { public float getDisplayWidth() { return mDisplayMetrics.widthPixels; } float getDisplayHeight() { public float getDisplayHeight() { return mDisplayMetrics.heightPixels; } Loading Loading @@ -3542,9 +3538,6 @@ public class StatusBar extends SystemUI implements DemoMode, public void fadeKeyguardWhilePulsing() { mNotificationPanelViewController.fadeOut(0, FADE_KEYGUARD_DURATION_PULSING, ()-> { if (shouldShowCircleReveal()) { startCircleReveal(); } hideKeyguard(); mStatusBarKeyguardViewManager.onKeyguardFadedAway(); }).start(); Loading Loading @@ -3885,7 +3878,7 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onDozeAmountChanged(float linear, float eased) { if (mFeatureFlags.useNewLockscreenAnimations() && !mCircleRevealAnimator.isRunning()) { && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) { mLightRevealScrim.setRevealAmount(1f - linear); } } Loading @@ -3908,7 +3901,7 @@ public class StatusBar extends SystemUI implements DemoMode, || (!isDozing && mWakefulnessLifecycle.getLastWakeReason() == PowerManager.WAKE_REASON_POWER_BUTTON)) { mLightRevealScrim.setRevealEffect(mPowerButtonReveal); } else if (!mCircleRevealAnimator.isRunning()) { } else if (!(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) { mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE); } Loading @@ -3920,36 +3913,8 @@ public class StatusBar extends SystemUI implements DemoMode, Trace.endSection(); } /** * Update the parameters for the dozing circle reveal that animates when the user authenticates * from AOD using the fingerprint sensor. */ public void updateCircleReveal() { final PointF fpLocation = mAuthRippleController.getFingerprintSensorLocation(); if (fpLocation != null) { mCircleReveal = new CircleReveal( fpLocation.x, fpLocation.y, 0, Math.max(Math.max(fpLocation.x, getDisplayWidth() - fpLocation.x), Math.max(fpLocation.y, getDisplayHeight() - fpLocation.y))); } } private void startCircleReveal() { mLightRevealScrim.setRevealEffect(mCircleReveal); mCircleRevealAnimator.cancel(); mCircleRevealAnimator.addUpdateListener(animation -> mLightRevealScrim.setRevealAmount( (float) mCircleRevealAnimator.getAnimatedValue())); mCircleRevealAnimator.setDuration(900); mCircleRevealAnimator.start(); } private boolean shouldShowCircleReveal() { return mCircleReveal != null && !mCircleRevealAnimator.isRunning() && mBiometricUnlockController.getBiometricType() == FINGERPRINT; public LightRevealScrim getLightRevealScrim() { return mLightRevealScrim; } private void updateKeyguardState() { Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +10 −7 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ 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.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.StatusBar import com.android.systemui.statusbar.policy.ConfigurationController Loading Loading @@ -53,6 +54,7 @@ class AuthRippleControllerTest : SysuiTestCase() { @Mock private lateinit var authController: AuthController @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController @Mock private lateinit var bypassController: KeyguardBypassController @Mock private lateinit var biometricUnlockController: BiometricUnlockController @Before fun setUp() { Loading @@ -66,6 +68,7 @@ class AuthRippleControllerTest : SysuiTestCase() { commandRegistry, notificationShadeWindowController, bypassController, biometricUnlockController, rippleView ) controller.init() Loading @@ -90,7 +93,7 @@ class AuthRippleControllerTest : SysuiTestCase() { // THEN update sensor location and show ripple verify(rippleView).setSensorLocation(fpsLocation) verify(rippleView).startRipple(any()) verify(rippleView).startRipple(any(), any()) } @Test Loading @@ -111,7 +114,7 @@ class AuthRippleControllerTest : SysuiTestCase() { false /* isStrongBiometric */) // THEN no ripple verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -132,7 +135,7 @@ class AuthRippleControllerTest : SysuiTestCase() { false /* isStrongBiometric */) // THEN no ripple verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -156,7 +159,7 @@ class AuthRippleControllerTest : SysuiTestCase() { // THEN show ripple verify(rippleView).setSensorLocation(faceLocation) verify(rippleView).startRipple(any()) verify(rippleView).startRipple(any(), any()) } @Test Loading @@ -176,7 +179,7 @@ class AuthRippleControllerTest : SysuiTestCase() { false /* isStrongBiometric */) // THEN no ripple verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -191,7 +194,7 @@ class AuthRippleControllerTest : SysuiTestCase() { 0 /* userId */, BiometricSourceType.FACE /* type */, false /* isStrongBiometric */) verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading @@ -206,7 +209,7 @@ class AuthRippleControllerTest : SysuiTestCase() { 0 /* userId */, BiometricSourceType.FINGERPRINT /* type */, false /* isStrongBiometric */) verify(rippleView, never()).startRipple(any()) verify(rippleView, never()).startRipple(any(), any()) } @Test Loading