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

Commit 2cca149b authored by Chris Li's avatar Chris Li Committed by Automerger Merge Worker
Browse files

Merge "Allow non-resizable apps in split-screen (6/n)" into sc-dev am: 0838b40e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13438138

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I84230eeb2e6952081de0f74e7efba70305818e12
parents 70908e55 0838b40e
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import android.window.TaskSnapshot;
import android.window.WindowContainerToken;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
@@ -179,6 +178,19 @@ public class TaskInfo {
    @Nullable
    public ActivityInfo topActivityInfo;

    /**
     * The top activity in this task.
     * @hide
     */
    @Nullable
    public IBinder topActivityToken;

    /**
     * Whether the direct top activity is in size compat mode on foreground.
     * @hide
     */
    public boolean topActivityInSizeCompat;

    /**
     * Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
     * supports), this is what the system actually uses for resizability based on other policy and
@@ -356,6 +368,8 @@ public class TaskInfo {
        parentTaskId = source.readInt();
        isFocused = source.readBoolean();
        isVisible = source.readBoolean();
        topActivityToken = source.readStrongBinder();
        topActivityInSizeCompat = source.readBoolean();
    }

    /**
@@ -391,6 +405,8 @@ public class TaskInfo {
        dest.writeInt(parentTaskId);
        dest.writeBoolean(isFocused);
        dest.writeBoolean(isVisible);
        dest.writeStrongBinder(topActivityToken);
        dest.writeBoolean(topActivityInSizeCompat);
    }

    @Override
@@ -415,6 +431,8 @@ public class TaskInfo {
                + " parentTaskId=" + parentTaskId
                + " isFocused=" + isFocused
                + " isVisible=" + isVisible
                + " topActivityToken=" + topActivityToken
                + " topActivityInSizeCompat=" + topActivityInSizeCompat
                + "}";
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -2180,6 +2180,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }

    /** @return Root task of this activity, null if there is no task. */
    @Nullable
    Task getRootTask() {
        return task != null ? task.getRootTask() : null;
    }
@@ -2188,6 +2189,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return task != null ? task.getRootTaskId() : INVALID_TASK_ID;
    }

    /** @return the first organized parent task. */
    @Nullable
    Task getOrganizedTask() {
        return task != null ? task.getOrganizedTask() : null;
    }

    @Override
    @Nullable
    TaskDisplayArea getDisplayArea() {
+9 −1
Original line number Diff line number Diff line
@@ -5485,14 +5485,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    /** Checks whether the given activity is in size compatibility mode and notifies the change. */
    void handleActivitySizeCompatModeIfNeeded(ActivityRecord r) {
        if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
        final Task organizedTask = r.getOrganizedTask();
        if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN
                || organizedTask == null) {
            // The callback is only interested in the foreground changes of fullscreen activity.
            return;
        }
        if (!r.inSizeCompatMode()) {
            if (mLastCompatModeActivity != null) {
                // TODO(b/178327644) Remove notifySizeCompatModeActivityChanged
                mAtmService.getTaskChangeNotificationController()
                        .notifySizeCompatModeActivityChanged(mDisplayId, null /* activityToken */);
                // This will do nothing until SizeCompatModeActivityController is moved to shell
                organizedTask.onSizeCompatActivityChanged();
            }
            mLastCompatModeActivity = null;
            return;
@@ -5501,8 +5506,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            return;
        }
        mLastCompatModeActivity = r;
        // TODO(b/178327644) Remove notifySizeCompatModeActivityChanged
        mAtmService.getTaskChangeNotificationController()
                .notifySizeCompatModeActivityChanged(mDisplayId, r.appToken);
        // This will do nothing until SizeCompatModeActivityController is moved to shell
        organizedTask.onSizeCompatActivityChanged();
    }

    boolean isUidPresent(int uid) {
+28 −0
Original line number Diff line number Diff line
@@ -3082,6 +3082,20 @@ class Task extends WindowContainer<WindowContainer> {
        return parentTask == null ? this : parentTask.getRootTask();
    }

    /** @return the first organized task. */
    @Nullable
    Task getOrganizedTask() {
        if (isOrganized()) {
            return this;
        }
        final WindowContainer parent = getParent();
        if (parent == null) {
            return null;
        }
        final Task parentTask = parent.asTask();
        return parentTask == null ? null : parentTask.getOrganizedTask();
    }

    // TODO(task-merge): Figure out what's the right thing to do for places that used it.
    boolean isRootTask() {
        return getRootTask() == this;
@@ -4172,6 +4186,14 @@ class Task extends WindowContainer<WindowContainer> {
        info.topActivityInfo = mReuseActivitiesReport.top != null
                ? mReuseActivitiesReport.top.info
                : null;
        info.topActivityToken = mReuseActivitiesReport.top != null
                ? mReuseActivitiesReport.top.appToken
                : null;
        // Whether the direct top activity is in size compat mode on foreground.
        info.topActivityInSizeCompat = mReuseActivitiesReport.top != null
                && mReuseActivitiesReport.top.getOrganizedTask() == this
                && mReuseActivitiesReport.top.inSizeCompatMode()
                && mReuseActivitiesReport.top.isState(RESUMED);
        info.launchCookies.clear();
        info.addLaunchCookie(mLaunchCookie);
        forAllActivities(r -> {
@@ -5221,6 +5243,12 @@ class Task extends WindowContainer<WindowContainer> {
        }
    }

    /** Called when the top activity in the Root Task enters or exits size compat mode. */
    void onSizeCompatActivityChanged() {
        // Trigger TaskInfoChanged to update the size compat restart button.
        dispatchTaskInfoChangedIfNeeded(true /* force */);
    }

    /**
     * See {@link WindowContainerTransaction#setBoundsChangeTransaction}. In short this
     * transaction will be consumed by the next BASE_APPLICATION window within our hierarchy
+43 −0
Original line number Diff line number Diff line
@@ -480,10 +480,13 @@ public class SizeCompatTests extends WindowTestsBase {
    /**
     * Ensures that {@link TaskStackListener} can receive callback about the activity in size
     * compatibility mode.
     *
     * TODO(b/178327644) Remove after update DC#handleActivitySizeCompatModeIfNeeded
     */
    @Test
    public void testHandleActivitySizeCompatMode() {
        setUpDisplaySizeWithApp(1000, 2000);
        doReturn(true).when(mTask).isOrganized();
        ActivityRecord activity = mActivity;
        activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
        prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
@@ -520,6 +523,46 @@ public class SizeCompatTests extends WindowTestsBase {
        assertEquals(null, compatTokens.get(0));
    }

    /**
     * Ensures that {@link TaskOrganizerController} can receive callback about the activity in size
     * compatibility mode.
     */
    @Test
    public void testHandleActivitySizeCompatModeChanged() {
        setUpDisplaySizeWithApp(1000, 2000);
        doReturn(true).when(mTask).isOrganized();
        ActivityRecord activity = mActivity;
        activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatModeChanged");
        prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
        assertFitted();

        // Resize the display so that the activity exercises size-compat mode.
        resizeDisplay(mTask.mDisplayContent, 1000, 2500);

        // Expect the exact token when the activity is in size compatibility mode.
        verify(mTask).onSizeCompatActivityChanged();
        ActivityManager.RunningTaskInfo taskInfo = mTask.getTaskInfo();

        assertEquals(mActivity.appToken, taskInfo.topActivityToken);
        assertTrue(taskInfo.topActivityInSizeCompat);

        // Make the activity resizable again by restarting it
        clearInvocations(mTask);
        activity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
        activity.mVisibleRequested = true;
        activity.restartProcessIfVisible();
        // The full lifecycle isn't hooked up so manually set state to resumed
        activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatModeChanged");
        mTask.mDisplayContent.handleActivitySizeCompatModeIfNeeded(activity);

        // Expect null token when switching to non-size-compat mode activity.
        verify(mTask).onSizeCompatActivityChanged();
        taskInfo = mTask.getTaskInfo();

        assertEquals(mActivity.appToken, taskInfo.topActivityToken);
        assertFalse(taskInfo.topActivityInSizeCompat);
    }

    @Test
    public void testShouldUseSizeCompatModeOnResizableTask() {
        setUpDisplaySizeWithApp(1000, 2500);
Loading