1 /* <lambda>null2 * Copyright (C) 2024 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.wm.shell.shared.animation 18 19 import android.animation.Animator 20 import android.animation.AnimatorSet 21 import android.animation.ValueAnimator 22 import android.content.Context 23 import android.os.Handler 24 import android.view.Choreographer 25 import android.view.SurfaceControl.Transaction 26 import android.window.TransitionInfo.Change 27 import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_MINIMIZE_WINDOW 28 import com.android.internal.jank.InteractionJankMonitor 29 30 /** Creates minimization animation */ 31 object MinimizeAnimator { 32 33 private const val MINIMIZE_ANIM_ALPHA_DURATION_MS = 100L 34 35 private val minimizeBoundsAnimationDef = 36 WindowAnimator.BoundsAnimationParams( 37 durationMs = 200, 38 endOffsetYDp = 12f, 39 endScale = 0.97f, 40 interpolator = Interpolators.STANDARD_ACCELERATE, 41 ) 42 43 /** 44 * Creates a minimize animator for given task [Change]. 45 * 46 * @param onAnimFinish finish-callback for the animation, note that this is called on the same 47 * thread as the animation itself. 48 * @param animationHandler the Handler that the animation is running on. 49 */ 50 @JvmStatic 51 fun create( 52 context: Context, 53 change: Change, 54 transaction: Transaction, 55 onAnimFinish: (Animator) -> Unit, 56 interactionJankMonitor: InteractionJankMonitor, 57 animationHandler: Handler, 58 ): Animator { 59 val boundsAnimator = WindowAnimator.createBoundsAnimator( 60 context.resources.displayMetrics, 61 minimizeBoundsAnimationDef, 62 change, 63 transaction, 64 ) 65 val alphaAnimator = ValueAnimator.ofFloat(1f, 0f).apply { 66 duration = MINIMIZE_ANIM_ALPHA_DURATION_MS 67 interpolator = Interpolators.LINEAR 68 addUpdateListener { animation -> 69 transaction 70 .setAlpha(change.leash, animation.animatedValue as Float) 71 .setFrameTimeline(Choreographer.getInstance().vsyncId) 72 .apply() 73 } 74 } 75 val listener = object : Animator.AnimatorListener { 76 override fun onAnimationStart(animator: Animator) { 77 interactionJankMonitor.begin( 78 change.leash, 79 context, 80 animationHandler, 81 CUJ_DESKTOP_MODE_MINIMIZE_WINDOW, 82 ) 83 } 84 override fun onAnimationCancel(animator: Animator) { 85 interactionJankMonitor.cancel(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW) 86 } 87 override fun onAnimationRepeat(animator: Animator) = Unit 88 override fun onAnimationEnd(animator: Animator) { 89 interactionJankMonitor.end(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW) 90 onAnimFinish(animator) 91 } 92 } 93 return AnimatorSet().apply { 94 playTogether(boundsAnimator, alphaAnimator) 95 addListener(listener) 96 } 97 } 98 } 99