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 androidx.core.animation.Animator 20 import androidx.core.animation.AnimatorSet 21 import androidx.core.animation.PathInterpolator 22 import com.android.systemui.Dumpable 23 import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState 24 import com.android.systemui.statusbar.policy.CallbackController 25 import kotlinx.coroutines.flow.StateFlow 26 27 interface SystemStatusAnimationScheduler : 28 CallbackController<SystemStatusAnimationCallback>, Dumpable { 29 30 /** 31 * The current state of the animation. This can be used from compose functions to coordinate 32 * their animations with the chip 33 */ 34 val animationState: StateFlow<SystemEventAnimationState> 35 onStatusEventnull36 fun onStatusEvent(event: StatusEvent) 37 38 fun removePersistentDot() 39 } 40 41 /** 42 * The general idea here is that this scheduler will run two value animators, and provide 43 * animator-like callbacks for each kind of animation. The SystemChrome animation is expected to 44 * create space for the chip animation to display. This means hiding the system elements in the 45 * status bar and keyguard. 46 * 47 * The value animators themselves are simple animators from 0.0 to 1.0. Listeners can apply any 48 * interpolation they choose but realistically these are most likely to be simple alpha transitions 49 */ 50 interface SystemStatusAnimationCallback { 51 /** Implement this method to return an [Animator] or [AnimatorSet] that presents the chip */ 52 fun onSystemEventAnimationBegin(): Animator? { 53 return null 54 } 55 56 /** Implement this method to return an [Animator] or [AnimatorSet] that hides the chip */ 57 fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator? { 58 return null 59 } 60 61 // Best method name, change my mind 62 fun onSystemStatusAnimationTransitionToPersistentDot(contentDescription: String?): Animator? { 63 return null 64 } 65 66 fun onHidePersistentDot(): Animator? { 67 return null 68 } 69 } 70 71 /** Commonly-needed interpolators can go here */ 72 @JvmField val STATUS_BAR_X_MOVE_OUT = PathInterpolator(0.33f, 0f, 0f, 1f) 73 @JvmField val STATUS_BAR_X_MOVE_IN = PathInterpolator(0f, 0f, 0f, 1f) 74 /** 75 * Status chip animation to dot have multiple stages of motion, the _1 and _2 interpolators should 76 * be used in succession 77 */ 78 val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1 = PathInterpolator(0.44f, 0f, 0.25f, 1f) 79 val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0.26f, 1f) 80 val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1 = PathInterpolator(0.4f, 0f, 0.17f, 1f) 81 val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0f, 1f) 82 val STATUS_CHIP_MOVE_TO_DOT = PathInterpolator(0f, 0f, 0.05f, 1f) 83 84 internal const val DEBOUNCE_DELAY = 100L 85 86 /** 87 * The total time spent on the chip animation is 1500ms, broken up into 3 sections: 88 * - 500ms to animate the chip in (including animating system icons away) 89 * - 500ms holding the chip on screen 90 * - 500ms to animate the chip away (and system icons back) 91 */ 92 internal const val APPEAR_ANIMATION_DURATION = 500L 93 internal const val DISPLAY_LENGTH = 3000L 94 internal const val DISAPPEAR_ANIMATION_DURATION = 500L 95 96 internal const val MIN_UPTIME: Long = 5 * 1000 97