1 /* 2 * 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 package com.android.wm.shell.back 17 18 import android.content.Context 19 import android.os.Handler 20 import android.view.SurfaceControl 21 import android.window.BackEvent 22 import com.android.wm.shell.R 23 import com.android.wm.shell.RootTaskDisplayAreaOrganizer 24 import com.android.wm.shell.shared.animation.Interpolators 25 import com.android.wm.shell.shared.annotations.ShellMainThread 26 import javax.inject.Inject 27 import kotlin.math.max 28 29 /** Class that defines cross-activity animation. */ 30 class DefaultCrossActivityBackAnimation 31 @Inject 32 constructor( 33 context: Context, 34 background: BackAnimationBackground, 35 rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer, 36 @ShellMainThread handler: Handler, 37 ) : 38 CrossActivityBackAnimation( 39 context, 40 background, 41 rootTaskDisplayAreaOrganizer, 42 SurfaceControl.Transaction(), 43 handler 44 ) { 45 46 private val postCommitInterpolator = Interpolators.EMPHASIZED 47 private val enteringStartOffset = 48 context.resources.getDimension(R.dimen.cross_activity_back_entering_start_offset) 49 override val allowEnteringYShift = true 50 preparePreCommitClosingRectMovementnull51 override fun preparePreCommitClosingRectMovement(swipeEdge: Int) { 52 startClosingRect.set(backAnimRect) 53 54 // scale closing target into the middle for rhs and to the right for lhs 55 targetClosingRect.set(startClosingRect) 56 targetClosingRect.scaleCentered(MAX_SCALE) 57 if (swipeEdge != BackEvent.EDGE_RIGHT) { 58 targetClosingRect.offset( 59 startClosingRect.right - targetClosingRect.right - displayBoundsMargin, 60 0f 61 ) 62 } 63 } 64 preparePreCommitEnteringRectMovementnull65 override fun preparePreCommitEnteringRectMovement() { 66 // the entering target starts 96dp to the left of the screen edge... 67 startEnteringRect.set(startClosingRect) 68 startEnteringRect.offset(-enteringStartOffset, 0f) 69 // ...and gets scaled in sync with the closing target 70 targetEnteringRect.set(startEnteringRect) 71 targetEnteringRect.scaleCentered(MAX_SCALE) 72 } 73 getPostCommitAnimationDurationnull74 override fun getPostCommitAnimationDuration() = POST_COMMIT_DURATION 75 76 override fun onGestureCommitted(velocity: Float) { 77 // We enter phase 2 of the animation, the starting coordinates for phase 2 are the current 78 // coordinate of the gesture driven phase. Let's update the start and target rects and kick 79 // off the animator in the superclass 80 startClosingRect.set(currentClosingRect) 81 startEnteringRect.set(currentEnteringRect) 82 targetEnteringRect.set(backAnimRect) 83 targetClosingRect.set(backAnimRect) 84 targetClosingRect.offset(currentClosingRect.left + enteringStartOffset, 0f) 85 super.onGestureCommitted(velocity) 86 } 87 onPostCommitProgressnull88 override fun onPostCommitProgress(linearProgress: Float) { 89 super.onPostCommitProgress(linearProgress) 90 val closingAlpha = max(1f - linearProgress * 5, 0f) 91 val progress = postCommitInterpolator.getInterpolation(linearProgress) 92 currentClosingRect.setInterpolatedRectF(startClosingRect, targetClosingRect, progress) 93 applyTransform( 94 closingTarget?.leash, 95 currentClosingRect, 96 closingAlpha, 97 flingMode = FlingMode.FLING_BOUNCE 98 ) 99 currentEnteringRect.setInterpolatedRectF(startEnteringRect, targetEnteringRect, progress) 100 applyTransform( 101 enteringTarget?.leash, 102 currentEnteringRect, 103 1f, 104 flingMode = FlingMode.FLING_BOUNCE 105 ) 106 applyTransaction() 107 } 108 109 110 companion object { 111 private const val POST_COMMIT_DURATION = 450L 112 } 113 } 114