diff options
author | Beverly <beverlyt@google.com> | 2021-09-14 16:27:36 -0400 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-09-20 22:31:24 +0000 |
commit | d6ea4600743c304b0a6dc1ee7e4d38ac1b822960 (patch) | |
tree | 52c099e578b6ca56d9e806764ee5a11cae286e9e | |
parent | 0cf5a35912b13a534a577d7fa63065e76180cd5d (diff) | |
download | base-d6ea4600743c304b0a6dc1ee7e4d38ac1b822960.tar.gz |
Update dwell ripple parameters
Targeted effect:
* Immediate visual response on touch down at
sufficiently visible radius for variable finger sizes.
* Then decelerate radius expansion to convey tension / elicit
force and constrain at limited max radius past first stage.
* Bump values on non-AOD surface to improve visibility with
more variable backgrounds.
Test: `adb shell cmd statusbar auth-ripple dwell` expands ripple (but
doesn't animate the retract)
Test: manual, atest SystemUITests
Bug: 198864174
Change-Id: I1fb2e456e89a824b1b749150e3d82c6bc3223f47
(cherry picked from commit bc9015e209a3d9537f862fbd3ca7d8f0412630c9)
3 files changed, 64 insertions, 57 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index 9c818fff5018..e232316b8a94 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -40,6 +40,7 @@ import com.android.systemui.util.ViewController import java.io.PrintWriter import javax.inject.Inject import javax.inject.Provider +import com.android.systemui.plugins.statusbar.StatusBarStateController /*** * Controls the ripple effect that shows when authentication is successful. @@ -57,6 +58,7 @@ class AuthRippleController @Inject constructor( private val bypassController: KeyguardBypassController, private val biometricUnlockController: BiometricUnlockController, private val udfpsControllerProvider: Provider<UdfpsController>, + private val statusBarStateController: StatusBarStateController, rippleView: AuthRippleView? ) : ViewController<AuthRippleView>(rippleView) { var fingerprintSensorLocation: PointF? = null @@ -64,8 +66,11 @@ class AuthRippleController @Inject constructor( private var circleReveal: LightRevealEffect? = null private var udfpsController: UdfpsController? = null + private var dwellScale = 2f private var expandedDwellScale = 2.5f + private var aodDwellScale = 1.9f + private var aodExpandedDwellScale = 2.3f private var udfpsRadius: Float = -1f override fun onInit() { @@ -163,6 +168,22 @@ class AuthRippleController @Inject constructor( Utils.getColorAttr(sysuiContext, android.R.attr.colorAccent).defaultColor) } + private fun showDwellRipple() { + if (statusBarStateController.isDozing) { + mView.startDwellRipple( + /* startRadius */ udfpsRadius, + /* endRadius */ udfpsRadius * aodDwellScale, + /* expandedRadius */ udfpsRadius * aodExpandedDwellScale, + /* isDozing */ true) + } else { + mView.startDwellRipple( + /* startRadius */ udfpsRadius, + /* endRadius */ udfpsRadius * dwellScale, + /* expandedRadius */ udfpsRadius * expandedDwellScale, + /* isDozing */ false) + } + } + private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { override fun onBiometricAuthenticated( @@ -204,10 +225,7 @@ class AuthRippleController @Inject constructor( } mView.setSensorLocation(fingerprintSensorLocation!!) - mView.startDwellRipple( - /* startRadius */ udfpsRadius, - /* endRadius */ udfpsRadius * dwellScale, - /* expandedRadius */ udfpsRadius * expandedDwellScale) + showDwellRipple() } override fun onFingerUp() { @@ -234,14 +252,18 @@ class AuthRippleController @Inject constructor( } inner class AuthRippleCommand : Command { - fun printDwellInfo(pw: PrintWriter) { - pw.println("dwell ripple: " + + fun printLockScreenDwellInfo(pw: PrintWriter) { + pw.println("lock screen dwell ripple: " + "\n\tsensorLocation=$fingerprintSensorLocation" + "\n\tdwellScale=$dwellScale" + - "\n\tdwellAlpha=${mView.dwellAlpha}, " + - "duration=${mView.dwellAlphaDuration}" + - "\n\tdwellExpand=$expandedDwellScale" + - "\n\t(crash systemui to reset to default)") + "\n\tdwellExpand=$expandedDwellScale") + } + + fun printAodDwellInfo(pw: PrintWriter) { + pw.println("aod dwell ripple: " + + "\n\tsensorLocation=$fingerprintSensorLocation" + + "\n\tdwellScale=$aodDwellScale" + + "\n\tdwellExpand=$aodExpandedDwellScale") } override fun execute(pw: PrintWriter, args: List<String>) { @@ -249,40 +271,12 @@ class AuthRippleController @Inject constructor( invalidCommand(pw) } else { when (args[0]) { - "dwellScale" -> { - if (args.size > 1 && args[1].toFloatOrNull() != null) { - dwellScale = args[1].toFloat() - printDwellInfo(pw) - } else { - pw.println("expected float argument <dwellScale>") - } - } - "dwellAlpha" -> { - if (args.size > 2 && args[1].toFloatOrNull() != null && - args[2].toLongOrNull() != null) { - mView.dwellAlpha = args[1].toFloat() - if (args[2].toFloat() > 200L) { - pw.println("alpha animation duration must be less than 200ms.") - } - mView.dwellAlphaDuration = kotlin.math.min(args[2].toLong(), 200L) - printDwellInfo(pw) - } else { - pw.println("expected two float arguments:" + - " <dwellAlpha> <dwellAlphaDuration>") - } - } - "dwellExpand" -> { - if (args.size > 1 && args[1].toFloatOrNull() != null) { - val expandedScale = args[1].toFloat() - if (expandedScale <= dwellScale) { - pw.println("invalid expandedScale. must be greater than " + - "dwellScale=$dwellScale, but given $expandedScale") - } else { - expandedDwellScale = expandedScale - } - printDwellInfo(pw) + "dwell" -> { + showDwellRipple() + if (statusBarStateController.isDozing) { + printAodDwellInfo(pw) } else { - pw.println("expected float argument <expandedScale>") + printLockScreenDwellInfo(pw) } } "fingerprint" -> { @@ -313,9 +307,7 @@ class AuthRippleController @Inject constructor( override fun help(pw: PrintWriter) { pw.println("Usage: adb shell cmd statusbar auth-ripple <command>") pw.println("Available commands:") - pw.println(" dwellScale <200ms_scale: float>") - pw.println(" dwellAlpha <alpha: float> <duration : long>") - pw.println(" dwellExpand <expanded_scale: float>") + pw.println(" dwell") pw.println(" fingerprint") pw.println(" face") pw.println(" custom <x-location: int> <y-location: int>") diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt index 8e1303713171..1113579e417c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt @@ -45,12 +45,18 @@ private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f */ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private val retractInterpolator = PathInterpolator(.05f, .93f, .1f, 1f) - private val dwellPulseDuration = 200L - var dwellAlphaDuration = dwellPulseDuration + + private val dwellPulseDuration = 50L + private val dwellAlphaDuration = dwellPulseDuration + private val dwellAlpha: Float = 1f private val dwellExpandDuration = 1200L - dwellPulseDuration - private val retractDuration = 400L - var dwellAlpha: Float = .5f + private val aodDwellPulseDuration = 50L + private var aodDwellAlphaDuration = aodDwellPulseDuration + private var aodDwellAlpha: Float = .8f + private var aodDwellExpandDuration = 1200L - aodDwellPulseDuration + + private val retractDuration = 400L private var alphaInDuration: Long = 0 private var unlockedRippleInProgress: Boolean = false private val rippleShader = RippleShader() @@ -142,7 +148,12 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at * Ripple that moves animates from an outer ripple ring of * startRadius => endRadius => expandedRadius */ - fun startDwellRipple(startRadius: Float, endRadius: Float, expandedRadius: Float) { + fun startDwellRipple( + startRadius: Float, + endRadius: Float, + expandedRadius: Float, + isDozing: Boolean + ) { if (unlockedRippleInProgress || dwellPulseOutAnimator?.isRunning == true) { return } @@ -153,12 +164,13 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val endInitialDwellProgress = endRadius / radius / 4f val endExpandDwellProgress = expandedRadius / radius / 4f - val pulseOutEndAlpha = (255 * dwellAlpha).toInt() - val expandDwellEndAlpha = kotlin.math.min((255 * (dwellAlpha + .25f)).toInt(), 255) + val alpha = if (isDozing) aodDwellAlpha else dwellAlpha + val pulseOutEndAlpha = (255 * alpha).toInt() + val expandDwellEndAlpha = kotlin.math.min((255 * (alpha + .25f)).toInt(), 255) val dwellPulseOutRippleAnimator = ValueAnimator.ofFloat(startDwellProgress, endInitialDwellProgress).apply { interpolator = Interpolators.LINEAR_OUT_SLOW_IN - duration = dwellPulseDuration + duration = if (isDozing) aodDwellPulseDuration else dwellPulseDuration addUpdateListener { animator -> val now = animator.currentPlayTime rippleShader.progress = animator.animatedValue as Float @@ -170,7 +182,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val dwellPulseOutAlphaAnimator = ValueAnimator.ofInt(0, pulseOutEndAlpha).apply { interpolator = Interpolators.LINEAR - duration = dwellAlphaDuration + duration = if (isDozing) aodDwellAlphaDuration else dwellAlphaDuration addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, @@ -184,7 +196,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val expandDwellRippleAnimator = ValueAnimator.ofFloat(endInitialDwellProgress, endExpandDwellProgress).apply { interpolator = Interpolators.LINEAR_OUT_SLOW_IN - duration = dwellExpandDuration + duration = if (isDozing) aodDwellExpandDuration else dwellExpandDuration addUpdateListener { animator -> val now = animator.currentPlayTime rippleShader.progress = animator.animatedValue as Float @@ -197,7 +209,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val expandDwellAlphaAnimator = ValueAnimator.ofInt(pulseOutEndAlpha, expandDwellEndAlpha) .apply { interpolator = Interpolators.LINEAR - duration = dwellExpandDuration + duration = if (isDozing) aodDwellExpandDuration else dwellExpandDuration addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, 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 8f5eefcff186..5c73077c0e69 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt @@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.phone.BiometricUnlockController @@ -59,6 +60,7 @@ class AuthRippleControllerTest : SysuiTestCase() { @Mock private lateinit var biometricUnlockController: BiometricUnlockController @Mock private lateinit var udfpsControllerProvider: Provider<UdfpsController> @Mock private lateinit var udfpsController: UdfpsController + @Mock private lateinit var statusBarStateController: StatusBarStateController @Before fun setUp() { @@ -76,6 +78,7 @@ class AuthRippleControllerTest : SysuiTestCase() { bypassController, biometricUnlockController, udfpsControllerProvider, + statusBarStateController, rippleView ) controller.init() |