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

Commit 0edc1a4f authored by Eghosa Ewansiha-Vlachavas's avatar Eghosa Ewansiha-Vlachavas
Browse files

Respect window layout gravity while maintianing intial bounds

When an app specifies gravity, apply gravity to initial bounds instead of ignoring bounds.

Flag: EXEMPT bug fix
Test: atest DesktopTasksControllerTest
Fixes: 438407035
Change-Id: I4a1e94e39f8574d942ce17bf62ef8454a490451d
parent dd4a629a
Loading
Loading
Loading
Loading
+27 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import android.annotation.NonNull;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.Rect;
import android.view.Gravity;
import android.window.DesktopModeFlags;
import android.window.DesktopModeFlags;


/**
/**
@@ -52,6 +53,32 @@ public final class DesktopModeCompatUtils {
                    || info.isChangeEnabled(OVERRIDE_EXCLUDE_CAPTION_INSETS_FROM_APP_BOUNDS));
                    || info.isChangeEnabled(OVERRIDE_EXCLUDE_CAPTION_INSETS_FROM_APP_BOUNDS));
    }
    }


    /**
     * Applies a vertical and horizontal gravity on the inOutBounds in relation to the stableBounds.
     */
    public static void applyLayoutGravity(int verticalGravity, int horizontalGravity,
            @NonNull Rect inOutBounds, @NonNull Rect stableBounds) {
        final int width = inOutBounds.width();
        final int height = inOutBounds.height();

        final float fractionOfHorizontalOffset = switch (horizontalGravity) {
            case Gravity.LEFT -> 0f;
            case Gravity.RIGHT -> 1f;
            default -> 0.5f;
        };

        final float fractionOfVerticalOffset = switch (verticalGravity) {
            case Gravity.TOP -> 0f;
            case Gravity.BOTTOM -> 1f;
            default -> 0.5f;
        };

        inOutBounds.offsetTo(stableBounds.left, stableBounds.top);
        final int xOffset = (int) (fractionOfHorizontalOffset * (stableBounds.width() - width));
        final int yOffset = (int) (fractionOfVerticalOffset * (stableBounds.height() - height));
        inOutBounds.offset(xOffset, yOffset);
    }

    /**
    /**
     * Returns the orientation of the given {@code rect}.
     * Returns the orientation of the given {@code rect}.
     */
     */
+11 −9
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.graphics.Point
import android.graphics.Rect
import android.graphics.Rect
import android.view.Gravity
import android.view.Gravity
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.DesktopModeCompatUtils.applyLayoutGravity
import com.android.wm.shell.R
import com.android.wm.shell.R
import com.android.wm.shell.desktopmode.DesktopTaskPosition.BottomLeft
import com.android.wm.shell.desktopmode.DesktopTaskPosition.BottomLeft
import com.android.wm.shell.desktopmode.DesktopTaskPosition.BottomRight
import com.android.wm.shell.desktopmode.DesktopTaskPosition.BottomRight
@@ -81,18 +82,19 @@ sealed class DesktopTaskPosition {
    abstract fun next(): DesktopTaskPosition
    abstract fun next(): DesktopTaskPosition
}
}


/**
fun applyLayoutGravityIfNeeded(taskInfo: TaskInfo, bounds: Rect, stableBounds: Rect): Boolean {
 * If the app has specified horizontal or vertical gravity layout, don't change the task position
    var horizontalGravity = 0
 * for cascading effect.
    var verticalGravity = 0
 */
fun canChangeTaskPosition(taskInfo: TaskInfo): Boolean {
    taskInfo.topActivityInfo?.windowLayout?.let {
    taskInfo.topActivityInfo?.windowLayout?.let {
        val horizontalGravityApplied = it.gravity.and(Gravity.HORIZONTAL_GRAVITY_MASK)
        horizontalGravity = it.gravity.and(Gravity.HORIZONTAL_GRAVITY_MASK)
        val verticalGravityApplied = it.gravity.and(Gravity.VERTICAL_GRAVITY_MASK)
        verticalGravity = it.gravity.and(Gravity.VERTICAL_GRAVITY_MASK)
        return horizontalGravityApplied == 0 && verticalGravityApplied == 0
    }
    }
    if (verticalGravity > 0 || horizontalGravity > 0) {
        applyLayoutGravity(verticalGravity, horizontalGravity, bounds, stableBounds)
        return true
        return true
    }
    }
    return false
}


/** Returns the current DesktopTaskPosition for a given window in the frame. */
/** Returns the current DesktopTaskPosition for a given window in the frame. */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+9 −5
Original line number Original line Diff line number Diff line
@@ -4428,10 +4428,8 @@ class DesktopTasksController(
            wct.setBounds(task.token, inheritedTaskBounds)
            wct.setBounds(task.token, inheritedTaskBounds)
        } else {
        } else {
            val initialBounds = getInitialBounds(displayLayout, task, deskId)
            val initialBounds = getInitialBounds(displayLayout, task, deskId)
            if (canChangeTaskPosition(task)) {
            wct.setBounds(task.token, initialBounds)
            wct.setBounds(task.token, initialBounds)
        }
        }
        }
        if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
        if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
            desksOrganizer.moveTaskToDesk(wct = wct, deskId = deskId, task = task)
            desksOrganizer.moveTaskToDesk(wct = wct, deskId = deskId, task = task)
        } else {
        } else {
@@ -4520,8 +4518,14 @@ class DesktopTasksController(
            } else {
            } else {
                calculateDefaultDesktopTaskBounds(displayLayout)
                calculateDefaultDesktopTaskBounds(displayLayout)
            }
            }

        var hasLayoutGravityApplied = false
        if (DesktopModeFlags.ENABLE_CASCADING_WINDOWS.isTrue) {
        if (!repository.isActiveTask(taskInfo.taskId)) {
            // Only apply layout gravity to new tasks in desk.
            val stableBounds = Rect()
            displayLayout.getStableBoundsForDesktopMode(stableBounds)
            hasLayoutGravityApplied = applyLayoutGravityIfNeeded(taskInfo, bounds, stableBounds)
        }
        if (DesktopModeFlags.ENABLE_CASCADING_WINDOWS.isTrue && !hasLayoutGravityApplied) {
            cascadeWindow(
            cascadeWindow(
                context,
                context,
                recentTasksController,
                recentTasksController,
+12 −8
Original line number Original line Diff line number Diff line
@@ -1379,47 +1379,51 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
    }
    }


    @Test
    @Test
    fun addMoveToDeskTaskChanges_gravityLeft_noBoundsApplied() {
    fun addMoveToDeskTaskChanges_gravityLeft_gravityAppliedOnBounds() {
        setUpLandscapeDisplay()
        setUpLandscapeDisplay()
        val stableBounds = Rect().also { displayLayout.getStableBoundsForDesktopMode(it) }
        val task = setUpFullscreenTask(gravity = Gravity.LEFT)
        val task = setUpFullscreenTask(gravity = Gravity.LEFT)
        val wct = WindowContainerTransaction()
        val wct = WindowContainerTransaction()
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)


        val finalBounds = findBoundsChange(wct, task)
        val finalBounds = findBoundsChange(wct, task)
        assertThat(finalBounds).isNull()
        assertThat(finalBounds!!.left).isEqualTo(stableBounds.left)
    }
    }


    @Test
    @Test
    fun addMoveToDeskTaskChanges_gravityRight_noBoundsApplied() {
    fun addMoveToDeskTaskChanges_gravityRight_gravityAppliedOnBounds() {
        setUpLandscapeDisplay()
        setUpLandscapeDisplay()
        val stableBounds = Rect().also { displayLayout.getStableBoundsForDesktopMode(it) }
        val task = setUpFullscreenTask(gravity = Gravity.RIGHT)
        val task = setUpFullscreenTask(gravity = Gravity.RIGHT)
        val wct = WindowContainerTransaction()
        val wct = WindowContainerTransaction()
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)


        val finalBounds = findBoundsChange(wct, task)
        val finalBounds = findBoundsChange(wct, task)
        assertThat(finalBounds).isNull()
        assertThat(finalBounds!!.right).isEqualTo(stableBounds.right)
    }
    }


    @Test
    @Test
    fun addMoveToDeskTaskChanges_gravityTop_noBoundsApplied() {
    fun addMoveToDeskTaskChanges_gravityTop_gravityAppliedOnBounds() {
        setUpLandscapeDisplay()
        setUpLandscapeDisplay()
        val stableBounds = Rect().also { displayLayout.getStableBoundsForDesktopMode(it) }
        val task = setUpFullscreenTask(gravity = Gravity.TOP)
        val task = setUpFullscreenTask(gravity = Gravity.TOP)
        val wct = WindowContainerTransaction()
        val wct = WindowContainerTransaction()
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)


        val finalBounds = findBoundsChange(wct, task)
        val finalBounds = findBoundsChange(wct, task)
        assertThat(finalBounds).isNull()
        assertThat(finalBounds!!.top).isEqualTo(stableBounds.top)
    }
    }


    @Test
    @Test
    fun addMoveToDeskTaskChanges_gravityBottom_noBoundsApplied() {
    fun addMoveToDeskTaskChanges_gravityBottom_gravityAppliedOnBounds() {
        setUpLandscapeDisplay()
        setUpLandscapeDisplay()
        val stableBounds = Rect().also { displayLayout.getStableBoundsForDesktopMode(it) }
        val task = setUpFullscreenTask(gravity = Gravity.BOTTOM)
        val task = setUpFullscreenTask(gravity = Gravity.BOTTOM)
        val wct = WindowContainerTransaction()
        val wct = WindowContainerTransaction()
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)
        controller.addMoveToDeskTaskChanges(wct, task, deskId = 0)


        val finalBounds = findBoundsChange(wct, task)
        val finalBounds = findBoundsChange(wct, task)
        assertThat(finalBounds).isNull()
        assertThat(finalBounds!!.bottom).isEqualTo(stableBounds.bottom)
    }
    }


    @Test
    @Test