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

Commit 233a1fe1 authored by mattsziklay's avatar mattsziklay
Browse files

Update handle menu coordinates properly on rotate.

Changes AdditionalSystemViewContainer's setPosition to use
WindowManager's updateViewLayout to properly update LayoutParams.

Additionally, calculates global HandleMenu coordinates using more
variables from WindowDecoraiton.RelayoutResult to ensure correct
positioning on display rotation. Previously, task bounds were used which
may not have updated by the time the HandleMenu relayout occurred.

Bug: 341366352
Test: manual
Flag: EXEMPT bugfix
Change-Id: Ie1484dee5c517d7b5312e4190b3165eba06755b0
parent 44acf2ef
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -337,7 +337,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        }

        if (isHandleMenuActive()) {
            mHandleMenu.relayout(startT);
            mHandleMenu.relayout(startT, mResult.mCaptionX);
        }

        updateRelayoutParams(mRelayoutParams, mContext, taskInfo, applyStartTransactionOnDraw,
@@ -863,7 +863,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                splitScreenController,
                DesktopModeStatus.canEnterDesktopMode(mContext),
                browserLinkAvailable(),
                mResult.mCaptionHeight
                mResult.mCaptionWidth,
                mResult.mCaptionHeight,
                mResult.mCaptionX
        );
        mWindowDecorViewHolder.onHandleMenuOpened();
        mHandleMenu.show();
+16 −13
Original line number Diff line number Diff line
@@ -69,7 +69,9 @@ class HandleMenu(
    private val splitScreenController: SplitScreenController,
    private val shouldShowWindowingPill: Boolean,
    private val shouldShowBrowserPill: Boolean,
    private val captionHeight: Int
    private val captionWidth: Int,
    private val captionHeight: Int,
    captionX: Int
) {
    private val context: Context = parentDecor.mDecorWindowContext
    private val taskInfo: ActivityManager.RunningTaskInfo = parentDecor.mTaskInfo
@@ -105,7 +107,7 @@ class HandleMenu(
    private val globalMenuPosition: Point = Point()

    init {
        updateHandleMenuPillPositions()
        updateHandleMenuPillPositions(captionX)
    }

    fun show() {
@@ -262,11 +264,11 @@ class HandleMenu(
    /**
     * Updates handle menu's position variables to reflect its next position.
     */
    private fun updateHandleMenuPillPositions() {
    private fun updateHandleMenuPillPositions(captionX: Int) {
        val menuX: Int
        val menuY: Int
        val taskBounds = taskInfo.getConfiguration().windowConfiguration.bounds
        updateGlobalMenuPosition(taskBounds)
        updateGlobalMenuPosition(taskBounds, captionX)
        if (layoutResId == R.layout.desktop_mode_app_header) {
            // Align the handle menu to the left side of the caption.
            menuX = marginMenuStart
@@ -287,7 +289,8 @@ class HandleMenu(
        handleMenuPosition.set(menuX.toFloat(), menuY.toFloat())
    }

    private fun updateGlobalMenuPosition(taskBounds: Rect) {
    private fun updateGlobalMenuPosition(taskBounds: Rect, captionX: Int) {
        val nonFreeformX = captionX + (captionWidth / 2) - (menuWidth / 2)
        when {
            taskInfo.isFreeform -> {
                globalMenuPosition.set(
@@ -297,7 +300,7 @@ class HandleMenu(
            }
            taskInfo.isFullscreen -> {
                globalMenuPosition.set(
                    /* x = */ taskBounds.width() / 2 - (menuWidth / 2),
                    /* x = */ nonFreeformX,
                    /* y = */ marginMenuTop
                )
            }
@@ -311,16 +314,13 @@ class HandleMenu(
                when (splitPosition) {
                    SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT -> {
                        globalMenuPosition.set(
                            /* x = */ leftOrTopStageBounds.width()
                                    + (rightOrBottomStageBounds.width() / 2)
                                    - (menuWidth / 2),
                            /* x = */ leftOrTopStageBounds.width() + nonFreeformX,
                            /* y = */ marginMenuTop
                        )
                    }
                    SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT -> {
                        globalMenuPosition.set(
                            /* x = */ (leftOrTopStageBounds.width() / 2)
                                    - (menuWidth / 2),
                            /* x = */ nonFreeformX,
                            /* y = */ marginMenuTop
                        )
                    }
@@ -332,9 +332,12 @@ class HandleMenu(
    /**
     * Update pill layout, in case task changes have caused positioning to change.
     */
    fun relayout(t: SurfaceControl.Transaction) {
    fun relayout(
        t: SurfaceControl.Transaction,
        captionX: Int
    ) {
        handleMenuViewContainer?.let { container ->
            updateHandleMenuPillPositions()
            updateHandleMenuPillPositions(captionX)
            container.setPosition(t, handleMenuPosition.x, handleMenuPosition.y)
        }
    }
+4 −4
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ class AdditionalSystemViewContainer(
    height: Int
) : AdditionalViewContainer() {
    override val view: View
    val windowManager: WindowManager? = context.getSystemService(WindowManager::class.java)

    init {
        view = LayoutInflater.from(context).inflate(layoutId, null)
@@ -51,12 +52,11 @@ class AdditionalSystemViewContainer(
            gravity = Gravity.LEFT or Gravity.TOP
            setTrustedOverlay()
        }
        val wm: WindowManager? = context.getSystemService(WindowManager::class.java)
        wm?.addView(view, lp)
        windowManager?.addView(view, lp)
    }

    override fun releaseView() {
        context.getSystemService(WindowManager::class.java)?.removeViewImmediate(view)
        windowManager?.removeViewImmediate(view)
    }

    override fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float) {
@@ -64,6 +64,6 @@ class AdditionalSystemViewContainer(
            this.x = x.toInt()
            this.y = y.toInt()
        }
        view.layoutParams = lp
        windowManager?.updateViewLayout(view, lp)
    }
}
+22 −7
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ class HandleMenuTest : ShellTestCase() {
    @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
    fun testFullscreenMenuUsesSystemViewContainer() {
        createTaskInfo(WINDOWING_MODE_FULLSCREEN, SPLIT_POSITION_UNDEFINED)
        val handleMenu = createAndShowHandleMenu()
        val handleMenu = createAndShowHandleMenu(SPLIT_POSITION_UNDEFINED)
        assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
        // Verify menu is created at coordinates that, when added to WindowManager,
        // show at the top-center of display.
@@ -142,7 +142,7 @@ class HandleMenuTest : ShellTestCase() {
    @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
    fun testFreeformMenu_usesViewHostViewContainer() {
        createTaskInfo(WINDOWING_MODE_FREEFORM, SPLIT_POSITION_UNDEFINED)
        handleMenu = createAndShowHandleMenu()
        handleMenu = createAndShowHandleMenu(SPLIT_POSITION_UNDEFINED)
        assertTrue(handleMenu.handleMenuViewContainer is AdditionalViewHostViewContainer)
        // Verify menu is created near top-left of task.
        val expected = Point(MENU_START_MARGIN, MENU_TOP_MARGIN)
@@ -153,7 +153,7 @@ class HandleMenuTest : ShellTestCase() {
    @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
    fun testSplitLeftMenu_usesSystemViewContainer() {
        createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_TOP_OR_LEFT)
        handleMenu = createAndShowHandleMenu()
        handleMenu = createAndShowHandleMenu(SPLIT_POSITION_TOP_OR_LEFT)
        assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
        // Verify menu is created at coordinates that, when added to WindowManager,
        // show at the top-center of split left task.
@@ -168,7 +168,7 @@ class HandleMenuTest : ShellTestCase() {
    @EnableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
    fun testSplitRightMenu_usesSystemViewContainer() {
        createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_BOTTOM_OR_RIGHT)
        handleMenu = createAndShowHandleMenu()
        handleMenu = createAndShowHandleMenu(SPLIT_POSITION_BOTTOM_OR_RIGHT)
        assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
        // Verify menu is created at coordinates that, when added to WindowManager,
        // show at the top-center of split right task.
@@ -208,16 +208,30 @@ class HandleMenuTest : ShellTestCase() {
        }
    }

    private fun createAndShowHandleMenu(): HandleMenu {
    private fun createAndShowHandleMenu(splitPosition: Int): HandleMenu {
        val layoutId = if (mockDesktopWindowDecoration.mTaskInfo.isFreeform) {
            R.layout.desktop_mode_app_header
        } else {
            R.layout.desktop_mode_app_handle
        }
        val captionX = when (mockDesktopWindowDecoration.mTaskInfo.windowingMode) {
            WINDOWING_MODE_FULLSCREEN -> (DISPLAY_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
            WINDOWING_MODE_FREEFORM -> 0
            WINDOWING_MODE_MULTI_WINDOW -> {
                if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
                    (SPLIT_LEFT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
                } else {
                    (SPLIT_RIGHT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
                }
            }
            else -> error("Invalid windowing mode")
        }
        val handleMenu = HandleMenu(mockDesktopWindowDecoration, layoutId,
                onClickListener, onTouchListener, appIcon, appName, displayController,
                splitScreenController, true /* shouldShowWindowingPill */,
                true /* shouldShowBrowserPill */, 50 /* captionHeight */)
                splitScreenController, shouldShowWindowingPill = true,
                shouldShowBrowserPill = true, captionWidth = HANDLE_WIDTH, captionHeight = 50,
                captionX = captionX
        )
        handleMenu.show()
        return handleMenu
    }
@@ -233,5 +247,6 @@ class HandleMenuTest : ShellTestCase() {
        private const val MENU_START_MARGIN = 20
        private const val MENU_PILL_ELEVATION = 2
        private const val MENU_PILL_SPACING_MARGIN = 4
        private const val HANDLE_WIDTH = 80
    }
}