Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 269cab6f authored by Johannes Gallmann's avatar Johannes Gallmann
Browse files

Improve predictive custom cross activity back animation

This changes the behaviour of custom cross-activity back animations. Until now, app-provided custom xml animations were seeked from 0 to 100% for the predictive back animation. With this CL this changes such that the system takes control over the precommit phase whereas the app-provided xml spec is applied to the post-commit animation:
1. The closing activity is scaled during pre-commit (exactly the same as in the default cross-activity-back-animation)
2. A scrim is added on top of the opening activity
3. The closing activity plays custom animation during post commit
4. The opening activity seeks custom animation to max 20% during pre-commit
5. The opening activity plays the remaining % of the custom animation during post-commit

Bug: 339440390
Flag: com.android.window.flags.predictive_back_system_anims
Test: atest CustomCrossActivityBackAnimationTest
Test: Manual, i.e. testing xml  specified cross activity back animations manually in a test app
Change-Id: Iefa1ce9a0169d0cab16deab196e4afa464b44b4e
parent c78496f9
Loading
Loading
Loading
Loading
+169 −127
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell.back

import android.animation.Animator
@@ -34,6 +35,7 @@ import android.view.RemoteAnimationTarget
import android.view.SurfaceControl
import android.view.animation.DecelerateInterpolator
import android.view.animation.Interpolator
import android.view.animation.Transformation
import android.window.BackEvent
import android.window.BackMotionEvent
import android.window.BackNavigationInfo
@@ -46,52 +48,45 @@ import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.animation.Interpolators
import com.android.wm.shell.protolog.ShellProtoLogGroup
import com.android.wm.shell.shared.annotations.ShellMainThread
import javax.inject.Inject
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

/** Class that defines cross-activity animation.  */
@ShellMainThread
class CrossActivityBackAnimation @Inject constructor(
abstract class CrossActivityBackAnimation(
    private val context: Context,
    private val background: BackAnimationBackground,
    private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
    private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    protected val transaction: SurfaceControl.Transaction,
    private val choreographer: Choreographer
) : ShellBackAnimation() {

    private val startClosingRect = RectF()
    private val targetClosingRect = RectF()
    private val currentClosingRect = RectF()
    protected val startClosingRect = RectF()
    protected val targetClosingRect = RectF()
    protected val currentClosingRect = RectF()

    private val startEnteringRect = RectF()
    private val targetEnteringRect = RectF()
    private val currentEnteringRect = RectF()
    protected val startEnteringRect = RectF()
    protected val targetEnteringRect = RectF()
    protected val currentEnteringRect = RectF()

    private val backAnimRect = Rect()
    protected val backAnimRect = Rect()
    private val cropRect = Rect()

    private var cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)

    private val backAnimationRunner = BackAnimationRunner(
        Callback(), Runner(), context, Cuj.CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY
    )
    private val backAnimationRunner =
        BackAnimationRunner(Callback(), Runner(), context, Cuj.CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY)
    private val initialTouchPos = PointF()
    private val transformMatrix = Matrix()
    private val tmpFloat9 = FloatArray(9)
    private var enteringTarget: RemoteAnimationTarget? = null
    private var closingTarget: RemoteAnimationTarget? = null
    private val transaction = SurfaceControl.Transaction()
    protected var enteringTarget: RemoteAnimationTarget? = null
    protected var closingTarget: RemoteAnimationTarget? = null
    private var triggerBack = false
    private var finishCallback: IRemoteAnimationFinishedCallback? = null
    private val progressAnimator = BackProgressAnimator()
    private val displayBoundsMargin =
        context.resources.getDimension(R.dimen.cross_task_back_vertical_margin)
    private val enteringStartOffset =
        context.resources.getDimension(R.dimen.cross_activity_back_entering_start_offset)

    private val gestureInterpolator = Interpolators.BACK_GESTURE
    private val postCommitInterpolator = Interpolators.FAST_OUT_SLOW_IN
    private val verticalMoveInterpolator: Interpolator = DecelerateInterpolator()

    private var scrimLayer: SurfaceControl? = null
@@ -103,13 +98,42 @@ class CrossActivityBackAnimation @Inject constructor(
    private var rightLetterboxLayer: SurfaceControl? = null
    private var letterboxColor: Int = 0

    /** Background color to be used during the animation, also see [getBackgroundColor] */
    protected var customizedBackgroundColor = 0

    /**
     * Whether the entering target should be shifted vertically with the user gesture in pre-commit
     */
    abstract val allowEnteringYShift: Boolean

    /**
     * Subclasses must set the [startEnteringRect] and [targetEnteringRect] to define the movement
     * of the enteringTarget during pre-commit phase.
     */
    abstract fun preparePreCommitEnteringRectMovement()

    /**
     * Returns a base transformation to apply to the entering target during pre-commit. The system
     * will apply the default animation on top of it.
     */
    protected open fun getPreCommitEnteringBaseTransformation(progress: Float): Transformation? =
        null

    override fun onConfigurationChanged(newConfiguration: Configuration) {
        cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
    }

    override fun getRunner() = backAnimationRunner

    private fun startBackAnimation(backMotionEvent: BackMotionEvent) {
    private fun getBackgroundColor(): Int =
        when {
            customizedBackgroundColor != 0 -> customizedBackgroundColor
            isLetterboxed -> letterboxColor
            enteringTarget != null -> enteringTarget!!.taskInfo.taskDescription!!.backgroundColor
            else -> 0
        }

    protected open fun startBackAnimation(backMotionEvent: BackMotionEvent) {
        if (enteringTarget == null || closingTarget == null) {
            ProtoLog.d(
                ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW,
@@ -122,8 +146,8 @@ class CrossActivityBackAnimation @Inject constructor(

        transaction.setAnimationTransaction()
        isLetterboxed = closingTarget!!.taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed
        enteringHasSameLetterbox = isLetterboxed &&
                closingTarget!!.localBounds.equals(enteringTarget!!.localBounds)
        enteringHasSameLetterbox =
            isLetterboxed && closingTarget!!.localBounds.equals(enteringTarget!!.localBounds)

        if (isLetterboxed && !enteringHasSameLetterbox) {
            // Play animation with letterboxes, if closing and entering target have mismatching
@@ -143,32 +167,27 @@ class CrossActivityBackAnimation @Inject constructor(
        targetClosingRect.scaleCentered(MAX_SCALE)
        if (backMotionEvent.swipeEdge != BackEvent.EDGE_RIGHT) {
            targetClosingRect.offset(
                startClosingRect.right - targetClosingRect.right - displayBoundsMargin, 0f
                startClosingRect.right - targetClosingRect.right - displayBoundsMargin,
                0f
            )
        }

        // the entering target starts 96dp to the left of the screen edge...
        startEnteringRect.set(startClosingRect)
        startEnteringRect.offset(-enteringStartOffset, 0f)

        // ...and gets scaled in sync with the closing target
        targetEnteringRect.set(startEnteringRect)
        targetEnteringRect.scaleCentered(MAX_SCALE)
        preparePreCommitEnteringRectMovement()

        // Draw background with task background color (or letterbox color).
        val backgroundColor = if (isLetterboxed) {
            letterboxColor
        } else {
            enteringTarget!!.taskInfo.taskDescription!!.backgroundColor
        }
        background.ensureBackground(
            closingTarget!!.windowConfiguration.bounds, backgroundColor, transaction
            closingTarget!!.windowConfiguration.bounds,
            getBackgroundColor(),
            transaction
        )
        ensureScrimLayer()
        if (isLetterboxed && enteringHasSameLetterbox) {
            // crop left and right letterboxes
            cropRect.set(closingTarget!!.localBounds.left, 0, closingTarget!!.localBounds.right,
                    closingTarget!!.windowConfiguration.bounds.height())
            cropRect.set(
                closingTarget!!.localBounds.left,
                0,
                closingTarget!!.localBounds.right,
                closingTarget!!.windowConfiguration.bounds.height()
            )
            // and add fake letterbox square surfaces instead
            ensureLetterboxes()
        } else {
@@ -185,8 +204,14 @@ class CrossActivityBackAnimation @Inject constructor(
        currentClosingRect.offset(0f, yOffset)
        applyTransform(closingTarget?.leash, currentClosingRect, 1f)
        currentEnteringRect.setInterpolatedRectF(startEnteringRect, targetEnteringRect, progress)
        currentEnteringRect.offset(0f, yOffset)
        applyTransform(enteringTarget?.leash, currentEnteringRect, 1f)
        if (allowEnteringYShift) currentEnteringRect.offset(0f, yOffset)
        val enteringTransformation = getPreCommitEnteringBaseTransformation(progress)
        applyTransform(
            enteringTarget?.leash,
            currentEnteringRect,
            enteringTransformation?.alpha ?: 1f,
            enteringTransformation
        )
        applyTransaction()
    }

@@ -199,30 +224,25 @@ class CrossActivityBackAnimation @Inject constructor(
        val deltaYRatio = min(screenHeight / 2f, abs(rawYDelta)) / (screenHeight / 2f)
        val interpolatedYRatio: Float = verticalMoveInterpolator.getInterpolation(deltaYRatio)
        // limit y-shift so surface never passes 8dp screen margin
        val deltaY = yDirection * interpolatedYRatio * max(
            0f, (screenHeight - centeredRect.height()) / 2f - displayBoundsMargin
        )
        val deltaY =
            max(0f, (screenHeight - centeredRect.height()) / 2f - displayBoundsMargin) *
                interpolatedYRatio *
                yDirection
        return deltaY
    }

    private fun onGestureCommitted() {
        if (closingTarget?.leash == null || enteringTarget?.leash == null ||
                !enteringTarget!!.leash.isValid || !closingTarget!!.leash.isValid
    protected open fun onGestureCommitted() {
        if (
            closingTarget?.leash == null ||
                enteringTarget?.leash == null ||
                !enteringTarget!!.leash.isValid ||
                !closingTarget!!.leash.isValid
        ) {
            finishAnimation()
            return
        }

        // We enter phase 2 of the animation, the starting coordinates for phase 2 are the current
        // coordinate of the gesture driven phase. Let's update the start and target rects and kick
        // off the animator
        startClosingRect.set(currentClosingRect)
        startEnteringRect.set(currentEnteringRect)
        targetEnteringRect.set(backAnimRect)
        targetClosingRect.set(backAnimRect)
        targetClosingRect.offset(currentClosingRect.left + enteringStartOffset, 0f)

        val valueAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(POST_ANIMATION_DURATION)
        val valueAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(POST_COMMIT_DURATION)
        valueAnimator.addUpdateListener { animation: ValueAnimator ->
            val progress = animation.animatedFraction
            onPostCommitProgress(progress)
@@ -230,27 +250,22 @@ class CrossActivityBackAnimation @Inject constructor(
                background.resetStatusBarCustomization()
            }
        }
        valueAnimator.addListener(object : AnimatorListenerAdapter() {
        valueAnimator.addListener(
            object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    background.resetStatusBarCustomization()
                    finishAnimation()
                }
        })
            }
        )
        valueAnimator.start()
    }

    private fun onPostCommitProgress(linearProgress: Float) {
        val closingAlpha = max(1f - linearProgress * 2, 0f)
        val progress = postCommitInterpolator.getInterpolation(linearProgress)
    protected open fun onPostCommitProgress(linearProgress: Float) {
        scrimLayer?.let { transaction.setAlpha(it, maxScrimAlpha * (1f - linearProgress)) }
        currentClosingRect.setInterpolatedRectF(startClosingRect, targetClosingRect, progress)
        applyTransform(closingTarget?.leash, currentClosingRect, closingAlpha)
        currentEnteringRect.setInterpolatedRectF(startEnteringRect, targetEnteringRect, progress)
        applyTransform(enteringTarget?.leash, currentEnteringRect, 1f)
        applyTransaction()
    }

    private fun finishAnimation() {
    protected open fun finishAnimation() {
        enteringTarget?.let {
            if (it.leash != null && it.leash.isValid) {
                transaction.setCornerRadius(it.leash, 0f)
@@ -278,32 +293,40 @@ class CrossActivityBackAnimation @Inject constructor(
        enteringHasSameLetterbox = false
    }

    private fun applyTransform(leash: SurfaceControl?, rect: RectF, alpha: Float) {
    protected fun applyTransform(
        leash: SurfaceControl?,
        rect: RectF,
        alpha: Float,
        baseTransformation: Transformation? = null
    ) {
        if (leash == null || !leash.isValid) return
        val scale = rect.width() / backAnimRect.width()
        transformMatrix.reset()
        val scalePivotX = if (isLetterboxed && enteringHasSameLetterbox) {
        val matrix = baseTransformation?.matrix ?: transformMatrix.apply { reset() }
        val scalePivotX =
            if (isLetterboxed && enteringHasSameLetterbox) {
                closingTarget!!.localBounds.left.toFloat()
            } else {
                0f
            }
        transformMatrix.setScale(scale, scale, scalePivotX, 0f)
        transformMatrix.postTranslate(rect.left, rect.top)
        transaction.setAlpha(leash, alpha)
            .setMatrix(leash, transformMatrix, tmpFloat9)
        matrix.postScale(scale, scale, scalePivotX, 0f)
        matrix.postTranslate(rect.left, rect.top)
        transaction
            .setAlpha(leash, keepMinimumAlpha(alpha))
            .setMatrix(leash, matrix, tmpFloat9)
            .setCrop(leash, cropRect)
            .setCornerRadius(leash, cornerRadius)
    }

    private fun applyTransaction() {
        transaction.setFrameTimelineVsync(Choreographer.getInstance().vsyncId)
    protected fun applyTransaction() {
        transaction.setFrameTimelineVsync(choreographer.vsyncId)
        transaction.apply()
    }

    private fun ensureScrimLayer() {
        if (scrimLayer != null) return
        val isDarkTheme: Boolean = isDarkMode(context)
        val scrimBuilder = SurfaceControl.Builder()
        val scrimBuilder =
            SurfaceControl.Builder()
                .setName("Cross-Activity back animation scrim")
                .setCallsite("CrossActivityBackAnimation")
                .setColorLayer()
@@ -314,7 +337,8 @@ class CrossActivityBackAnimation @Inject constructor(
        scrimLayer = scrimBuilder.build()
        val colorComponents = floatArrayOf(0f, 0f, 0f)
        maxScrimAlpha = if (isDarkTheme) MAX_SCRIM_ALPHA_DARK else MAX_SCRIM_ALPHA_LIGHT
        val scrimCrop = if (isLetterboxed) {
        val scrimCrop =
            if (isLetterboxed) {
                closingTarget!!.windowConfiguration.bounds
            } else {
                closingTarget!!.localBounds
@@ -339,21 +363,34 @@ class CrossActivityBackAnimation @Inject constructor(
    private fun ensureLetterboxes() {
        closingTarget?.let { t ->
            if (t.localBounds.left != 0 && leftLetterboxLayer == null) {
                val bounds = Rect(0, t.windowConfiguration.bounds.top, t.localBounds.left,
                        t.windowConfiguration.bounds.bottom)
                val bounds =
                    Rect(
                        0,
                        t.windowConfiguration.bounds.top,
                        t.localBounds.left,
                        t.windowConfiguration.bounds.bottom
                    )
                leftLetterboxLayer = ensureLetterbox(bounds)
            }
            if (t.localBounds.right != t.windowConfiguration.bounds.right &&
                    rightLetterboxLayer == null) {
                val bounds = Rect(t.localBounds.right, t.windowConfiguration.bounds.top,
                        t.windowConfiguration.bounds.right, t.windowConfiguration.bounds.bottom)
            if (
                t.localBounds.right != t.windowConfiguration.bounds.right &&
                    rightLetterboxLayer == null
            ) {
                val bounds =
                    Rect(
                        t.localBounds.right,
                        t.windowConfiguration.bounds.top,
                        t.windowConfiguration.bounds.right,
                        t.windowConfiguration.bounds.bottom
                    )
                rightLetterboxLayer = ensureLetterbox(bounds)
            }
        }
    }

    private fun ensureLetterbox(bounds: Rect): SurfaceControl {
        val letterboxBuilder = SurfaceControl.Builder()
        val letterboxBuilder =
            SurfaceControl.Builder()
                .setName("Cross-Activity back animation letterbox")
                .setCallsite("CrossActivityBackAnimation")
                .setColorLayer()
@@ -362,8 +399,12 @@ class CrossActivityBackAnimation @Inject constructor(

        rootTaskDisplayAreaOrganizer.attachToDisplayArea(Display.DEFAULT_DISPLAY, letterboxBuilder)
        val layer = letterboxBuilder.build()
        val colorComponents = floatArrayOf(Color.red(letterboxColor) / 255f,
                Color.green(letterboxColor) / 255f, Color.blue(letterboxColor) / 255f)
        val colorComponents =
            floatArrayOf(
                Color.red(letterboxColor) / 255f,
                Color.green(letterboxColor) / 255f,
                Color.blue(letterboxColor) / 255f
            )
        transaction
            .setColor(layer, colorComponents)
            .setCrop(layer, bounds)
@@ -415,9 +456,7 @@ class CrossActivityBackAnimation @Inject constructor(
        }

        override fun onBackCancelled() {
            progressAnimator.onBackCancelled {
                finishAnimation()
            }
            progressAnimator.onBackCancelled { finishAnimation() }
        }

        override fun onBackInvoked() {
@@ -435,7 +474,8 @@ class CrossActivityBackAnimation @Inject constructor(
            finishedCallback: IRemoteAnimationFinishedCallback
        ) {
            ProtoLog.d(
                ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW, "Start back to activity animation."
                ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW,
                "Start back to activity animation."
            )
            for (a in apps) {
                when (a.mode) {
@@ -452,23 +492,25 @@ class CrossActivityBackAnimation @Inject constructor(
    }

    companion object {
        /** Max scale of the entering/closing window.*/
        private const val MAX_SCALE = 0.9f

        /** Duration of post animation after gesture committed.  */
        private const val POST_ANIMATION_DURATION = 300L

        /** Max scale of the closing window. */
        internal const val MAX_SCALE = 0.9f
        private const val MAX_SCRIM_ALPHA_DARK = 0.8f
        private const val MAX_SCRIM_ALPHA_LIGHT = 0.2f
        private const val POST_COMMIT_DURATION = 300L
    }
}

// The target will loose focus when alpha == 0, so keep a minimum value for it.
private fun keepMinimumAlpha(transAlpha: Float): Float {
    return max(transAlpha.toDouble(), 0.005).toFloat()
}

private fun isDarkMode(context: Context): Boolean {
    return context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
        Configuration.UI_MODE_NIGHT_YES
}

private fun RectF.setInterpolatedRectF(start: RectF, target: RectF, progress: Float) {
internal fun RectF.setInterpolatedRectF(start: RectF, target: RectF, progress: Float) {
    require(!(progress < 0 || progress > 1)) { "Progress value must be between 0 and 1" }
    left = start.left + (target.left - start.left) * progress
    top = start.top + (target.top - start.top) * progress
@@ -476,7 +518,7 @@ private fun RectF.setInterpolatedRectF(start: RectF, target: RectF, progress: Fl
    bottom = start.bottom + (target.bottom - start.bottom) * progress
}

private fun RectF.scaleCentered(
internal fun RectF.scaleCentered(
    scale: Float,
    pivotX: Float = left + width() / 2,
    pivotY: Float = top + height() / 2
+256 −0

File added.

Preview size limit exceeded, changes collapsed.

+0 −443

File deleted.

Preview size limit exceeded, changes collapsed.

+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.wm.shell.back

import android.content.Context
import android.view.Choreographer
import android.view.SurfaceControl
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.animation.Interpolators
import com.android.wm.shell.shared.annotations.ShellMainThread
import javax.inject.Inject
import kotlin.math.max

/** Class that defines cross-activity animation. */
@ShellMainThread
class DefaultCrossActivityBackAnimation
@Inject
constructor(
    context: Context,
    background: BackAnimationBackground,
    rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
) :
    CrossActivityBackAnimation(
        context,
        background,
        rootTaskDisplayAreaOrganizer,
        SurfaceControl.Transaction(),
        Choreographer.getInstance()
    ) {

    private val postCommitInterpolator = Interpolators.FAST_OUT_SLOW_IN
    private val enteringStartOffset =
        context.resources.getDimension(R.dimen.cross_activity_back_entering_start_offset)
    override val allowEnteringYShift = true

    override fun preparePreCommitEnteringRectMovement() {
        // the entering target starts 96dp to the left of the screen edge...
        startEnteringRect.set(startClosingRect)
        startEnteringRect.offset(-enteringStartOffset, 0f)
        // ...and gets scaled in sync with the closing target
        targetEnteringRect.set(startEnteringRect)
        targetEnteringRect.scaleCentered(MAX_SCALE)
    }

    override fun onGestureCommitted() {
        // We enter phase 2 of the animation, the starting coordinates for phase 2 are the current
        // coordinate of the gesture driven phase. Let's update the start and target rects and kick
        // off the animator in the superclass
        startClosingRect.set(currentClosingRect)
        startEnteringRect.set(currentEnteringRect)
        targetEnteringRect.set(backAnimRect)
        targetClosingRect.set(backAnimRect)
        targetClosingRect.offset(currentClosingRect.left + enteringStartOffset, 0f)
        super.onGestureCommitted()
    }

    override fun onPostCommitProgress(linearProgress: Float) {
        super.onPostCommitProgress(linearProgress)
        val closingAlpha = max(1f - linearProgress * 2, 0f)
        val progress = postCommitInterpolator.getInterpolation(linearProgress)
        currentClosingRect.setInterpolatedRectF(startClosingRect, targetClosingRect, progress)
        applyTransform(closingTarget?.leash, currentClosingRect, closingAlpha)
        currentEnteringRect.setInterpolatedRectF(startEnteringRect, targetEnteringRect, progress)
        applyTransform(enteringTarget?.leash, currentEnteringRect, 1f)
        applyTransaction()
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -16,9 +16,9 @@

package com.android.wm.shell.dagger.back;

import com.android.wm.shell.back.CrossActivityBackAnimation;
import com.android.wm.shell.back.CrossTaskBackAnimation;
import com.android.wm.shell.back.CustomizeActivityAnimation;
import com.android.wm.shell.back.CustomCrossActivityBackAnimation;
import com.android.wm.shell.back.DefaultCrossActivityBackAnimation;
import com.android.wm.shell.back.ShellBackAnimation;
import com.android.wm.shell.back.ShellBackAnimationRegistry;

@@ -47,7 +47,7 @@ public interface ShellBackAnimationModule {
    @Binds
    @ShellBackAnimation.CrossActivity
    ShellBackAnimation bindCrossActivityShellBackAnimation(
            CrossActivityBackAnimation crossActivityBackAnimation);
            DefaultCrossActivityBackAnimation defaultCrossActivityBackAnimation);

    /** Default cross task back animation */
    @Binds
@@ -59,5 +59,5 @@ public interface ShellBackAnimationModule {
    @Binds
    @ShellBackAnimation.CustomizeActivity
    ShellBackAnimation provideCustomizeActivityShellBackAnimation(
            CustomizeActivityAnimation customizeActivityAnimation);
            CustomCrossActivityBackAnimation customCrossActivityBackAnimation);
}
Loading