Revert^2: Fix pip enter/expand from split-screen secondary.
Split up validateWindowingMode into a validity check and
the one that "resolves" split-screen. This way, calling
setWindowingMode on an ActivityStack won't assign a
random mode (it won't convert undefined into split-secondary).
Without this, the task itself was getting set to secondary
(when it should just be inheriting).
Then, piptaskorganizer will reparent to secondary if in
split-mode (thus using the same logic it used to get the
final animation bounds).
Upon enter, instead of changing root-task mode to pinned,
only the leaf task changes (this is because pinned is now
an alwaysCreateStack activity type). WM, unfortunately,
has to reparent to displayarea here so that it doesn't
mess-up the topActivityType reported via onTaskInfoChanged.
Also made pip params come directly from the top activity
rather than be stored on the task. Otherwise, nested
pip activities wouldn't properly report their params
because they would have been set on the root rather
than their direct parent which meant that once the
direct parent became root, it wouldn't have the params
Bug: 154515783
Bug: 144711770
Test: go to split with a pippable in secondary. go to home
in secondary.
Change-Id: I74912f828b40745f502bc667bd8371c98891a73e
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 8d6ce47..7e2efc0 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 @@
? 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 e67b3d7..02a7aca 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 @@
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 850b657..4b427a2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1287,12 +1287,6 @@
}
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);
@@ -7777,6 +7771,6 @@
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 9df3f85..1d72555 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 @@
// 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 fb7ba62..3371520 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1440,6 +1440,7 @@
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/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index 4cd3180..513be7a 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -146,7 +146,10 @@
if (mTmpParams.hasWindowingMode()
&& mTmpParams.mWindowingMode != task.getStack().getWindowingMode()) {
- task.getStack().setWindowingMode(mTmpParams.mWindowingMode);
+ final int activityType = activity != null
+ ? activity.getActivityType() : task.getActivityType();
+ task.getStack().setWindowingMode(task.getDisplayArea().validateWindowingMode(
+ mTmpParams.mWindowingMode, activity, task, activityType));
}
if (mTmpParams.mBounds.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 9a30f1c..c93b735 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 @@
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 @@
// 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 caa0ddb..85a3161 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -109,7 +109,6 @@
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 @@
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.
* <ul>
* <lis>The task won't be removed when it is empty. Removal has to be an explicit request
@@ -3592,10 +3585,11 @@
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
@@ -4511,8 +4505,7 @@
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 0a1ee2b..37a4c1f 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_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 @@
}
/**
- * 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 @@
}
}
+ 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 2ea58a0..fdc5c7b 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 @@
spyOn(record);
doReturn(true).when(record).checkEnterPictureInPictureState(any(), anyBoolean());
- record.getRootTask().setHasBeenVisible(true);
+ record.getTask().setHasBeenVisible(true);
return record;
}