summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffect.kt170
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieShader.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffectTest.kt35
3 files changed, 35 insertions, 172 deletions
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffect.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffect.kt
index c08afd3e1bda..0cb01fd1e0b0 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffect.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffect.kt
@@ -44,31 +44,42 @@ class GlowPieEffect(
fun play() {
if (mainAnimator.isRunning) return
- baseGlow.resetProgress()
- firstGlowPie.resetProgress()
- secondGlowPie.resetProgress()
-
mainAnimator.addUpdateListener { updateListener ->
val time = updateListener.currentPlayTime.toFloat() % mainAnimator.duration
- // Remap each glow pie progress.
- baseGlow.updateProgress(time)
- firstGlowPie.updateProgress(time)
- secondGlowPie.updateProgress(time)
+ // TODO(b/335315940): Extract the timestamps to config.
+ val progress1 = MathUtils.constrainedMap(0f, 1f, 250f, 2500f, time)
+ val progress2 = MathUtils.constrainedMap(0f, 1f, 350f, 2600f, time)
// TODO(b/335315940): Consider passing in 2D Matrix.
- glowPieShader.setAngles(baseGlow.angle(), firstGlowPie.angle(), secondGlowPie.angle())
+ val angle0 = 0f // No rotation for the base.
+ // Negate the angle since we want clock-wise rotation.
+ val angle1 =
+ -(MathUtils.constrainedMap(-PI / 2f, 4f * PI, 0f, 1f, progress1) + progress1 * PI)
+ val angle2 =
+ -(MathUtils.constrainedMap(-PI / 2f, 3f * PI, 0f, 1f, progress2) + progress2 * PI)
+ glowPieShader.setAngle(angle0, angle1, angle2)
+ val bottomThreshold0 = 0f
+ val topThreshold0 = 0f
+
+ val bottomThreshold1 = MathUtils.lerp(1f, -FEATHER, progress1)
+ val topThreshold1 = MathUtils.lerp(1f + FEATHER, 0f, progress1)
+
+ val bottomThreshold2 = MathUtils.lerp(1f, -FEATHER, progress2)
+ val topThreshold2 = MathUtils.lerp(1f + FEATHER, 0f, progress2)
+
glowPieShader.setBottomAngleThresholds(
- baseGlow.bottomThreshold(),
- firstGlowPie.bottomThreshold(),
- secondGlowPie.bottomThreshold()
+ bottomThreshold0,
+ bottomThreshold1,
+ bottomThreshold2
)
- glowPieShader.setTopAngleThresholds(
- baseGlow.topThreshold(),
- firstGlowPie.topThreshold(),
- secondGlowPie.topThreshold()
- )
- glowPieShader.setAlphas(baseGlow.alpha(), firstGlowPie.alpha(), secondGlowPie.alpha())
+ glowPieShader.setTopAngleThresholds(topThreshold0, topThreshold1, topThreshold2)
+
+ // Remap timestamps (in MS) to alpha [0, 1].
+ val alpha0 = MathUtils.constrainedMap(0f, 1f, 2250f, 2950f, time)
+ val alpha1 = MathUtils.constrainedMap(1f, 0f, 2500f, 2750f, time)
+ val alpha2 = MathUtils.constrainedMap(1f, 0f, 2600f, 2850f, time)
+ glowPieShader.setAlphas(alpha0, alpha1, alpha2)
// Finally trigger the draw callback.
renderEffectDrawCallback.onDraw(
@@ -87,123 +98,10 @@ class GlowPieEffect(
mainAnimator.cancel()
}
- companion object {
- @VisibleForTesting const val PI = Math.PI.toFloat()
- @VisibleForTesting const val FEATHER = 0.3f
- @VisibleForTesting const val DURATION_MS = 3000L
-
- private val baseGlow = BaseGlow()
- private val firstGlowPie = FirstGlowPie()
- private val secondGlowPie = SecondGlowPie()
- }
-
- /** Contains animation parameters for each layer of glow pie. */
- interface GlowPie {
- /**
- * The start & end timestamps of the animation. Must be smaller than or equal to the full
- * [DURATION_MS].
- */
- val startMs: Float
- val endMs: Float
- /**
- * Start & end angles in radian. This determines how many cycles you want to rotate. e.g.
- * startAngle = 0f endAngle = 4f * PI, will give you the 2 cycles.
- */
- val startAngle: Float
- val endAngle: Float
- /**
- * Start & end timestamps of the fade out duration. You may want to override [alpha] if you
- * want to make it fade in. See [BaseGlow].
- */
- val alphaFadeStartMs: Float
- val alphaFadeEndMs: Float
-
- /** Below two values are expected to be updated through [updateProgress]. */
- /** Normalized progress. */
- var progress: Float
- /** current time of the animation in ms. */
- var time: Float
-
- // Must be called before retrieving angle, bottom & top thresholds, and alpha.
- // Otherwise the values would be stale.
- fun updateProgress(time: Float) {
- progress = MathUtils.constrainedMap(0f, 1f, startMs, endMs, time)
- this.time = time
- }
-
- fun resetProgress() {
- progress = 0f
- time = 0f
- }
-
- fun angle(): Float {
- // Negate the angle since we want clock-wise rotation.
- val angle =
- MathUtils.constrainedMap(startAngle, endAngle, 0f, 1f, progress) + progress * PI
- return -angle
- }
-
- fun bottomThreshold(): Float {
- return MathUtils.lerp(1f, -FEATHER, progress)
- }
-
- fun topThreshold(): Float {
- return MathUtils.lerp(1f + FEATHER, 0f, progress)
- }
-
- // By default, it fades "out".
- fun alpha(): Float {
- // Remap timestamps (in MS) to alpha [0, 1].
- return MathUtils.constrainedMap(1f, 0f, alphaFadeStartMs, alphaFadeEndMs, time)
- }
- }
-
- data class BaseGlow(
- override val startMs: Float = 0f,
- override val endMs: Float = 0f,
- override val startAngle: Float = 0f,
- override val endAngle: Float = 0f,
- override val alphaFadeStartMs: Float = 2250f,
- override val alphaFadeEndMs: Float = 2950f,
- ) : GlowPie {
-
- override var progress: Float = 1f
- override var time: Float = 0f
- override fun updateProgress(time: Float) {}
-
- override fun resetProgress() {}
-
- override fun angle(): Float = 0f
-
- override fun bottomThreshold(): Float = 0f
-
- override fun topThreshold(): Float = 0f
-
- // Base glow fade "in" (i.e. reveals).
- override fun alpha(): Float {
- return MathUtils.constrainedMap(0f, 1f, alphaFadeStartMs, alphaFadeEndMs, time)
- }
+ private companion object {
+ private const val PI = Math.PI.toFloat()
+ private const val FEATHER = 0.3f
+ // This indicates a single loop of the animation.
+ private const val DURATION_MS = 3000L
}
-
- data class FirstGlowPie(
- override val startMs: Float = 250f,
- override val endMs: Float = 2500f,
- override val startAngle: Float = -PI / 2f,
- override val endAngle: Float = 4f * PI,
- override val alphaFadeStartMs: Float = 2500f,
- override val alphaFadeEndMs: Float = 2750f,
- override var progress: Float = 0f,
- override var time: Float = 0f
- ) : GlowPie
-
- data class SecondGlowPie(
- override val startMs: Float = 350f,
- override val endMs: Float = 2600f,
- override val startAngle: Float = -PI / 2f,
- override val endAngle: Float = 3f * PI,
- override val alphaFadeStartMs: Float = 2600f,
- override val alphaFadeEndMs: Float = 2850f,
- override var progress: Float = 0f,
- override var time: Float = 0f
- ) : GlowPie
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieShader.kt
index 2dbc0b5e24aa..cbb781fa4950 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieShader.kt
@@ -199,7 +199,7 @@ class GlowPieShader : RuntimeShader(GLOW_PIE_SHADER_COMP) {
setColorUniform("in_colors2", colors[2])
}
- fun setAngles(vararg angles: Float) {
+ fun setAngle(vararg angles: Float) {
if (angles.size != NUM_PIE) {
Log.wtf(TAG, "The number of angles must be $NUM_PIE")
return
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffectTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffectTest.kt
index 8105cc58b58e..792d65c0d556 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffectTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/gloweffect/GlowPieEffectTest.kt
@@ -91,39 +91,4 @@ class GlowPieEffectTest : SysUiStateTest() {
assertThat(glowPieEffect.mainAnimator.isRunning).isFalse()
}
-
- @Test
- fun glowPie_progress_computesProgressCorrectly() {
- val myGlowPieConfig =
- object : GlowPieEffect.GlowPie {
- override val startMs: Float = 0f
- override val endMs: Float = GlowPieEffect.DURATION_MS.toFloat()
- override val startAngle: Float = 0f
- override val endAngle: Float = 6f * GlowPieEffect.PI
- override val alphaFadeStartMs: Float = 0f
- override val alphaFadeEndMs: Float = GlowPieEffect.DURATION_MS.toFloat()
- override var progress: Float = 0f
- override var time: Float = 0f
- }
-
- val playTime = GlowPieEffect.DURATION_MS.toFloat() * 0.5f
- val tolerance = 1e-4f
- myGlowPieConfig.updateProgress(playTime)
-
- assertThat(myGlowPieConfig.time).isWithin(tolerance).of(playTime)
- assertThat(myGlowPieConfig.progress).isWithin(tolerance).of(0.5f)
- assertThat(myGlowPieConfig.angle()).isWithin(tolerance).of(-3.5f * GlowPieEffect.PI)
- assertThat(myGlowPieConfig.bottomThreshold())
- .isWithin(tolerance)
- .of((1f - GlowPieEffect.FEATHER) * 0.5f)
- assertThat(myGlowPieConfig.topThreshold())
- .isWithin(tolerance)
- .of((1f + GlowPieEffect.FEATHER) * 0.5f)
- assertThat(myGlowPieConfig.alpha()).isWithin(tolerance).of(0.5f)
-
- myGlowPieConfig.resetProgress()
-
- assertThat(myGlowPieConfig.time).isEqualTo(0f)
- assertThat(myGlowPieConfig.progress).isEqualTo(0f)
- }
}