• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.events
18 
19 import android.annotation.IntDef
20 import androidx.core.animation.Animator
21 import androidx.core.animation.AnimatorSet
22 import androidx.core.animation.PathInterpolator
23 import com.android.systemui.Dumpable
24 import com.android.systemui.statusbar.policy.CallbackController
25 
26 interface SystemStatusAnimationScheduler :
27         CallbackController<SystemStatusAnimationCallback>, Dumpable {
28 
getAnimationStatenull29     @SystemAnimationState fun getAnimationState(): Int
30 
31     fun onStatusEvent(event: StatusEvent)
32 
33     fun removePersistentDot()
34 }
35 
36 /**
37  * The general idea here is that this scheduler will run two value animators, and provide
38  * animator-like callbacks for each kind of animation. The SystemChrome animation is expected to
39  * create space for the chip animation to display. This means hiding the system elements in the
40  * status bar and keyguard.
41  *
42  * The value animators themselves are simple animators from 0.0 to 1.0. Listeners can apply any
43  * interpolation they choose but realistically these are most likely to be simple alpha transitions
44  */
45 interface SystemStatusAnimationCallback {
46     /** Implement this method to return an [Animator] or [AnimatorSet] that presents the chip */
47     fun onSystemEventAnimationBegin(): Animator? { return null }
48     /** Implement this method to return an [Animator] or [AnimatorSet] that hides the chip */
49     fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator? { return null }
50 
51     // Best method name, change my mind
52     fun onSystemStatusAnimationTransitionToPersistentDot(contentDescription: String?): Animator? {
53         return null
54     }
55     fun onHidePersistentDot(): Animator? { return null }
56 }
57 
58 
59 /**
60  * Animation state IntDef
61  */
62 @Retention(AnnotationRetention.SOURCE)
63 @IntDef(
64         value = [
65             IDLE,
66             ANIMATION_QUEUED,
67             ANIMATING_IN,
68             RUNNING_CHIP_ANIM,
69             ANIMATING_OUT,
70             SHOWING_PERSISTENT_DOT
71         ]
72 )
73 annotation class SystemAnimationState
74 
75 /** No animation is in progress */
76 @SystemAnimationState const val IDLE = 0
77 /** An animation is queued, and awaiting the debounce period */
78 const val ANIMATION_QUEUED = 1
79 /** System is animating out, and chip is animating in */
80 const val ANIMATING_IN = 2
81 /** Chip has animated in and is awaiting exit animation, and optionally playing its own animation */
82 const val RUNNING_CHIP_ANIM = 3
83 /** Chip is animating away and system is animating back */
84 const val ANIMATING_OUT = 4
85 /** Chip has animated away, and the persistent dot is showing */
86 const val SHOWING_PERSISTENT_DOT = 5
87 
88 /** Commonly-needed interpolators can go here */
89 @JvmField val STATUS_BAR_X_MOVE_OUT = PathInterpolator(0.33f, 0f, 0f, 1f)
90 @JvmField val STATUS_BAR_X_MOVE_IN = PathInterpolator(0f, 0f, 0f, 1f)
91 /**
92  * Status chip animation to dot have multiple stages of motion, the _1 and _2 interpolators should
93  * be used in succession
94  */
95 val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1 = PathInterpolator(0.44f, 0f, 0.25f, 1f)
96 val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0.26f, 1f)
97 val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1 = PathInterpolator(0.4f, 0f, 0.17f, 1f)
98 val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0f, 1f)
99 val STATUS_CHIP_MOVE_TO_DOT = PathInterpolator(0f, 0f, 0.05f, 1f)
100 
101 internal const val DEBOUNCE_DELAY = 100L
102 
103 /**
104  * The total time spent on the chip animation is 1500ms, broken up into 3 sections:
105  * - 500ms to animate the chip in (including animating system icons away)
106  * - 500ms holding the chip on screen
107  * - 500ms to animate the chip away (and system icons back)
108  */
109 internal const val APPEAR_ANIMATION_DURATION = 500L
110 internal const val DISPLAY_LENGTH = 3000L
111 internal const val DISAPPEAR_ANIMATION_DURATION = 500L
112 
113 internal const val MIN_UPTIME: Long = 5 * 1000