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

Commit 7bb86722 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Support Activity launches above the expandable

This CL adds support for activity launches where the opening window is
opening above the expandable surface.

Before this CL, we would automatically assume that the opening window
would be below the expandable surface, which is currently always the
case given that the animator is used only in the shade and status bar at
the moment (and those are above any app that we open).

After this CL, the ActivityLaunchAnimator has an additional parameter
for launches that happen above the expandable surface, which happen when
launching an Activity from a normal app or from a launcher.

Bug: 235576267
Test: Manual
Change-Id: I49c6095ffe52119d117af6c597463542b4630bbd
parent 4bc0c59a
Loading
Loading
Loading
Loading
+39 −5
Original line number Diff line number Diff line
@@ -332,6 +332,17 @@ class ActivityLaunchAnimator(
        val isDialogLaunch: Boolean
            get() = false

        /**
         * Whether the expandable controller by this [Controller] is below the launching window that
         * is going to be animated.
         *
         * This should be `false` when launching an app from the shade or status bar, given that
         * they are drawn above all apps. This is usually `true` when using this launcher in a
         * normal app or a launcher, that are drawn below the animating activity/window.
         */
        val isBelowAnimatingWindow: Boolean
            get() = false

        /**
         * The intent was started. If [willAnimate] is false, nothing else will happen and the
         * animation will not be started.
@@ -468,7 +479,7 @@ class ActivityLaunchAnimator(
            // We animate the opening window and delegate the view expansion to [this.controller].
            val delegate = this.controller
            val controller =
                object : LaunchAnimator.Controller by delegate {
                object : Controller by delegate {
                    override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
                        listeners.forEach { it.onLaunchAnimationStart() }
                        delegate.onLaunchAnimationStart(isExpandingFullyAbove)
@@ -488,7 +499,7 @@ class ActivityLaunchAnimator(
                        // Apply the state to the window only if it is visible, i.e. when the
                        // expanding view is *not* visible.
                        if (!state.visible) {
                            applyStateToWindow(window, state)
                            applyStateToWindow(window, state, linearProgress)
                        }
                        navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }

@@ -502,11 +513,16 @@ class ActivityLaunchAnimator(
                    controller,
                    endState,
                    windowBackgroundColor,
                    drawHole = true
                    fadeOutWindowBackgroundLayer = !controller.isBelowAnimatingWindow,
                    drawHole = !controller.isBelowAnimatingWindow,
                )
        }

        private fun applyStateToWindow(window: RemoteAnimationTarget, state: LaunchAnimator.State) {
        private fun applyStateToWindow(
            window: RemoteAnimationTarget,
            state: LaunchAnimator.State,
            linearProgress: Float,
        ) {
            if (transactionApplierView.viewRootImpl == null) {
                // If the view root we synchronize with was detached, don't apply any transaction
                // (as [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw).
@@ -548,6 +564,24 @@ class ActivityLaunchAnimator(
                windowCropF.bottom.roundToInt()
            )

            // The alpha of the opening window. If it opens above the expandable, then it should
            // fade in progressively. Otherwise, it should be fully opaque and will be progressively
            // revealed as the window background color layer above the window fades out.
            val alpha =
                if (controller.isBelowAnimatingWindow) {
                    val windowProgress =
                        LaunchAnimator.getProgress(
                            TIMINGS,
                            linearProgress,
                            TIMINGS.contentAfterFadeInDelay,
                            TIMINGS.contentAfterFadeInDuration
                        )

                    INTERPOLATORS.contentAfterFadeInInterpolator.getInterpolation(windowProgress)
                } else {
                    1f
                }

            // The scale will also be applied to the corner radius, so we divide by the scale to
            // keep the original radius. We use the max of (topCornerRadius, bottomCornerRadius) to
            // make sure that the window does not draw itself behind the expanding view. This is
@@ -556,7 +590,7 @@ class ActivityLaunchAnimator(
            val cornerRadius = maxOf(state.topCornerRadius, state.bottomCornerRadius) / scale
            val params =
                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(window.leash)
                    .withAlpha(1f)
                    .withAlpha(alpha)
                    .withMatrix(matrix)
                    .withWindowCrop(windowCrop)
                    .withCornerRadius(cornerRadius)
+12 −6
Original line number Diff line number Diff line
@@ -199,17 +199,19 @@ class LaunchAnimator(private val timings: Timings, private val interpolators: In

    /**
     * Start a launch animation controlled by [controller] towards [endState]. An intermediary layer
     * with [windowBackgroundColor] will fade in then fade out above the expanding view, and should
     * be the same background color as the opening (or closing) window. If [drawHole] is true, then
     * this intermediary layer will be drawn with SRC blending mode while it fades out.
     * with [windowBackgroundColor] will fade in then (optionally) fade out above the expanding
     * view, and should be the same background color as the opening (or closing) window.
     *
     * TODO(b/184121838): Remove [drawHole] and instead make the StatusBar draw this hole instead.
     * If [fadeOutWindowBackgroundLayer] is true, then this intermediary layer will fade out during
     * the second half of the animation, and will have SRC blending mode (ultimately punching a hole
     * in the [launch container][Controller.launchContainer]) iff [drawHole] is true.
     */
    fun startAnimation(
        controller: Controller,
        endState: State,
        windowBackgroundColor: Int,
        drawHole: Boolean = false
        fadeOutWindowBackgroundLayer: Boolean = true,
        drawHole: Boolean = false,
    ): Animation {
        val state = controller.createAnimatorState()

@@ -369,6 +371,7 @@ class LaunchAnimator(private val timings: Timings, private val interpolators: In
                state,
                linearProgress,
                container,
                fadeOutWindowBackgroundLayer,
                drawHole
            )
            controller.onLaunchAnimationProgress(state, progress, linearProgress)
@@ -397,6 +400,7 @@ class LaunchAnimator(private val timings: Timings, private val interpolators: In
        state: State,
        linearProgress: Float,
        launchContainer: View,
        fadeOutWindowBackgroundLayer: Boolean,
        drawHole: Boolean
    ) {
        // Update position.
@@ -432,7 +436,7 @@ class LaunchAnimator(private val timings: Timings, private val interpolators: In
            val alpha =
                interpolators.contentBeforeFadeOutInterpolator.getInterpolation(fadeInProgress)
            drawable.alpha = (alpha * 0xFF).roundToInt()
        } else {
        } else if (fadeOutWindowBackgroundLayer) {
            val fadeOutProgress =
                getProgress(
                    timings,
@@ -447,6 +451,8 @@ class LaunchAnimator(private val timings: Timings, private val interpolators: In
            if (drawHole) {
                drawable.setXfermode(SRC_MODE)
            }
        } else {
            drawable.alpha = 0xFF
        }
    }
}