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

Commit b09f4089 authored by Chris Li's avatar Chris Li
Browse files

Have the top activity follow Task resizability

When a non-resizable activity is launched in a Task with resizable root
activity, it should follow the Task resizability.

Fix: 205062005
Test: manually with a test app
Test: atest WmTests:SizeCompatTests
Change-Id: I92fa2dd2a03f4edd336e0752194d9194dae5fc74
parent 8f7d2534
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -2724,7 +2724,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (windowingMode == WINDOWING_MODE_PINNED && info.supportsPictureInPicture()) {
            return false;
        }
        if (WindowConfiguration.inMultiWindowMode(windowingMode) && supportsMultiWindow()
        // Activity should be resizable if the task is.
        final boolean supportsMultiWindow = task != null
                ? task.supportsMultiWindow() || supportsMultiWindow()
                : supportsMultiWindow();
        if (WindowConfiguration.inMultiWindowMode(windowingMode) && supportsMultiWindow
                && !mAtmService.mForceResizableActivities) {
            // The non resizable app will be letterboxed instead of being forced resizable.
            return false;
@@ -7287,7 +7291,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                return false;
            }
        }
        return !isResizeable() && (info.isFixedOrientation() || hasFixedAspectRatio())
        // Activity should be resizable if the task is.
        final boolean isResizeable = task != null
                ? task.isResizeable() || isResizeable()
                : isResizeable();
        return !isResizeable && (info.isFixedOrientation() || hasFixedAspectRatio())
                // The configuration of non-standard type should be enforced by system.
                // {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} is set when this activity is
                // added to a task, but this function is called when resolving the launch params, at
@@ -7657,7 +7665,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            // orientation with insets applied.
            return;
        }
        if (WindowConfiguration.inMultiWindowMode(windowingMode) && isResizeable()) {
        // Activity should be resizable if the task is.
        final boolean isResizeable = task != null
                ? task.isResizeable() || isResizeable()
                : isResizeable();
        if (WindowConfiguration.inMultiWindowMode(windowingMode) && isResizeable) {
            // Ignore orientation request for resizable apps in multi window.
            return;
        }
+13 −9
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.server.wm;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
@@ -100,7 +102,6 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;

import android.app.ActivityOptions;
import android.app.WindowConfiguration;
import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.DestroyActivityItem;
@@ -560,7 +561,7 @@ public class ActivityRecordTests extends WindowTestsBase {
        final ActivityRecord activity = createActivityWith2LevelTask();
        final Task task = activity.getTask();
        final Task rootTask = activity.getRootTask();
        rootTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
        rootTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
        final Rect stableRect = new Rect();
        rootTask.mDisplayContent.getStableRect(stableRect);

@@ -602,19 +603,22 @@ public class ActivityRecordTests extends WindowTestsBase {

    @Test
    public void respectRequestedOrientationForNonResizableInSplitWindows() {
        final Task task = new TaskBuilder(mSupervisor)
                .setCreateParentTask(true).setCreateActivity(true).build();
        final Task rootTask = task.getRootTask();
        final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
        spyOn(tda);
        doReturn(true).when(tda).supportsNonResizableMultiWindow();
        final Task rootTask = mDisplayContent.getDefaultTaskDisplayArea().createRootTask(
                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
        rootTask.setBounds(0, 0, 1000, 500);
        final ActivityRecord activity = new ActivityBuilder(mAtm)
                .setParentTask(task)
                .setParentTask(rootTask)
                .setCreateTask(true)
                .setOnTop(true)
                .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
                .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
                .build();
        final Task task = activity.getTask();

        // Task in landscape.
        rootTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
        task.setBounds(0, 0, 1000, 500);
        assertEquals(ORIENTATION_LANDSCAPE, task.getConfiguration().orientation);

        // Asserts fixed orientation request is respected, and the orientation is not changed.
@@ -623,7 +627,7 @@ public class ActivityRecordTests extends WindowTestsBase {
        // Clear size compat.
        activity.clearSizeCompatMode();
        activity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
        activity.mDisplayContent.sendNewConfiguration();
        mDisplayContent.sendNewConfiguration();

        // Relaunching the app should still respect the orientation request.
        assertEquals(ORIENTATION_PORTRAIT, activity.getConfiguration().orientation);
+9 −43
Original line number Diff line number Diff line
@@ -157,46 +157,6 @@ public class SizeCompatTests extends WindowTestsBase {
        assertNotEquals(originalOverrideBounds, mActivity.getBounds());
    }

    @Test
    public void testKeepBoundsWhenChangingFromFreeformToFullscreen() {
        removeGlobalMinSizeRestriction();
        // Create landscape freeform display and a freeform app.
        DisplayContent display = new TestDisplayContent.Builder(mAtm, 2000, 1000)
                .setCanRotate(false)
                .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM).build();
        setUpApp(display);

        // Put app window into portrait freeform and then make it a compat app.
        final Rect bounds = new Rect(100, 100, 400, 600);
        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 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;
        final int dy = bounds.top + bounds.height() / 2;
        mTask.setBounds(bounds.left - dx, bounds.top - dy, bounds.right - dx, bounds.bottom - dy);
        // expected:<Rect(-150, 100 - 150, 600)> but was:<Rect(-150, 0 - 150, 500)>
        assertEquals(mTask.getBounds(), mActivity.getBounds());

        final int density = mActivity.getConfiguration().densityDpi;

        // Change display configuration to fullscreen.
        Configuration c = new Configuration(display.getRequestedOverrideConfiguration());
        c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
        display.onRequestedOverrideConfigurationChanged(c);

        // Check if dimensions on screen stay the same by scaling.
        assertScaled();
        assertEquals(bounds.width(), mActivity.getBounds().width());
        assertEquals(bounds.height(), mActivity.getBounds().height());
        assertEquals(density, mActivity.getConfiguration().densityDpi);
        // Size compat mode is sandboxed at the activity level.
        assertActivityMaxBoundsSandboxed();
    }

    @Test
    public void testFixedAspectRatioBoundsWithDecorInSquareDisplay() {
        final int notchHeight = 100;
@@ -687,7 +647,7 @@ public class SizeCompatTests extends WindowTestsBase {
                .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
                .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                .build();
        assertTrue(activity.shouldCreateCompatDisplayInsets());
        assertFalse(activity.shouldCreateCompatDisplayInsets());

        // The non-resizable activity should not be size compat because it is on a resizable task
        // in multi-window mode.
@@ -719,7 +679,7 @@ public class SizeCompatTests extends WindowTestsBase {
    }

    @Test
    public void testShouldCreateCompatDisplayInsetsWhenUnresizeableAndSupportsSizeChangesFalse() {
    public void testShouldNotCreateCompatDisplayInsetsWhenRootActivityIsResizeable() {
        setUpDisplaySizeWithApp(1000, 2500);

        // Make the task root resizable.
@@ -728,7 +688,7 @@ public class SizeCompatTests extends WindowTestsBase {
        // Create an activity on the same task.
        final ActivityRecord activity = buildActivityRecord(/* supportsSizeChanges= */false,
                RESIZE_MODE_UNRESIZEABLE, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        assertTrue(activity.shouldCreateCompatDisplayInsets());
        assertFalse(activity.shouldCreateCompatDisplayInsets());
    }

    @Test
@@ -2269,6 +2229,12 @@ public class SizeCompatTests extends WindowTestsBase {
        activity.info.resizeMode = isUnresizable
                ? RESIZE_MODE_UNRESIZEABLE
                : RESIZE_MODE_RESIZEABLE;
        final Task task = activity.getTask();
        if (task != null) {
            // Update the Task resize value as activity will follow the task.
            task.mResizeMode = activity.info.resizeMode;
            task.getRootActivity().info.resizeMode = activity.info.resizeMode;
        }
        activity.mVisibleRequested = true;
        if (maxAspect >= 0) {
            activity.info.setMaxAspectRatio(maxAspect);