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

Commit 67b5d6f6 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Sandboxing for non-resizable in multiwindow" into sc-dev

parents e2a4f531 d4c8686d
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -1219,12 +1219,6 @@
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DragState.java"
    },
    "-681380736": {
      "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing from mismatch with parent bounds? %s size compat mode %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "-677449371": {
      "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
      "level": "DEBUG",
@@ -2875,6 +2869,12 @@
      "group": "WM_DEBUG_BOOT",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "1237719089": {
      "message": "Sandbox max bounds for uid %s to bounds %s. letterboxing from mismatch with parent bounds = %s, has mCompatDisplayInsets = %s, should create compatDisplayInsets = %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "1246035185": {
      "message": "stopFreezingDisplayLocked: Returning waitingForConfig=%b, waitingForRemoteRotation=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d",
      "level": "DEBUG",
+33 −11
Original line number Diff line number Diff line
@@ -6954,18 +6954,27 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
        getResolvedOverrideConfiguration().seq = mConfigurationSeq;

        // Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in
        // size compat mode.
        // Sandbox max bounds by setting it to the activity bounds, if activity is letterboxed, or
        // has or will have mCompatDisplayInsets for size compat.
        if (providesMaxBounds()) {
            mTmpBounds.set(resolvedConfig.windowConfiguration.getBounds());
            if (mTmpBounds.isEmpty()) {
                // When there is no override bounds, the activity will inherit the bounds from
                // parent.
                mTmpBounds.set(newParentConfiguration.windowConfiguration.getBounds());
            }
            if (DEBUG_CONFIGURATION) {
                ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s "
                        + "due to letterboxing from mismatch with parent bounds? %s size compat "
                        + "mode %s", getUid(),
                        resolvedConfig.windowConfiguration.getBounds(), !matchParentBounds(),
                        inSizeCompatMode());
                ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s. "
                                + "letterboxing from mismatch with parent bounds = %s, "
                                + "has mCompatDisplayInsets = %s, "
                                + "should create compatDisplayInsets = %s",
                        getUid(),
                        mTmpBounds,
                        !matchParentBounds(),
                        mCompatDisplayInsets != null,
                        shouldCreateCompatDisplayInsets());
            }
            resolvedConfig.windowConfiguration
                    .setMaxBounds(resolvedConfig.windowConfiguration.getBounds());
            resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds);
        }
    }

@@ -7318,8 +7327,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            return false;
        }
        // Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
        // smaller than task bounds) or put in size compat mode.
        return !matchParentBounds() || inSizeCompatMode();
        // smaller than task bounds).
        if (!matchParentBounds()) {
            return true;
        }

        // Max bounds should be sandboxed when an activity should have compatDisplayInsets, and it
        // will keep the same bounds and screen configuration when it was first launched regardless
        // how its parent window changes, so that the sandbox API will provide a consistent result.
        if (mCompatDisplayInsets != null || shouldCreateCompatDisplayInsets()) {
            return true;
        }

        // No need to sandbox for resizable apps in multi-window because resizableActivity=true
        // indicates that they support multi-window.
        return false;
    }

    @VisibleForTesting
+56 −6
Original line number Diff line number Diff line
@@ -132,8 +132,8 @@ public class SizeCompatTests extends WindowTestsBase {
        mTask.setBounds(bounds);
        prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
        assertEquals(bounds, mActivity.getBounds());
        // Activity is not yet in size compat mode; it is filling the freeform window.
        assertMaxBoundsInheritDisplayAreaBounds();
        // Activity is not yet in size compat mode; it is filling the freeform task window.
        assertActivityMaxBoundsSandboxed();

        // The activity should be able to accept negative x position [-150, 100 - 150, 600].
        final int dx = bounds.left + bounds.width() / 2;
@@ -1388,7 +1388,7 @@ public class SizeCompatTests extends WindowTestsBase {
    }

    @Test
    public void testSupportsNonResizableInSplitScreen() {
    public void testSupportsNonResizableInSplitScreen_letterboxForDifferentOrientation() {
        // Support non resizable in multi window
        mAtm.mSupportsNonResizableMultiWindow = true;
        setUpDisplaySizeWithApp(1000, 2800);
@@ -1399,16 +1399,18 @@ public class SizeCompatTests extends WindowTestsBase {
        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
        final Rect originalBounds = new Rect(mActivity.getBounds());

        // Move activity to split screen
        // Move activity to split screen which takes half of the screen.
        mTask.reparent(organizer.mPrimary, POSITION_TOP,
                false /*moveParents*/, "test");
        organizer.mPrimary.setBounds(0, 0, 1000, 1400);
        assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mTask.getWindowingMode());
        assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mActivity.getWindowingMode());

        // Non-resizable activity in size compat mode
        assertScaled();
        assertEquals(originalBounds,
                mActivity.getConfiguration().windowConfiguration.getBounds());
        final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
        assertEquals(originalBounds.width(), newBounds.width());
        assertEquals(originalBounds.height(), newBounds.height());
        assertActivityMaxBoundsSandboxed();

        // Recompute the natural configuration of the non-resizable activity and the split screen.
@@ -1440,6 +1442,54 @@ public class SizeCompatTests extends WindowTestsBase {
                mActivity.getLetterboxInsets());
    }

    @Test
    public void testSupportsNonResizableInSplitScreen_fillTaskForSameOrientation() {
        // Support non resizable in multi window
        mAtm.mSupportsNonResizableMultiWindow = true;
        setUpDisplaySizeWithApp(1000, 2800);
        final TestSplitOrganizer organizer =
                new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());

        // Non-resizable portrait activity
        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
        final Rect originalBounds = new Rect(mActivity.getBounds());

        // Move activity to split screen which takes half of the screen.
        mTask.reparent(organizer.mPrimary, POSITION_TOP,
                false /*moveParents*/, "test");
        organizer.mPrimary.setBounds(0, 0, 1000, 1400);
        assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mTask.getWindowingMode());
        assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mActivity.getWindowingMode());

        // Non-resizable activity in size compat mode
        assertScaled();
        final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
        assertEquals(originalBounds.width(), newBounds.width());
        assertEquals(originalBounds.height(), newBounds.height());
        assertActivityMaxBoundsSandboxed();

        // Recompute the natural configuration of the non-resizable activity and the split screen.
        mActivity.clearSizeCompatMode();
        mActivity.setVisible(false);
        mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN);
        mActivity.mDisplayContent.mOpeningApps.add(mActivity);
        addWindowToActivity(mActivity);
        mActivity.mRootWindowContainer.performSurfacePlacement();

        // Split screen is also in portrait [1000,1400], which meets the activity request. It should
        // sandbox to the activity bounds for non-resizable.
        assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation);
        assertEquals(ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
        assertFitted();
        assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
        assertActivityMaxBoundsSandboxed();

        // Activity bounds fill split screen.
        final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds());
        final Rect letterboxedBounds = new Rect(mActivity.getBounds());
        assertEquals(primarySplitBounds, letterboxedBounds);
    }

    private static WindowState addWindowToActivity(ActivityRecord activity) {
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;