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 }