diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 8d6ce4718aefe7e04d82b297a65187cd58ac5e9f..7e2efc04ea8ead7d2df0f87de0fa86ef5b5d0d4c 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -552,6 +552,9 @@ public class PipTaskOrganizer extends TaskOrganizer { ? null : destinationBounds; // As for the final windowing mode, simply reset it to undefined. wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); + if (mSplitDivider != null && direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN) { + wct.reparent(mToken, mSplitDivider.getSecondaryRoot(), true /* onTop */); + } } else { taskBounds = destinationBounds; } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index e67b3d715c84f965aa449f4c8c6bedb8e428b6d6..02a7aca38abe738d51c3e0e063571f805da2692c 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -813,4 +813,12 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, updateVisibility(true /* visible */); } } + + /** @return the container token for the secondary split root task. */ + public WindowContainerToken getSecondaryRoot() { + if (mSplits == null || mSplits.mSecondary == null) { + return null; + } + return mSplits.mSecondary.token; + } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index f05217c0b47a712abafaeed1a0ace40541cfa281..e08bfd55011f0c4d6ded6240f41824e31c8e61d2 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1281,12 +1281,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } if (stack != null && stack.topRunningActivity() == this) { - // carry over the PictureInPictureParams to the parent stack without calling - // TaskOrganizerController#dispatchTaskInfoChanged. - // this is to ensure the stack holding up-to-dated pinned stack information - // when activity is re-parented to enter pip mode, see also - // RootWindowContainer#moveActivityToPinnedStack - stack.mPictureInPictureParams.copyOnlySet(pictureInPictureArgs); // make ensure the TaskOrganizer still works after re-parenting if (firstWindowDrawn) { stack.setHasBeenVisible(true); @@ -7769,6 +7763,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void setPictureInPictureParams(PictureInPictureParams p) { pictureInPictureArgs.copyOnlySet(p); - getTask().getRootTask().setPictureInPictureParams(p); + getTask().getRootTask().onPictureInPictureParamsChanged(); } } diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 9df3f855ad86a21541adf447be165c1ce306c2ec..1d72555787594803fd1de9346003d275db496134 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -702,8 +702,10 @@ class ActivityStack extends Task { // Need to make sure windowing mode is supported. If we in the process of creating the stack // no need to resolve the windowing mode again as it is already resolved to the right mode. if (!creating) { - windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, - null /* ActivityRecord */, topTask, getActivityType()); + if (!taskDisplayArea.isValidWindowingMode(windowingMode, null /* ActivityRecord */, + topTask, getActivityType())) { + windowingMode = WINDOWING_MODE_UNDEFINED; + } } if (taskDisplayArea.getRootSplitScreenPrimaryTask() == this && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) { diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 9a3ef4b1a63742c6a5f96e2e03003e6b5b6d16c4..6761bdecb5d83038df9b3bae4fc8f3ecd7276d9f 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -1459,6 +1459,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mService.deferWindowLayout(); try { stack.setWindowingMode(WINDOWING_MODE_UNDEFINED); + stack.setBounds(null); if (toDisplay.getDisplayId() != stack.getDisplayId()) { stack.reparent(toDisplay.getDefaultTaskDisplayArea(), false /* onTop */); } else { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 9a30f1c8e11dc73244dc3d7dbfe7b647f21abcbb..c93b7354999bdfe4e5446da09ac1b9fe36889a61 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2170,7 +2170,7 @@ class RootWindowContainer extends WindowContainer final boolean singleActivity = task.getChildCount() == 1; final ActivityStack stack; if (singleActivity) { - stack = r.getRootTask(); + stack = (ActivityStack) task; } else { // In the case of multiple activities, we will create a new task for it and then // move the PIP activity into the task. @@ -2183,6 +2183,11 @@ class RootWindowContainer extends WindowContainer // up-to-dated pinned stack information on this newly created stack. r.reparent(stack, MAX_VALUE, reason); } + if (stack.getParent() != taskDisplayArea) { + // stack is nested, but pinned tasks need to be direct children of their + // display area, so reparent. + stack.reparent(taskDisplayArea, true /* onTop */); + } stack.setWindowingMode(WINDOWING_MODE_PINNED); // Reset the state that indicates it can enter PiP while pausing after we've moved it diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 7ab9ccd9e9d2063ef54605d5231894826508127f..c2f98a74911a230122902d216336120f59ed4d43 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -110,7 +110,6 @@ import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppGlobals; -import android.app.PictureInPictureParams; import android.app.TaskInfo; import android.app.WindowConfiguration; import android.content.ComponentName; @@ -490,12 +489,6 @@ class Task extends WindowContainer { */ boolean mTaskAppearedSent; - /** - * Last Picture-in-Picture params applicable to the task. Updated when the app - * enters Picture-in-Picture or when setPictureInPictureParams is called. - */ - PictureInPictureParams mPictureInPictureParams = new PictureInPictureParams.Builder().build(); - /** * This task was created by the task organizer which has the following implementations. *
    @@ -3602,10 +3595,11 @@ class Task extends WindowContainer { info.resizeMode = top != null ? top.mResizeMode : mResizeMode; info.topActivityType = top.getActivityType(); - if (mPictureInPictureParams.empty()) { + ActivityRecord rootActivity = top.getRootActivity(); + if (rootActivity == null || rootActivity.pictureInPictureArgs.empty()) { info.pictureInPictureParams = null; } else { - info.pictureInPictureParams = mPictureInPictureParams; + info.pictureInPictureParams = rootActivity.pictureInPictureArgs; } info.topActivityInfo = mReuseActivitiesReport.top != null ? mReuseActivitiesReport.top.info @@ -4521,8 +4515,7 @@ class Task extends WindowContainer { updateShadowsRadius(hasFocus, getPendingTransaction()); } - void setPictureInPictureParams(PictureInPictureParams p) { - mPictureInPictureParams.copyOnlySet(p); + void onPictureInPictureParamsChanged() { if (isOrganized()) { mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, true /* force */); } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 0a1ee2b79711c8a91c2bad38a548ad024485f602..37a4c1f6849b50984e5a06619d5ea2d5f2b21c65 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -21,7 +21,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; @@ -1333,16 +1332,16 @@ final class TaskDisplayArea extends DisplayArea { } /** - * Check that the requested windowing-mode is appropriate for the specified task and/or activity + * Check if the requested windowing-mode is appropriate for the specified task and/or activity * on this display. * * @param windowingMode The windowing-mode to validate. * @param r The {@link ActivityRecord} to check against. * @param task The {@link Task} to check against. * @param activityType An activity type. - * @return The provided windowingMode or the closest valid mode which is appropriate. + * @return {@code true} if windowingMode is valid, {@code false} otherwise. */ - int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task, + boolean isValidWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task, int activityType) { // Make sure the windowing mode we are trying to use makes sense for what is supported. boolean supportsMultiWindow = mAtmService.mSupportsMultiWindow; @@ -1362,24 +1361,35 @@ final class TaskDisplayArea extends DisplayArea { } } + return windowingMode != WINDOWING_MODE_UNDEFINED + && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen, + supportsFreeform, supportsPip, activityType); + } + + /** + * Check that the requested windowing-mode is appropriate for the specified task and/or activity + * on this display. + * + * @param windowingMode The windowing-mode to validate. + * @param r The {@link ActivityRecord} to check against. + * @param task The {@link Task} to check against. + * @param activityType An activity type. + * @return The provided windowingMode or the closest valid mode which is appropriate. + */ + int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task, + int activityType) { final boolean inSplitScreenMode = isSplitScreenModeActivated(); - if (!inSplitScreenMode - && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) { + if (!inSplitScreenMode && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) { // Switch to the display's windowing mode if we are not in split-screen mode and we are // trying to launch in split-screen secondary. windowingMode = WINDOWING_MODE_UNDEFINED; - } else if (inSplitScreenMode && (windowingMode == WINDOWING_MODE_FULLSCREEN - || windowingMode == WINDOWING_MODE_UNDEFINED) - && supportsSplitScreen) { + } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_UNDEFINED) { windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; } - - if (windowingMode != WINDOWING_MODE_UNDEFINED - && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen, - supportsFreeform, supportsPip, activityType)) { - return windowingMode; + if (!isValidWindowingMode(windowingMode, r, task, activityType)) { + return WINDOWING_MODE_UNDEFINED; } - return WINDOWING_MODE_UNDEFINED; + return windowingMode; } boolean isTopStack(ActivityStack stack) { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 2ea58a028a0abff72a14376b90a12a7963ed0a1d..fdc5c7bf0ce14a2b890da4e0d14bac8c1e243bbc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -836,7 +836,7 @@ public class WindowOrganizerTests extends WindowTestsBase { spyOn(record); doReturn(true).when(record).checkEnterPictureInPictureState(any(), anyBoolean()); - record.getRootTask().setHasBeenVisible(true); + record.getTask().setHasBeenVisible(true); return record; }