Loading packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt +11 −8 Original line number Diff line number Diff line Loading @@ -15,8 +15,8 @@ */ package com.android.systemui.surfaceeffects.turbulencenoise import android.graphics.BlendMode import android.graphics.Color import java.util.Random /** Turbulence noise animation configuration. */ data class TurbulenceNoiseAnimationConfig( Loading @@ -26,6 +26,11 @@ data class TurbulenceNoiseAnimationConfig( /** Multiplier for the noise luma matte. Increase this for brighter effects. */ val luminosityMultiplier: Float = DEFAULT_LUMINOSITY_MULTIPLIER, /** Initial noise offsets. */ val noiseOffsetX: Float = random.nextFloat(), val noiseOffsetY: Float = random.nextFloat(), val noiseOffsetZ: Float = random.nextFloat(), /** * Noise move speed variables. * Loading @@ -45,18 +50,15 @@ data class TurbulenceNoiseAnimationConfig( val noiseMoveSpeedZ: Float = DEFAULT_NOISE_SPEED_Z, /** Color of the effect. */ var color: Int = DEFAULT_COLOR, val color: Int = DEFAULT_COLOR, /** Background color of the effect. */ val backgroundColor: Int = DEFAULT_BACKGROUND_COLOR, val opacity: Int = DEFAULT_OPACITY, val width: Float = 0f, val height: Float = 0f, val maxDuration: Float = DEFAULT_MAX_DURATION_IN_MILLIS, val easeInDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS, val easeOutDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS, val pixelDensity: Float = 1f, val blendMode: BlendMode = DEFAULT_BLEND_MODE, val onAnimationEnd: Runnable? = null, /** * Variants in noise. Higher number means more contrast; lower number means less contrast but * make the noise dimmed. You may want to increase the [lumaMatteBlendFactor] to compensate. Loading @@ -68,7 +70,9 @@ data class TurbulenceNoiseAnimationConfig( * want to use this if you have made the noise softer using [lumaMatteBlendFactor]. Expected * range [0, 1]. */ val lumaMatteOverallBrightness: Float = DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS val lumaMatteOverallBrightness: Float = DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS, /** Whether to flip the luma mask. */ val shouldInverseNoiseLuminosity: Boolean = false ) { companion object { const val DEFAULT_MAX_DURATION_IN_MILLIS = 30_000f // Max 30 sec Loading @@ -76,11 +80,10 @@ data class TurbulenceNoiseAnimationConfig( const val DEFAULT_LUMINOSITY_MULTIPLIER = 1f const val DEFAULT_NOISE_GRID_COUNT = 1.2f const val DEFAULT_NOISE_SPEED_Z = 0.3f const val DEFAULT_OPACITY = 150 // full opacity is 255. const val DEFAULT_COLOR = Color.WHITE const val DEFAULT_LUMA_MATTE_BLEND_FACTOR = 1f const val DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS = 0f const val DEFAULT_BACKGROUND_COLOR = Color.BLACK val DEFAULT_BLEND_MODE = BlendMode.SRC_OVER private val random = Random() } } packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt +5 −2 Original line number Diff line number Diff line Loading @@ -69,12 +69,15 @@ class TurbulenceNoiseController(private val turbulenceNoiseView: TurbulenceNoise * * <p>It plays ease-in, main, and ease-out animations in sequence. */ fun play(config: TurbulenceNoiseAnimationConfig) { fun play( baseType: TurbulenceNoiseShader.Companion.Type, config: TurbulenceNoiseAnimationConfig ) { if (state != AnimationState.NOT_PLAYING) { return // Ignore if any of the animation is playing. } turbulenceNoiseView.applyConfig(config) turbulenceNoiseView.initShader(baseType, config) playEaseInAnimation() } Loading packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt +31 −7 Original line number Diff line number Diff line Loading @@ -22,10 +22,10 @@ import java.lang.Float.max /** * Shader that renders turbulence simplex noise, by default no octave. * * @param useFractal whether to use fractal noise (4 octaves). * @param baseType the base [Type] of the shader. */ class TurbulenceNoiseShader(useFractal: Boolean = false) : RuntimeShader(if (useFractal) FRACTAL_NOISE_SHADER else SIMPLEX_NOISE_SHADER) { class TurbulenceNoiseShader(val baseType: Type = Type.SIMPLEX_NOISE) : RuntimeShader(getShader(baseType)) { // language=AGSL companion object { private const val UNIFORMS = Loading Loading @@ -86,11 +86,34 @@ class TurbulenceNoiseShader(useFractal: Boolean = false) : return vec4(color * in_opacity, in_opacity); } """ private const val SIMPLEX_NOISE_SHADER = ShaderUtilLibrary.SHADER_LIB + UNIFORMS + SIMPLEX_SHADER private const val FRACTAL_NOISE_SHADER = ShaderUtilLibrary.SHADER_LIB + UNIFORMS + FRACTAL_SHADER // TODO (b/282007590): Add NOISE_WITH_SPARKLE enum class Type { SIMPLEX_NOISE, SIMPLEX_NOISE_FRACTAL, } fun getShader(type: Type): String { return when (type) { Type.SIMPLEX_NOISE -> SIMPLEX_NOISE_SHADER Type.SIMPLEX_NOISE_FRACTAL -> FRACTAL_NOISE_SHADER } } } /** Convenient way for updating multiple uniform values via config object. */ fun applyConfig(config: TurbulenceNoiseAnimationConfig) { setGridCount(config.gridCount) setPixelDensity(config.pixelDensity) setColor(config.color) setBackgroundColor(config.backgroundColor) setSize(config.width, config.height) setLumaMatteFactors(config.lumaMatteBlendFactor, config.lumaMatteOverallBrightness) setInverseNoiseLuminosity(config.shouldInverseNoiseLuminosity) } /** Sets the number of grid for generating noise. */ Loading @@ -107,18 +130,19 @@ class TurbulenceNoiseShader(useFractal: Boolean = false) : setFloatUniform("in_pixelDensity", pixelDensity) } /** Sets the noise color of the effect. */ /** Sets the noise color of the effect. Alpha is ignored. */ fun setColor(color: Int) { setColorUniform("in_color", color) } /** Sets the background color of the effect. */ /** Sets the background color of the effect. Alpha is ignored. */ fun setBackgroundColor(color: Int) { setColorUniform("in_backgroundColor", color) } /** * Sets the opacity to achieve fade in/ out of the animation. * Sets the opacity of the effect. Not intended to set by the client as it is used for * ease-in/out animations. * * Expected value range is [1, 0]. */ Loading packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt +36 −31 Original line number Diff line number Diff line Loading @@ -19,12 +19,12 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.content.Context import android.graphics.BlendMode import android.graphics.Canvas import android.graphics.Paint import android.util.AttributeSet import android.view.View import androidx.annotation.VisibleForTesting import androidx.core.graphics.ColorUtils /** * View that renders turbulence noise effect. Loading @@ -44,8 +44,8 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex private const val MS_TO_SEC = 0.001f } private val turbulenceNoiseShader = TurbulenceNoiseShader() private val paint = Paint().apply { this.shader = turbulenceNoiseShader } private val paint = Paint() @VisibleForTesting var turbulenceNoiseShader: TurbulenceNoiseShader? = null @VisibleForTesting var noiseConfig: TurbulenceNoiseAnimationConfig? = null @VisibleForTesting var currentAnimator: ValueAnimator? = null Loading @@ -61,9 +61,7 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex /** Updates the color during the animation. No-op if there's no animation playing. */ internal fun updateColor(color: Int) { noiseConfig?.let { turbulenceNoiseShader.setColor(ColorUtils.setAlphaComponent(color, it.opacity)) } turbulenceNoiseShader?.setColor(color) } /** Plays the turbulence noise with no easing. */ Loading @@ -73,24 +71,25 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex return } val config = noiseConfig!! val shader = turbulenceNoiseShader!! val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = config.maxDuration.toLong() // Animation should start from the initial position to avoid abrupt transition. val initialX = turbulenceNoiseShader.noiseOffsetX val initialY = turbulenceNoiseShader.noiseOffsetY val initialZ = turbulenceNoiseShader.noiseOffsetZ val initialX = shader.noiseOffsetX val initialY = shader.noiseOffsetY val initialZ = shader.noiseOffsetZ animator.addUpdateListener { updateListener -> val timeInSec = updateListener.currentPlayTime * MS_TO_SEC turbulenceNoiseShader.setNoiseMove( shader.setNoiseMove( initialX + timeInSec * config.noiseMoveSpeedX, initialY + timeInSec * config.noiseMoveSpeedY, initialZ + timeInSec * config.noiseMoveSpeedZ ) turbulenceNoiseShader.setOpacity(config.luminosityMultiplier) shader.setOpacity(config.luminosityMultiplier) invalidate() } Loading @@ -115,27 +114,28 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex return } val config = noiseConfig!! val shader = turbulenceNoiseShader!! val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = config.easeInDuration.toLong() // Animation should start from the initial position to avoid abrupt transition. val initialX = turbulenceNoiseShader.noiseOffsetX val initialY = turbulenceNoiseShader.noiseOffsetY val initialZ = turbulenceNoiseShader.noiseOffsetZ val initialX = shader.noiseOffsetX val initialY = shader.noiseOffsetY val initialZ = shader.noiseOffsetZ animator.addUpdateListener { updateListener -> val timeInSec = updateListener.currentPlayTime * MS_TO_SEC val progress = updateListener.animatedValue as Float turbulenceNoiseShader.setNoiseMove( shader.setNoiseMove( offsetX + initialX + timeInSec * config.noiseMoveSpeedX, offsetY + initialY + timeInSec * config.noiseMoveSpeedY, initialZ + timeInSec * config.noiseMoveSpeedZ ) // TODO: Replace it with a better curve. turbulenceNoiseShader.setOpacity(progress * config.luminosityMultiplier) shader.setOpacity(progress * config.luminosityMultiplier) invalidate() } Loading @@ -160,27 +160,28 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex return } val config = noiseConfig!! val shader = turbulenceNoiseShader!! val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = config.easeOutDuration.toLong() // Animation should start from the initial position to avoid abrupt transition. val initialX = turbulenceNoiseShader.noiseOffsetX val initialY = turbulenceNoiseShader.noiseOffsetY val initialZ = turbulenceNoiseShader.noiseOffsetZ val initialX = shader.noiseOffsetX val initialY = shader.noiseOffsetY val initialZ = shader.noiseOffsetZ animator.addUpdateListener { updateListener -> val timeInSec = updateListener.currentPlayTime * MS_TO_SEC val progress = updateListener.animatedValue as Float turbulenceNoiseShader.setNoiseMove( shader.setNoiseMove( initialX + timeInSec * config.noiseMoveSpeedX, initialY + timeInSec * config.noiseMoveSpeedY, initialZ + timeInSec * config.noiseMoveSpeedZ ) // TODO: Replace it with a better curve. turbulenceNoiseShader.setOpacity((1f - progress) * config.luminosityMultiplier) shader.setOpacity((1f - progress) * config.luminosityMultiplier) invalidate() } Loading Loading @@ -211,18 +212,22 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex /** Applies shader uniforms. Must be called before playing animation. */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) fun applyConfig(config: TurbulenceNoiseAnimationConfig) { fun initShader( baseType: TurbulenceNoiseShader.Companion.Type, config: TurbulenceNoiseAnimationConfig ) { noiseConfig = config with(turbulenceNoiseShader) { setGridCount(config.gridCount) setColor(config.color) setBackgroundColor(config.backgroundColor) setSize(config.width, config.height) setPixelDensity(config.pixelDensity) setInverseNoiseLuminosity(inverse = false) setLumaMatteFactors(config.lumaMatteBlendFactor, config.lumaMatteOverallBrightness) } paint.blendMode = config.blendMode if (turbulenceNoiseShader == null || turbulenceNoiseShader?.baseType != baseType) { turbulenceNoiseShader = TurbulenceNoiseShader(baseType) paint.shader = turbulenceNoiseShader!! } turbulenceNoiseShader!!.applyConfig(config) } /** Sets the blend mode of the View. */ fun setBlendMode(blendMode: BlendMode) { paint.blendMode = blendMode } internal fun clearConfig() { Loading packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java +15 −5 Original line number Diff line number Diff line Loading @@ -118,6 +118,8 @@ import com.android.systemui.surfaceeffects.ripple.RippleAnimationConfig; import com.android.systemui.surfaceeffects.ripple.RippleShader; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseAnimationConfig; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseShader.Companion.Type; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView; import com.android.systemui.util.ColorUtilKt; import com.android.systemui.util.animation.TransitionLayout; import com.android.systemui.util.concurrency.DelayableExecutor; Loading @@ -132,6 +134,7 @@ import kotlin.Unit; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.Executor; import javax.inject.Inject; Loading Loading @@ -251,6 +254,8 @@ public class MediaControlPanel { private boolean mWasPlaying = false; private boolean mButtonClicked = false; private final Random mRandom = new Random(); /** * Initialize a new control panel * Loading Loading @@ -448,7 +453,10 @@ public class MediaControlPanel { MultiRippleView multiRippleView = vh.getMultiRippleView(); mMultiRippleController = new MultiRippleController(multiRippleView); mTurbulenceNoiseController = new TurbulenceNoiseController(vh.getTurbulenceNoiseView()); TurbulenceNoiseView turbulenceNoiseView = vh.getTurbulenceNoiseView(); turbulenceNoiseView.setBlendMode(BlendMode.SCREEN); mTurbulenceNoiseController = new TurbulenceNoiseController(turbulenceNoiseView); mColorSchemeTransition = new ColorSchemeTransition( mContext, mMediaViewHolder, mMultiRippleController, mTurbulenceNoiseController); Loading Loading @@ -587,6 +595,7 @@ public class MediaControlPanel { } // Color will be correctly updated in ColorSchemeTransition. mTurbulenceNoiseController.play( Type.SIMPLEX_NOISE, mTurbulenceNoiseAnimationConfig ); mMainExecutor.executeDelayed( Loading Loading @@ -1227,22 +1236,23 @@ public class MediaControlPanel { return new TurbulenceNoiseAnimationConfig( /* gridCount= */ 2.14f, TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER, /* noiseOffsetX= */ mRandom.nextFloat(), /* noiseOffsetY= */ mRandom.nextFloat(), /* noiseOffsetZ= */ mRandom.nextFloat(), /* noiseMoveSpeedX= */ 0.42f, /* noiseMoveSpeedY= */ 0f, TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_SPEED_Z, /* color= */ mColorSchemeTransition.getAccentPrimary().getCurrentColor(), /* backgroundColor= */ Color.BLACK, /* opacity= */ 51, /* width= */ mMediaViewHolder.getTurbulenceNoiseView().getWidth(), /* height= */ mMediaViewHolder.getTurbulenceNoiseView().getHeight(), TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS, /* easeInDuration= */ 1350f, /* easeOutDuration= */ 1350f, getContext().getResources().getDisplayMetrics().density, BlendMode.SCREEN, /* onAnimationEnd= */ null, /* lumaMatteBlendFactor= */ 0.26f, /* lumaMatteOverallBrightness= */ 0.09f /* lumaMatteOverallBrightness= */ 0.09f, /* shouldInverseNoiseLuminosity= */ false ); } private void clearButton(final ImageButton button) { Loading Loading
packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt +11 −8 Original line number Diff line number Diff line Loading @@ -15,8 +15,8 @@ */ package com.android.systemui.surfaceeffects.turbulencenoise import android.graphics.BlendMode import android.graphics.Color import java.util.Random /** Turbulence noise animation configuration. */ data class TurbulenceNoiseAnimationConfig( Loading @@ -26,6 +26,11 @@ data class TurbulenceNoiseAnimationConfig( /** Multiplier for the noise luma matte. Increase this for brighter effects. */ val luminosityMultiplier: Float = DEFAULT_LUMINOSITY_MULTIPLIER, /** Initial noise offsets. */ val noiseOffsetX: Float = random.nextFloat(), val noiseOffsetY: Float = random.nextFloat(), val noiseOffsetZ: Float = random.nextFloat(), /** * Noise move speed variables. * Loading @@ -45,18 +50,15 @@ data class TurbulenceNoiseAnimationConfig( val noiseMoveSpeedZ: Float = DEFAULT_NOISE_SPEED_Z, /** Color of the effect. */ var color: Int = DEFAULT_COLOR, val color: Int = DEFAULT_COLOR, /** Background color of the effect. */ val backgroundColor: Int = DEFAULT_BACKGROUND_COLOR, val opacity: Int = DEFAULT_OPACITY, val width: Float = 0f, val height: Float = 0f, val maxDuration: Float = DEFAULT_MAX_DURATION_IN_MILLIS, val easeInDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS, val easeOutDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS, val pixelDensity: Float = 1f, val blendMode: BlendMode = DEFAULT_BLEND_MODE, val onAnimationEnd: Runnable? = null, /** * Variants in noise. Higher number means more contrast; lower number means less contrast but * make the noise dimmed. You may want to increase the [lumaMatteBlendFactor] to compensate. Loading @@ -68,7 +70,9 @@ data class TurbulenceNoiseAnimationConfig( * want to use this if you have made the noise softer using [lumaMatteBlendFactor]. Expected * range [0, 1]. */ val lumaMatteOverallBrightness: Float = DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS val lumaMatteOverallBrightness: Float = DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS, /** Whether to flip the luma mask. */ val shouldInverseNoiseLuminosity: Boolean = false ) { companion object { const val DEFAULT_MAX_DURATION_IN_MILLIS = 30_000f // Max 30 sec Loading @@ -76,11 +80,10 @@ data class TurbulenceNoiseAnimationConfig( const val DEFAULT_LUMINOSITY_MULTIPLIER = 1f const val DEFAULT_NOISE_GRID_COUNT = 1.2f const val DEFAULT_NOISE_SPEED_Z = 0.3f const val DEFAULT_OPACITY = 150 // full opacity is 255. const val DEFAULT_COLOR = Color.WHITE const val DEFAULT_LUMA_MATTE_BLEND_FACTOR = 1f const val DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS = 0f const val DEFAULT_BACKGROUND_COLOR = Color.BLACK val DEFAULT_BLEND_MODE = BlendMode.SRC_OVER private val random = Random() } }
packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt +5 −2 Original line number Diff line number Diff line Loading @@ -69,12 +69,15 @@ class TurbulenceNoiseController(private val turbulenceNoiseView: TurbulenceNoise * * <p>It plays ease-in, main, and ease-out animations in sequence. */ fun play(config: TurbulenceNoiseAnimationConfig) { fun play( baseType: TurbulenceNoiseShader.Companion.Type, config: TurbulenceNoiseAnimationConfig ) { if (state != AnimationState.NOT_PLAYING) { return // Ignore if any of the animation is playing. } turbulenceNoiseView.applyConfig(config) turbulenceNoiseView.initShader(baseType, config) playEaseInAnimation() } Loading
packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt +31 −7 Original line number Diff line number Diff line Loading @@ -22,10 +22,10 @@ import java.lang.Float.max /** * Shader that renders turbulence simplex noise, by default no octave. * * @param useFractal whether to use fractal noise (4 octaves). * @param baseType the base [Type] of the shader. */ class TurbulenceNoiseShader(useFractal: Boolean = false) : RuntimeShader(if (useFractal) FRACTAL_NOISE_SHADER else SIMPLEX_NOISE_SHADER) { class TurbulenceNoiseShader(val baseType: Type = Type.SIMPLEX_NOISE) : RuntimeShader(getShader(baseType)) { // language=AGSL companion object { private const val UNIFORMS = Loading Loading @@ -86,11 +86,34 @@ class TurbulenceNoiseShader(useFractal: Boolean = false) : return vec4(color * in_opacity, in_opacity); } """ private const val SIMPLEX_NOISE_SHADER = ShaderUtilLibrary.SHADER_LIB + UNIFORMS + SIMPLEX_SHADER private const val FRACTAL_NOISE_SHADER = ShaderUtilLibrary.SHADER_LIB + UNIFORMS + FRACTAL_SHADER // TODO (b/282007590): Add NOISE_WITH_SPARKLE enum class Type { SIMPLEX_NOISE, SIMPLEX_NOISE_FRACTAL, } fun getShader(type: Type): String { return when (type) { Type.SIMPLEX_NOISE -> SIMPLEX_NOISE_SHADER Type.SIMPLEX_NOISE_FRACTAL -> FRACTAL_NOISE_SHADER } } } /** Convenient way for updating multiple uniform values via config object. */ fun applyConfig(config: TurbulenceNoiseAnimationConfig) { setGridCount(config.gridCount) setPixelDensity(config.pixelDensity) setColor(config.color) setBackgroundColor(config.backgroundColor) setSize(config.width, config.height) setLumaMatteFactors(config.lumaMatteBlendFactor, config.lumaMatteOverallBrightness) setInverseNoiseLuminosity(config.shouldInverseNoiseLuminosity) } /** Sets the number of grid for generating noise. */ Loading @@ -107,18 +130,19 @@ class TurbulenceNoiseShader(useFractal: Boolean = false) : setFloatUniform("in_pixelDensity", pixelDensity) } /** Sets the noise color of the effect. */ /** Sets the noise color of the effect. Alpha is ignored. */ fun setColor(color: Int) { setColorUniform("in_color", color) } /** Sets the background color of the effect. */ /** Sets the background color of the effect. Alpha is ignored. */ fun setBackgroundColor(color: Int) { setColorUniform("in_backgroundColor", color) } /** * Sets the opacity to achieve fade in/ out of the animation. * Sets the opacity of the effect. Not intended to set by the client as it is used for * ease-in/out animations. * * Expected value range is [1, 0]. */ Loading
packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt +36 −31 Original line number Diff line number Diff line Loading @@ -19,12 +19,12 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.content.Context import android.graphics.BlendMode import android.graphics.Canvas import android.graphics.Paint import android.util.AttributeSet import android.view.View import androidx.annotation.VisibleForTesting import androidx.core.graphics.ColorUtils /** * View that renders turbulence noise effect. Loading @@ -44,8 +44,8 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex private const val MS_TO_SEC = 0.001f } private val turbulenceNoiseShader = TurbulenceNoiseShader() private val paint = Paint().apply { this.shader = turbulenceNoiseShader } private val paint = Paint() @VisibleForTesting var turbulenceNoiseShader: TurbulenceNoiseShader? = null @VisibleForTesting var noiseConfig: TurbulenceNoiseAnimationConfig? = null @VisibleForTesting var currentAnimator: ValueAnimator? = null Loading @@ -61,9 +61,7 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex /** Updates the color during the animation. No-op if there's no animation playing. */ internal fun updateColor(color: Int) { noiseConfig?.let { turbulenceNoiseShader.setColor(ColorUtils.setAlphaComponent(color, it.opacity)) } turbulenceNoiseShader?.setColor(color) } /** Plays the turbulence noise with no easing. */ Loading @@ -73,24 +71,25 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex return } val config = noiseConfig!! val shader = turbulenceNoiseShader!! val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = config.maxDuration.toLong() // Animation should start from the initial position to avoid abrupt transition. val initialX = turbulenceNoiseShader.noiseOffsetX val initialY = turbulenceNoiseShader.noiseOffsetY val initialZ = turbulenceNoiseShader.noiseOffsetZ val initialX = shader.noiseOffsetX val initialY = shader.noiseOffsetY val initialZ = shader.noiseOffsetZ animator.addUpdateListener { updateListener -> val timeInSec = updateListener.currentPlayTime * MS_TO_SEC turbulenceNoiseShader.setNoiseMove( shader.setNoiseMove( initialX + timeInSec * config.noiseMoveSpeedX, initialY + timeInSec * config.noiseMoveSpeedY, initialZ + timeInSec * config.noiseMoveSpeedZ ) turbulenceNoiseShader.setOpacity(config.luminosityMultiplier) shader.setOpacity(config.luminosityMultiplier) invalidate() } Loading @@ -115,27 +114,28 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex return } val config = noiseConfig!! val shader = turbulenceNoiseShader!! val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = config.easeInDuration.toLong() // Animation should start from the initial position to avoid abrupt transition. val initialX = turbulenceNoiseShader.noiseOffsetX val initialY = turbulenceNoiseShader.noiseOffsetY val initialZ = turbulenceNoiseShader.noiseOffsetZ val initialX = shader.noiseOffsetX val initialY = shader.noiseOffsetY val initialZ = shader.noiseOffsetZ animator.addUpdateListener { updateListener -> val timeInSec = updateListener.currentPlayTime * MS_TO_SEC val progress = updateListener.animatedValue as Float turbulenceNoiseShader.setNoiseMove( shader.setNoiseMove( offsetX + initialX + timeInSec * config.noiseMoveSpeedX, offsetY + initialY + timeInSec * config.noiseMoveSpeedY, initialZ + timeInSec * config.noiseMoveSpeedZ ) // TODO: Replace it with a better curve. turbulenceNoiseShader.setOpacity(progress * config.luminosityMultiplier) shader.setOpacity(progress * config.luminosityMultiplier) invalidate() } Loading @@ -160,27 +160,28 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex return } val config = noiseConfig!! val shader = turbulenceNoiseShader!! val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = config.easeOutDuration.toLong() // Animation should start from the initial position to avoid abrupt transition. val initialX = turbulenceNoiseShader.noiseOffsetX val initialY = turbulenceNoiseShader.noiseOffsetY val initialZ = turbulenceNoiseShader.noiseOffsetZ val initialX = shader.noiseOffsetX val initialY = shader.noiseOffsetY val initialZ = shader.noiseOffsetZ animator.addUpdateListener { updateListener -> val timeInSec = updateListener.currentPlayTime * MS_TO_SEC val progress = updateListener.animatedValue as Float turbulenceNoiseShader.setNoiseMove( shader.setNoiseMove( initialX + timeInSec * config.noiseMoveSpeedX, initialY + timeInSec * config.noiseMoveSpeedY, initialZ + timeInSec * config.noiseMoveSpeedZ ) // TODO: Replace it with a better curve. turbulenceNoiseShader.setOpacity((1f - progress) * config.luminosityMultiplier) shader.setOpacity((1f - progress) * config.luminosityMultiplier) invalidate() } Loading Loading @@ -211,18 +212,22 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex /** Applies shader uniforms. Must be called before playing animation. */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) fun applyConfig(config: TurbulenceNoiseAnimationConfig) { fun initShader( baseType: TurbulenceNoiseShader.Companion.Type, config: TurbulenceNoiseAnimationConfig ) { noiseConfig = config with(turbulenceNoiseShader) { setGridCount(config.gridCount) setColor(config.color) setBackgroundColor(config.backgroundColor) setSize(config.width, config.height) setPixelDensity(config.pixelDensity) setInverseNoiseLuminosity(inverse = false) setLumaMatteFactors(config.lumaMatteBlendFactor, config.lumaMatteOverallBrightness) } paint.blendMode = config.blendMode if (turbulenceNoiseShader == null || turbulenceNoiseShader?.baseType != baseType) { turbulenceNoiseShader = TurbulenceNoiseShader(baseType) paint.shader = turbulenceNoiseShader!! } turbulenceNoiseShader!!.applyConfig(config) } /** Sets the blend mode of the View. */ fun setBlendMode(blendMode: BlendMode) { paint.blendMode = blendMode } internal fun clearConfig() { Loading
packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java +15 −5 Original line number Diff line number Diff line Loading @@ -118,6 +118,8 @@ import com.android.systemui.surfaceeffects.ripple.RippleAnimationConfig; import com.android.systemui.surfaceeffects.ripple.RippleShader; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseAnimationConfig; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseShader.Companion.Type; import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView; import com.android.systemui.util.ColorUtilKt; import com.android.systemui.util.animation.TransitionLayout; import com.android.systemui.util.concurrency.DelayableExecutor; Loading @@ -132,6 +134,7 @@ import kotlin.Unit; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.Executor; import javax.inject.Inject; Loading Loading @@ -251,6 +254,8 @@ public class MediaControlPanel { private boolean mWasPlaying = false; private boolean mButtonClicked = false; private final Random mRandom = new Random(); /** * Initialize a new control panel * Loading Loading @@ -448,7 +453,10 @@ public class MediaControlPanel { MultiRippleView multiRippleView = vh.getMultiRippleView(); mMultiRippleController = new MultiRippleController(multiRippleView); mTurbulenceNoiseController = new TurbulenceNoiseController(vh.getTurbulenceNoiseView()); TurbulenceNoiseView turbulenceNoiseView = vh.getTurbulenceNoiseView(); turbulenceNoiseView.setBlendMode(BlendMode.SCREEN); mTurbulenceNoiseController = new TurbulenceNoiseController(turbulenceNoiseView); mColorSchemeTransition = new ColorSchemeTransition( mContext, mMediaViewHolder, mMultiRippleController, mTurbulenceNoiseController); Loading Loading @@ -587,6 +595,7 @@ public class MediaControlPanel { } // Color will be correctly updated in ColorSchemeTransition. mTurbulenceNoiseController.play( Type.SIMPLEX_NOISE, mTurbulenceNoiseAnimationConfig ); mMainExecutor.executeDelayed( Loading Loading @@ -1227,22 +1236,23 @@ public class MediaControlPanel { return new TurbulenceNoiseAnimationConfig( /* gridCount= */ 2.14f, TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER, /* noiseOffsetX= */ mRandom.nextFloat(), /* noiseOffsetY= */ mRandom.nextFloat(), /* noiseOffsetZ= */ mRandom.nextFloat(), /* noiseMoveSpeedX= */ 0.42f, /* noiseMoveSpeedY= */ 0f, TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_SPEED_Z, /* color= */ mColorSchemeTransition.getAccentPrimary().getCurrentColor(), /* backgroundColor= */ Color.BLACK, /* opacity= */ 51, /* width= */ mMediaViewHolder.getTurbulenceNoiseView().getWidth(), /* height= */ mMediaViewHolder.getTurbulenceNoiseView().getHeight(), TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS, /* easeInDuration= */ 1350f, /* easeOutDuration= */ 1350f, getContext().getResources().getDisplayMetrics().density, BlendMode.SCREEN, /* onAnimationEnd= */ null, /* lumaMatteBlendFactor= */ 0.26f, /* lumaMatteOverallBrightness= */ 0.09f /* lumaMatteOverallBrightness= */ 0.09f, /* shouldInverseNoiseLuminosity= */ false ); } private void clearButton(final ImageButton button) { Loading