1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.systemui.surfaceeffects.turbulencenoise 17 18 import android.view.View 19 import androidx.annotation.VisibleForTesting 20 21 /** Plays [TurbulenceNoiseView] in ease-in, main (no easing), and ease-out order. */ 22 class TurbulenceNoiseController(private val turbulenceNoiseView: TurbulenceNoiseView) { 23 24 companion object { 25 /** 26 * States of the turbulence noise animation. 27 * 28 * <p>The state is designed to be follow the order below: [AnimationState.EASE_IN], 29 * [AnimationState.MAIN], [AnimationState.EASE_OUT]. 30 */ 31 enum class AnimationState { 32 EASE_IN, 33 MAIN, 34 EASE_OUT, 35 NOT_PLAYING 36 } 37 } 38 39 /** Current state of the animation. */ 40 @VisibleForTesting 41 var state: AnimationState = AnimationState.NOT_PLAYING 42 set(value) { 43 field = value 44 if (state == AnimationState.NOT_PLAYING) { 45 turbulenceNoiseView.visibility = View.INVISIBLE 46 turbulenceNoiseView.clearConfig() 47 } else { 48 turbulenceNoiseView.visibility = View.VISIBLE 49 } 50 } 51 52 init { 53 turbulenceNoiseView.visibility = View.INVISIBLE 54 } 55 56 /** Updates the color of the noise. */ updateNoiseColornull57 fun updateNoiseColor(color: Int) { 58 if (state == AnimationState.NOT_PLAYING) { 59 return 60 } 61 turbulenceNoiseView.updateColor(color) 62 } 63 64 /** 65 * Plays [TurbulenceNoiseView] with the given config. 66 * 67 * <p>It plays ease-in, main, and ease-out animations in sequence. 68 */ playnull69 fun play( 70 baseType: TurbulenceNoiseShader.Companion.Type, 71 config: TurbulenceNoiseAnimationConfig 72 ) { 73 if (state != AnimationState.NOT_PLAYING) { 74 return // Ignore if any of the animation is playing. 75 } 76 77 turbulenceNoiseView.initShader(baseType, config) 78 playEaseInAnimation() 79 } 80 81 // TODO(b/237282226): Support force finish. 82 /** Finishes the main animation, which triggers the ease-out animation. */ finishnull83 fun finish() { 84 if (state == AnimationState.MAIN) { 85 turbulenceNoiseView.finish(nextAnimation = this::playEaseOutAnimation) 86 } 87 } 88 playEaseInAnimationnull89 private fun playEaseInAnimation() { 90 if (state != AnimationState.NOT_PLAYING) { 91 return 92 } 93 state = AnimationState.EASE_IN 94 95 turbulenceNoiseView.playEaseIn(this::playMainAnimation) 96 } 97 playMainAnimationnull98 private fun playMainAnimation() { 99 if (state != AnimationState.EASE_IN) { 100 return 101 } 102 state = AnimationState.MAIN 103 104 turbulenceNoiseView.play(this::playEaseOutAnimation) 105 } 106 playEaseOutAnimationnull107 private fun playEaseOutAnimation() { 108 if (state != AnimationState.MAIN) { 109 return 110 } 111 state = AnimationState.EASE_OUT 112 113 turbulenceNoiseView.playEaseOut(onAnimationEnd = { state = AnimationState.NOT_PLAYING }) 114 } 115 } 116