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

Commit 84eea84a authored by Omar Elmekkawy's avatar Omar Elmekkawy
Browse files

Add fade in animation to tiling divider to make it look nicer upon tiling.

This CL adds a fade in animation of 300 ms, upon snap resizing left/right,
the divider won't appear instantly, but will start fading it after the
tiled app reaches it's destination.

Flag: com.android.window.flags.enable_tile_resizing

Test: on device testing of UI, really hard to unit test the UI here.

Bug: 379663061
Change-Id: I3cccd3f32ae019ba7e6cdbe9f1f08b95d8c22e00
parent a458b252
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ class ToggleResizeDesktopTaskTransitionHandler(

    private var boundsAnimator: Animator? = null
    private var initialBounds: Rect? = null
    private var callback: (() -> Unit)? = null

    constructor(
        transitions: Transitions,
@@ -61,9 +62,14 @@ class ToggleResizeDesktopTaskTransitionHandler(
     *   bounds of the actual task). This is provided so that the animation resizing can begin where
     *   the task leash currently is for smoother UX.
     */
    fun startTransition(wct: WindowContainerTransaction, taskLeashBounds: Rect? = null) {
    fun startTransition(
        wct: WindowContainerTransaction,
        taskLeashBounds: Rect? = null,
        callback: (() -> Unit)? = null,
    ) {
        transitions.startTransition(TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE, wct, this)
        initialBounds = taskLeashBounds
        this.callback = callback
    }

    fun setOnTaskResizeAnimationListener(listener: OnTaskResizeAnimationListener) {
@@ -121,6 +127,8 @@ class ToggleResizeDesktopTaskTransitionHandler(
                            interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW)
                            interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW)
                            interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE)
                            callback?.invoke()
                            callback = null
                        },
                    )
                    addUpdateListener { anim ->
+38 −14
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.wm.shell.windowdecor.tiling

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.Configuration
import android.graphics.Path
@@ -144,7 +147,6 @@ class DesktopTilingDividerWindowManager(
     * @param relativeLeash the task leash that the TilingDividerView should be shown on top of.
     */
    fun generateViewHost(relativeLeash: SurfaceControl) {
        val t = transactionSupplier.get()
        val surfaceControlViewHost =
            SurfaceControlViewHost(context, context.display, this, "DesktopTilingManager")
        val dividerView =
@@ -155,22 +157,40 @@ class DesktopTilingDividerWindowManager(
        val tmpDividerBounds = Rect()
        getDividerBounds(tmpDividerBounds)
        dividerView.setup(this, tmpDividerBounds, handleRegionSize, isDarkMode)
        t.setRelativeLayer(leash, relativeLeash, 1)
        val dividerAnimatorT = transactionSupplier.get()
        val dividerAnimator =
            ValueAnimator.ofFloat(0f, 1f).apply {
                duration = DIVIDER_FADE_IN_ALPHA_DURATION
                addUpdateListener {
                    dividerAnimatorT.setAlpha(leash, animatedValue as Float).apply()
                }
                addListener(
                    object : AnimatorListenerAdapter() {
                        override fun onAnimationStart(animation: Animator) {
                            dividerAnimatorT
                                .setRelativeLayer(leash, relativeLeash, 1)
                                .setPosition(
                                    leash,
                                    dividerBounds.left.toFloat() - maxRoundedCornerRadius,
                                    dividerBounds.top.toFloat(),
                                )
                                .setAlpha(leash, 0f)
                                .show(leash)
        syncQueue.runInSync { transaction ->
            transaction.merge(t)
            t.close()
                                .apply()
                        }

                        override fun onAnimationEnd(animation: Animator) {
                            dividerAnimatorT.setAlpha(leash, 1f).apply()
                            dividerShown = true
                        }
                    }
                )
            }
        dividerAnimator.start()
        viewHost = surfaceControlViewHost
        dividerView.addOnLayoutChangeListener(this)
        tilingDividerView = dividerView
        updateTouchRegion()
        dividerView.addOnLayoutChangeListener(this)
    }

    /** Changes divider colour if dark/light mode is toggled. */
@@ -311,4 +331,8 @@ class DesktopTilingDividerWindowManager(
            )
            .maxOf { position -> display.getRoundedCorner(position)?.getRadius() ?: 0 }
    }

    companion object {
        private const val DIVIDER_FADE_IN_ALPHA_DURATION = 300L
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -133,10 +133,10 @@ class DesktopTilingWindowDecoration(
        isDarkMode = isTaskInDarkMode(taskInfo)
        // Observe drag resizing to break tiling if a task is drag resized.
        desktopModeWindowDecoration.addDragResizeListener(this)

        val callback = { initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp) }
        if (isTiled) {
            val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
            toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds)
            toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds, callback)
        } else {
            // Handle the case where we attempt to snap resize when already snap resized: the task
            // position won't need to change but we want to animate the surface going back to the
@@ -147,10 +147,10 @@ class DesktopTilingWindowDecoration(
                    resizeMetadata.getLeash(),
                    startBounds = currentBounds,
                    endBounds = destinationBounds,
                    callback,
                )
            }
        }
        initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp)
        return isTiled
    }

+5 −5
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
            SCREEN_ORIENTATION_LANDSCAPE,
        )

        verify(resizeTransitionHandler, never()).startTransition(any(), any())
        verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
    }

    @Test
@@ -209,7 +209,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
            SCREEN_ORIENTATION_LANDSCAPE,
        )

        verify(resizeTransitionHandler, never()).startTransition(any(), any())
        verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
    }

    @Test
@@ -225,7 +225,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {

        handler.handleActivityOrientationChange(task, newTask)

        verify(resizeTransitionHandler, never()).startTransition(any(), any())
        verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
    }

    @Test
@@ -240,7 +240,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
            SCREEN_ORIENTATION_LANDSCAPE,
        )

        verify(resizeTransitionHandler, never()).startTransition(any(), any())
        verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
    }

    @Test
@@ -318,7 +318,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
        val arg: ArgumentCaptor<WindowContainerTransaction> =
            ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
        verify(resizeTransitionHandler, atLeastOnce())
            .startTransition(capture(arg), eq(currentBounds))
            .startTransition(capture(arg), eq(currentBounds), isNull())
        return arg.value
    }

+7 −4
Original line number Diff line number Diff line
@@ -5146,7 +5146,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
        )

        // Assert that task is NOT updated via WCT
        verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
        verify(toggleResizeDesktopTaskTransitionHandler, never())
            .startTransition(any(), any(), any())
        // Assert that task leash is updated via Surface Animations
        verify(mReturnToDragStartAnimator)
            .start(
@@ -5631,7 +5632,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            InputMethod.TOUCH,
        )
        // Assert that task is NOT updated via WCT
        verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
        verify(toggleResizeDesktopTaskTransitionHandler, never())
            .startTransition(any(), any(), any())

        // Assert that task leash is updated via Surface Animations
        verify(mReturnToDragStartAnimator)
@@ -5728,7 +5730,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
        )

        // Assert that task is NOT updated via WCT
        verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
        verify(toggleResizeDesktopTaskTransitionHandler, never())
            .startTransition(any(), any(), any())
        verify(mockToast).show()
    }

@@ -6778,7 +6781,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
    ): WindowContainerTransaction {
        val arg = argumentCaptor<WindowContainerTransaction>()
        verify(toggleResizeDesktopTaskTransitionHandler, atLeastOnce())
            .startTransition(arg.capture(), eq(currentBounds))
            .startTransition(arg.capture(), eq(currentBounds), isNull())
        return arg.lastValue
    }

Loading