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