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 
17 package com.android.systemui.statusbar.phone.fragment
18 
19 import androidx.core.animation.Animator
20 import androidx.core.animation.AnimatorSet
21 import androidx.core.animation.ValueAnimator
22 import android.content.res.Resources
23 import android.view.View
24 import com.android.systemui.res.R
25 import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_IN
26 import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_OUT
27 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback
28 import com.android.systemui.util.animation.AnimationUtil.Companion.frames
29 import com.android.systemui.util.doOnCancel
30 import com.android.systemui.util.doOnEnd
31 
32 /**
33  * An implementation of [StatusBarSystemEventDefaultAnimator], applying the onAlphaChanged and
34  * onTranslationXChanged callbacks directly to the provided animatedView.
35  */
36 class StatusBarSystemEventAnimator @JvmOverloads constructor(
37         val animatedView: View,
38         resources: Resources,
39         isAnimationRunning: Boolean = false
40 ) : StatusBarSystemEventDefaultAnimator(
41         resources = resources,
42         onAlphaChanged = animatedView::setAlpha,
43         onTranslationXChanged = animatedView::setTranslationX,
44         isAnimationRunning = isAnimationRunning
45 )
46 
47 /**
48  * Tied directly to [SystemStatusAnimationScheduler]. Any StatusBar-like thing (keyguard, collapsed
49  * status bar fragment), can use this Animator to get the default system status animation. It simply
50  * needs to implement the onAlphaChanged and onTranslationXChanged callbacks.
51  *
52  * This animator relies on resources, and should be recreated whenever resources are updated. While
53  * this class could be used directly as the animation callback, it's probably best to forward calls
54  * to it so that it can be recreated at any moment without needing to remove/add callback.
55  */
56 
57 open class StatusBarSystemEventDefaultAnimator @JvmOverloads constructor(
58         resources: Resources,
59         private val onAlphaChanged: (Float) -> Unit,
60         private val onTranslationXChanged: (Float) -> Unit,
61         var isAnimationRunning: Boolean = false
62 ) : SystemStatusAnimationCallback {
63     private val translationXIn: Int = resources.getDimensionPixelSize(
64             R.dimen.ongoing_appops_chip_animation_in_status_bar_translation_x)
65     private val translationXOut: Int = resources.getDimensionPixelSize(
66             R.dimen.ongoing_appops_chip_animation_out_status_bar_translation_x)
67 
onSystemEventAnimationBeginnull68     override fun onSystemEventAnimationBegin(): Animator {
69         isAnimationRunning = true
70         val moveOut = ValueAnimator.ofFloat(0f, 1f).apply {
71             duration = 23.frames
72             interpolator = STATUS_BAR_X_MOVE_OUT
73             addUpdateListener {
74                 onTranslationXChanged(-(translationXIn * animatedValue as Float))
75             }
76         }
77         val alphaOut = ValueAnimator.ofFloat(1f, 0f).apply {
78             duration = 8.frames
79             interpolator = null
80             addUpdateListener {
81                 onAlphaChanged(animatedValue as Float)
82             }
83         }
84 
85         val animSet = AnimatorSet()
86         animSet.playTogether(moveOut, alphaOut)
87         return animSet
88     }
89 
onSystemEventAnimationFinishnull90     override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
91         onTranslationXChanged(translationXOut.toFloat())
92         val moveIn = ValueAnimator.ofFloat(1f, 0f).apply {
93             duration = 23.frames
94             startDelay = 7.frames
95             interpolator = STATUS_BAR_X_MOVE_IN
96             addUpdateListener {
97                 onTranslationXChanged(translationXOut * animatedValue as Float)
98             }
99         }
100         val alphaIn = ValueAnimator.ofFloat(0f, 1f).apply {
101             duration = 5.frames
102             startDelay = 11.frames
103             interpolator = null
104             addUpdateListener {
105                 onAlphaChanged(animatedValue as Float)
106             }
107         }
108 
109         val animatorSet = AnimatorSet()
110         animatorSet.playTogether(moveIn, alphaIn)
111         animatorSet.doOnEnd { isAnimationRunning = false }
112         animatorSet.doOnCancel { isAnimationRunning = false }
113         return animatorSet
114     }
115 }