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

Commit 6630d85d authored by chaviw's avatar chaviw Committed by Chavi Weingarten
Browse files

Allow WindowOrganizerController to handle DisplayAreas

The current code for WindowOrganizerController only allows transactions
to be submitted for Tasks. This change makes the request handing more
generic so it should allow for transactions to be submitted for all
WindwoContainers. However, we're limiting the requests to Tasks and
DisplayAreas to avoid any larger issues.

There are some transactions that will only work for Tasks so there
is a separate code path to handle Task specific transactions.

Test: WindowOrganizerTests
Bug: 152116619
Bug: 152114574
Change-Id: I916a8f0c92be490318ee45e09f6a5e8a4ee6ec62
parent 461f3809
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -438,7 +438,6 @@ class Task extends WindowContainer<WindowContainer> {
    static final int FLAG_FORCE_HIDDEN_FOR_TASK_ORG = 1 << 1;
    static final int FLAG_FORCE_HIDDEN_FOR_TASK_ORG = 1 << 1;
    private int mForceHiddenFlags = 0;
    private int mForceHiddenFlags = 0;



    SurfaceControl.Transaction mMainWindowSizeChangeTransaction;
    SurfaceControl.Transaction mMainWindowSizeChangeTransaction;


    private final FindRootHelper mFindRootHelper = new FindRootHelper();
    private final FindRootHelper mFindRootHelper = new FindRootHelper();
+41 −29
Original line number Original line Diff line number Diff line
@@ -186,12 +186,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        return syncId;
        return syncId;
    }
    }


    private int sanitizeAndApplyChange(WindowContainer container,
    private int applyChanges(WindowContainer container, WindowContainerTransaction.Change change) {
            WindowContainerTransaction.Change change) {
        if (!(container instanceof Task)) {
            throw new RuntimeException("Invalid token in task transaction");
        }
        final Task task = (Task) container;
        // The "client"-facing API should prevent bad changes; however, just in case, sanitize
        // The "client"-facing API should prevent bad changes; however, just in case, sanitize
        // masks here.
        // masks here.
        final int configMask = change.getConfigSetMask() & CONTROLLABLE_CONFIGS;
        final int configMask = change.getConfigSetMask() & CONTROLLABLE_CONFIGS;
@@ -211,11 +206,38 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
            }
            }
        }
        }
        if ((change.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) {

            if (task.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, change.getHidden())) {
        final int windowingMode = change.getWindowingMode();
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
        if (windowingMode > -1) {
            container.setWindowingMode(windowingMode);
        }
        return effects;
    }

    private int applyTaskChanges(Task tr, WindowContainerTransaction.Change c) {
        int effects = 0;
        final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();

        if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) {
            if (tr.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, c.getHidden())) {
                effects = TRANSACT_EFFECTS_LIFECYCLE;
            }
        }

        final int childWindowingMode = c.getActivityWindowingMode();
        if (childWindowingMode > -1) {
            tr.setActivityWindowingMode(childWindowingMode);
        }

        if (t != null) {
            tr.setMainWindowSizeChangeTransaction(t);
        }
        }

        Rect enterPipBounds = c.getEnterPipBounds();
        if (enterPipBounds != null) {
            mService.mStackSupervisor.updatePictureInPictureMode(tr, enterPipBounds, true);
        }
        }

        return effects;
        return effects;
    }
    }


@@ -283,30 +305,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        return TRANSACT_EFFECTS_LIFECYCLE;
        return TRANSACT_EFFECTS_LIFECYCLE;
    }
    }


    private void sanitizeWindowContainer(WindowContainer wc) {
        if (!(wc instanceof Task) && !(wc instanceof DisplayArea)) {
            throw new RuntimeException("Invalid token in task or displayArea transaction");
        }
    }

    private int applyWindowContainerChange(WindowContainer wc,
    private int applyWindowContainerChange(WindowContainer wc,
            WindowContainerTransaction.Change c) {
            WindowContainerTransaction.Change c) {
        int effects = sanitizeAndApplyChange(wc, c);
        sanitizeWindowContainer(wc);


        final Task tr = wc.asTask();
        int effects = applyChanges(wc, c);


        final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();
        if (wc instanceof Task) {
        if (t != null) {
            effects |= applyTaskChanges(wc.asTask(), c);
            tr.setMainWindowSizeChangeTransaction(t);
        }

        Rect enterPipBounds = c.getEnterPipBounds();
        if (enterPipBounds != null) {
            mService.mStackSupervisor.updatePictureInPictureMode(tr,
                    enterPipBounds, true);
        }

        final int windowingMode = c.getWindowingMode();
        if (windowingMode > -1) {
            tr.setWindowingMode(windowingMode);
        }
        final int childWindowingMode = c.getActivityWindowingMode();
        if (childWindowingMode > -1) {
            tr.setActivityWindowingMode(childWindowingMode);
        }
        }


        return effects;
        return effects;
+41 −27
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowContainer.POSITION_TOP;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
@@ -70,7 +71,6 @@ import android.window.WindowContainerTransaction;


import androidx.test.filters.SmallTest;
import androidx.test.filters.SmallTest;


import org.junit.After;
import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
@@ -87,7 +87,7 @@ import java.util.List;
@SmallTest
@SmallTest
@Presubmit
@Presubmit
@RunWith(WindowTestRunner.class)
@RunWith(WindowTestRunner.class)
public class TaskOrganizerTests extends WindowTestsBase {
public class WindowOrganizerTests extends WindowTestsBase {
    private ITaskOrganizer registerMockOrganizer(int windowingMode) {
    private ITaskOrganizer registerMockOrganizer(int windowingMode) {
        final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
        final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
        when(organizer.asBinder()).thenReturn(new Binder());
        when(organizer.asBinder()).thenReturn(new Binder());
@@ -307,11 +307,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
        final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
        final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
        final Task task = stack.getTopMostTask();
        final Task task = stack.getTopMostTask();
        WindowContainerTransaction t = new WindowContainerTransaction();
        testTransaction(task);
        Rect newBounds = new Rect(10, 10, 100, 100);
        t.setBounds(task.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 100, 100));
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        assertEquals(newBounds, task.getBounds());
    }
    }


    @Test
    @Test
@@ -321,24 +317,41 @@ public class TaskOrganizerTests extends WindowTestsBase {
                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
        StackInfo info =
        StackInfo info =
                mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
                mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
        WindowContainerTransaction t = new WindowContainerTransaction();
        assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.stackToken);
        assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.stackToken);
        testTransaction(stack);
    }

    @Test
    public void testDisplayAreaTransaction() {
        removeGlobalMinSizeRestriction();
        final DisplayArea displayArea = new DisplayArea<>(mWm, ABOVE_TASKS, "DisplayArea");
        testTransaction(displayArea);
    }

    private void testTransaction(WindowContainer wc) {
        WindowContainerTransaction t = new WindowContainerTransaction();
        Rect newBounds = new Rect(10, 10, 100, 100);
        Rect newBounds = new Rect(10, 10, 100, 100);
        t.setBounds(info.stackToken, new Rect(10, 10, 100, 100));
        t.setBounds(wc.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 100, 100));
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        assertEquals(newBounds, stack.getBounds());
        assertEquals(newBounds, wc.getBounds());
    }
    }


    @Test
    @Test
    public void testSetWindowingMode() {
    public void testSetWindowingMode() {
        final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
        final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
        final WindowContainerTransaction t = new WindowContainerTransaction();
        testSetWindowingMode(stack);


        t.setWindowingMode(stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_FULLSCREEN);
        final DisplayArea displayArea = new DisplayArea<>(mWm, ABOVE_TASKS, "DisplayArea");
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        displayArea.setWindowingMode(WINDOWING_MODE_FREEFORM);
        testSetWindowingMode(displayArea);
    }


        assertEquals(WINDOWING_MODE_FULLSCREEN, stack.getWindowingMode());
    private void testSetWindowingMode(WindowContainer wc) {
        final WindowContainerTransaction t = new WindowContainerTransaction();
        t.setWindowingMode(wc.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_FULLSCREEN);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        assertEquals(WINDOWING_MODE_FULLSCREEN, wc.getWindowingMode());
    }
    }


    @Test
    @Test
@@ -400,7 +413,8 @@ public class TaskOrganizerTests extends WindowTestsBase {
        final int origScreenHDp = task.getConfiguration().screenHeightDp;
        final int origScreenHDp = task.getConfiguration().screenHeightDp;
        t = new WindowContainerTransaction();
        t = new WindowContainerTransaction();
        // verify that setting config overrides on parent restricts children.
        // verify that setting config overrides on parent restricts children.
        t.setScreenSizeDp(stack.mRemoteToken.toWindowContainerToken(), origScreenWDp, origScreenHDp);
        t.setScreenSizeDp(stack.mRemoteToken
                .toWindowContainerToken(), origScreenWDp, origScreenHDp);
        t.setBounds(task.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 150, 200));
        t.setBounds(task.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 150, 200));
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
        assertEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
        assertEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
@@ -817,8 +831,8 @@ public class TaskOrganizerTests extends WindowTestsBase {
        mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, WINDOWING_MODE_PINNED);
        mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, WINDOWING_MODE_PINNED);
        final ActivityRecord record = makePipableActivity();
        final ActivityRecord record = makePipableActivity();


        final PictureInPictureParams p =
        final PictureInPictureParams p = new PictureInPictureParams.Builder()
            new PictureInPictureParams.Builder().setAspectRatio(new Rational(1, 2)).build();
                .setAspectRatio(new Rational(1, 2)).build();
        assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
        assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
        waitUntilHandlersIdle();
        waitUntilHandlersIdle();
        assertNotNull(o.mInfo);
        assertNotNull(o.mInfo);
@@ -838,15 +852,15 @@ public class TaskOrganizerTests extends WindowTestsBase {
        mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, WINDOWING_MODE_PINNED);
        mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, WINDOWING_MODE_PINNED);


        final ActivityRecord record = makePipableActivity();
        final ActivityRecord record = makePipableActivity();
        final PictureInPictureParams p =
        final PictureInPictureParams p = new PictureInPictureParams.Builder()
            new PictureInPictureParams.Builder().setAspectRatio(new Rational(1, 2)).build();
                .setAspectRatio(new Rational(1, 2)).build();
        assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
        assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
        waitUntilHandlersIdle();
        waitUntilHandlersIdle();
        assertNotNull(o.mInfo);
        assertNotNull(o.mInfo);
        assertNotNull(o.mInfo.pictureInPictureParams);
        assertNotNull(o.mInfo.pictureInPictureParams);


        final PictureInPictureParams p2 =
        final PictureInPictureParams p2 = new PictureInPictureParams.Builder()
            new PictureInPictureParams.Builder().setAspectRatio(new Rational(3, 4)).build();
                .setAspectRatio(new Rational(3, 4)).build();
        mWm.mAtmService.setPictureInPictureParams(record.token, p2);
        mWm.mAtmService.setPictureInPictureParams(record.token, p2);
        waitUntilHandlersIdle();
        waitUntilHandlersIdle();
        assertNotNull(o.mChangedInfo);
        assertNotNull(o.mChangedInfo);