diff options
5 files changed, 0 insertions, 461 deletions
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt deleted file mode 100644 index ffa2b4662f33..000000000000 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.surfaceeffects.revealeffect - -import android.animation.Animator -import android.animation.AnimatorListenerAdapter -import android.animation.ValueAnimator -import android.graphics.RenderEffect -import androidx.core.graphics.ColorUtils -import com.android.systemui.surfaceeffects.RenderEffectDrawCallback -import com.android.systemui.surfaceeffects.utils.MathUtils -import kotlin.math.max -import kotlin.math.min - -/** Creates a reveal effect with a circular ripple sparkles on top. */ -class RippleRevealEffect( - private val config: RippleRevealEffectConfig, - private val renderEffectCallback: RenderEffectDrawCallback, - private val stateChangedCallback: AnimationStateChangedCallback? = null -) { - private val rippleRevealShader = RippleRevealShader().apply { applyConfig(config) } - private val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f) - - fun play() { - if (animator.isRunning) { - return - } - - animator.duration = config.duration.toLong() - animator.addUpdateListener { updateListener -> - val playTime = updateListener.currentPlayTime.toFloat() - rippleRevealShader.setTime(playTime * TIME_SCALE_FACTOR) - - // Compute radius. - val progress = updateListener.animatedValue as Float - val innerRad = MathUtils.lerp(config.innerRadiusStart, config.innerRadiusEnd, progress) - val outerRad = MathUtils.lerp(config.outerRadiusStart, config.outerRadiusEnd, progress) - rippleRevealShader.setInnerRadius(innerRad) - rippleRevealShader.setOuterRadius(outerRad) - - // Compute alphas. - val innerAlphaProgress = - MathUtils.constrainedMap( - 1f, - 0f, - config.innerFadeOutStart, - config.duration, - playTime - ) - val outerAlphaProgress = - MathUtils.constrainedMap( - 1f, - 0f, - config.outerFadeOutStart, - config.duration, - playTime - ) - val innerAlpha = MathUtils.lerp(0f, 255f, innerAlphaProgress) - val outerAlpha = MathUtils.lerp(0f, 255f, outerAlphaProgress) - - val innerColor = ColorUtils.setAlphaComponent(config.innerColor, innerAlpha.toInt()) - val outerColor = ColorUtils.setAlphaComponent(config.outerColor, outerAlpha.toInt()) - rippleRevealShader.setInnerColor(innerColor) - rippleRevealShader.setOuterColor(outerColor) - - // Pass in progresses since those functions take in normalized alpha values. - rippleRevealShader.setBackgroundAlpha(max(innerAlphaProgress, outerAlphaProgress)) - rippleRevealShader.setSparkleAlpha(min(innerAlphaProgress, outerAlphaProgress)) - - // Trigger draw callback. - renderEffectCallback.onDraw( - RenderEffect.createRuntimeShaderEffect( - rippleRevealShader, - RippleRevealShader.BACKGROUND_UNIFORM - ) - ) - } - animator.addListener( - object : AnimatorListenerAdapter() { - override fun onAnimationEnd(animation: Animator) { - stateChangedCallback?.onAnimationEnd() - } - } - ) - animator.start() - stateChangedCallback?.onAnimationStart() - } - - interface AnimationStateChangedCallback { - fun onAnimationStart() - fun onAnimationEnd() - } - - private companion object { - private const val TIME_SCALE_FACTOR = 0.00175f - } -} diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt deleted file mode 100644 index 9675f19613a8..000000000000 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.surfaceeffects.revealeffect - -import android.graphics.Color - -/** Defines parameters needed for [RippleRevealEffect]. */ -data class RippleRevealEffectConfig( - /** Total duration of the animation. */ - val duration: Float = 0f, - /** Timestamp of when the inner mask starts fade out. (Linear fadeout) */ - val innerFadeOutStart: Float = 0f, - /** Timestamp of when the outer mask starts fade out. (Linear fadeout) */ - val outerFadeOutStart: Float = 0f, - /** Center x position of the effect. */ - val centerX: Float = 0f, - /** Center y position of the effect. */ - val centerY: Float = 0f, - /** Start radius of the inner circle. */ - val innerRadiusStart: Float = 0f, - /** End radius of the inner circle. */ - val innerRadiusEnd: Float = 0f, - /** Start radius of the outer circle. */ - val outerRadiusStart: Float = 0f, - /** End radius of the outer circle. */ - val outerRadiusEnd: Float = 0f, - /** - * Pixel density of the display. Do not pass a random value. The value must come from - * [context.resources.displayMetrics.density]. - */ - val pixelDensity: Float = 1f, - /** - * The amount the circle masks should be softened. Higher value will make the edge of the circle - * mask soft. - */ - val blurAmount: Float = 0f, - /** Color of the inner circle mask. */ - val innerColor: Int = Color.WHITE, - /** Color of the outer circle mask. */ - val outerColor: Int = Color.WHITE, - /** Multiplier to make the sparkles visible. */ - val sparkleStrength: Float = SPARKLE_STRENGTH, - /** Size of the sparkle. Expected range [0, 1]. */ - val sparkleScale: Float = SPARKLE_SCALE -) { - /** Default parameters. */ - companion object { - const val SPARKLE_STRENGTH: Float = 0.3f - const val SPARKLE_SCALE: Float = 0.8f - } -} diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt deleted file mode 100644 index a3f979542055..000000000000 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.surfaceeffects.revealeffect - -import android.graphics.RuntimeShader -import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary -import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary - -/** Circular reveal effect with sparkles. */ -class RippleRevealShader : RuntimeShader(SHADER) { - // language=AGSL - companion object { - const val BACKGROUND_UNIFORM = "in_dst" - private const val MAIN = - """ - uniform shader ${BACKGROUND_UNIFORM}; - uniform half in_dstAlpha; - uniform half in_time; - uniform vec2 in_center; - uniform half in_innerRadius; - uniform half in_outerRadius; - uniform half in_sparkleStrength; - uniform half in_blur; - uniform half in_pixelDensity; - uniform half in_sparkleScale; - uniform half in_sparkleAlpha; - layout(color) uniform vec4 in_innerColor; - layout(color) uniform vec4 in_outerColor; - - vec4 main(vec2 p) { - half innerMask = soften(sdCircle(p - in_center, in_innerRadius), in_blur); - half outerMask = soften(sdCircle(p - in_center, in_outerRadius), in_blur); - - // Flip it since we are interested in the circle. - innerMask = 1.-innerMask; - outerMask = 1.-outerMask; - - // Color two circles using the mask. - vec4 inColor = vec4(in_innerColor.rgb, 1.) * in_innerColor.a; - vec4 outColor = vec4(in_outerColor.rgb, 1.) * in_outerColor.a; - vec4 blend = mix(inColor, outColor, innerMask); - - vec4 dst = vec4(in_dst.eval(p).rgb, 1.); - dst *= in_dstAlpha; - - blend *= blend.a; - // Do normal blend with the background. - blend = blend + dst * (1. - blend.a); - - half sparkle = - sparkles(p - mod(p, in_pixelDensity * in_sparkleScale), in_time); - // Add sparkles using additive blending. - blend += sparkle * in_sparkleStrength * in_sparkleAlpha; - - // Mask everything at the end. - blend *= outerMask; - - return blend; - } - """ - - private const val SHADER = - ShaderUtilLibrary.SHADER_LIB + - SdfShaderLibrary.SHADER_SDF_OPERATION_LIB + - SdfShaderLibrary.CIRCLE_SDF + - MAIN - } - - fun applyConfig(config: RippleRevealEffectConfig) { - setCenter(config.centerX, config.centerY) - setInnerRadius(config.innerRadiusStart) - setOuterRadius(config.outerRadiusStart) - setBlurAmount(config.blurAmount) - setPixelDensity(config.pixelDensity) - setSparkleScale(config.sparkleScale) - setSparkleStrength(config.sparkleStrength) - setInnerColor(config.innerColor) - setOuterColor(config.outerColor) - } - - fun setTime(time: Float) { - setFloatUniform("in_time", time) - } - - fun setCenter(centerX: Float, centerY: Float) { - setFloatUniform("in_center", centerX, centerY) - } - - fun setInnerRadius(radius: Float) { - setFloatUniform("in_innerRadius", radius) - } - - fun setOuterRadius(radius: Float) { - setFloatUniform("in_outerRadius", radius) - } - - fun setBlurAmount(blurAmount: Float) { - setFloatUniform("in_blur", blurAmount) - } - - fun setPixelDensity(density: Float) { - setFloatUniform("in_pixelDensity", density) - } - - fun setSparkleScale(scale: Float) { - setFloatUniform("in_sparkleScale", scale) - } - - fun setSparkleStrength(strength: Float) { - setFloatUniform("in_sparkleStrength", strength) - } - - fun setInnerColor(color: Int) { - setColorUniform("in_innerColor", color) - } - - fun setOuterColor(color: Int) { - setColorUniform("in_outerColor", color) - } - - /** Sets the background alpha. Range [0,1]. */ - fun setBackgroundAlpha(alpha: Float) { - setFloatUniform("in_dstAlpha", alpha) - } - - /** Sets the sparkle alpha. Range [0,1]. */ - fun setSparkleAlpha(alpha: Float) { - setFloatUniform("in_sparkleAlpha", alpha) - } -} diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt deleted file mode 100644 index 1411c32b813b..000000000000 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.surfaceeffects.utils - -/** Copied from android.utils.MathUtils */ -object MathUtils { - fun constrainedMap( - rangeMin: Float, - rangeMax: Float, - valueMin: Float, - valueMax: Float, - value: Float - ): Float { - return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value)) - } - - fun lerp(start: Float, stop: Float, amount: Float): Float { - return start + (stop - start) * amount - } - - fun lerpInv(a: Float, b: Float, value: Float): Float { - return if (a != b) (value - a) / (b - a) else 0.0f - } - - fun saturate(value: Float): Float { - return constrain(value, 0.0f, 1.0f) - } - - fun lerpInvSat(a: Float, b: Float, value: Float): Float { - return saturate(lerpInv(a, b, value)) - } - - fun constrain(amount: Float, low: Float, high: Float): Float { - return if (amount < low) low else if (amount > high) high else amount - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt deleted file mode 100644 index b1df159cdefc..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.surfaceeffects.revealeffect - -import android.graphics.RenderEffect -import android.testing.AndroidTestingRunner -import android.testing.TestableLooper -import androidx.test.filters.SmallTest -import com.android.systemui.animation.AnimatorTestRule -import com.android.systemui.model.SysUiStateTest -import com.android.systemui.surfaceeffects.RenderEffectDrawCallback -import com.google.common.truth.Truth.assertThat -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@SmallTest -@RunWith(AndroidTestingRunner::class) -@TestableLooper.RunWithLooper(setAsMainLooper = true) -class RippleRevealEffectTest : SysUiStateTest() { - - @get:Rule val animatorTestRule = AnimatorTestRule(this) - - @Test - fun play_triggersDrawCallback() { - var effectFromCallback: RenderEffect? = null - val revealEffectConfig = RippleRevealEffectConfig(duration = 1000f) - val drawCallback = - object : RenderEffectDrawCallback { - override fun onDraw(renderEffect: RenderEffect) { - effectFromCallback = renderEffect - } - } - val revealEffect = RippleRevealEffect(revealEffectConfig, drawCallback) - assertThat(effectFromCallback).isNull() - - revealEffect.play() - - animatorTestRule.advanceTimeBy(500L) - - assertThat(effectFromCallback).isNotNull() - } - - @Test - fun play_triggersStateChangedCallback() { - val revealEffectConfig = RippleRevealEffectConfig(duration = 1000f) - val drawCallback = - object : RenderEffectDrawCallback { - override fun onDraw(renderEffect: RenderEffect) {} - } - var animationStartedCalled = false - var animationEndedCalled = false - val stateChangedCallback = - object : RippleRevealEffect.AnimationStateChangedCallback { - override fun onAnimationStart() { - animationStartedCalled = true - } - - override fun onAnimationEnd() { - animationEndedCalled = true - } - } - val revealEffect = - RippleRevealEffect(revealEffectConfig, drawCallback, stateChangedCallback) - - assertThat(animationStartedCalled).isFalse() - assertThat(animationEndedCalled).isFalse() - - revealEffect.play() - - assertThat(animationStartedCalled).isTrue() - - animatorTestRule.advanceTimeBy(revealEffectConfig.duration.toLong()) - - assertThat(animationEndedCalled).isTrue() - } -} |