Loading libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +7 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,13 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { if (Transitions.ENABLE_SHELL_TRANSITIONS) return; final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId); final Point positionInParent = taskInfo.positionInParent; mSyncQueue.runInSync(t -> t.setPosition(leash, positionInParent.x, positionInParent.y)); mSyncQueue.runInSync(t -> { // Reset several properties back. For instance, when an Activity enters PiP with // multiple activities in the same task, a new task will be created from that Activity // and we want reset the leash of the original task. t.setPosition(leash, positionInParent.x, positionInParent.y); t.setWindowCrop(leash, null); }); } @Override Loading services/core/java/com/android/server/wm/RecentsAnimationController.java +1 −0 Original line number Diff line number Diff line Loading @@ -1084,6 +1084,7 @@ public class RecentsAnimationController implements DeathRecipient { .setPosition(taskSurface, mFinishBounds.left, mFinishBounds.top) .setWindowCrop(taskSurface, mFinishBounds.width(), mFinishBounds.height()) .apply(); mTask.mLastRecentsAnimationBounds.set(mFinishBounds); mFinishBounds.setEmpty(); } else if (!mTask.isAttached()) { // Apply the task's pending transaction in case it is detached and its transaction Loading services/core/java/com/android/server/wm/RootWindowContainer.java +12 −25 Original line number Diff line number Diff line Loading @@ -2104,30 +2104,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> onTop); } boolean moveTopRootTaskActivityToPinnedRootTask(int rootTaskId) { final Task rootTask = getRootTask(rootTaskId); if (rootTask == null) { throw new IllegalArgumentException( "moveTopStackActivityToPinnedRootTask: Unknown rootTaskId=" + rootTaskId); } final ActivityRecord r = rootTask.topRunningActivity(); if (r == null) { Slog.w(TAG, "moveTopStackActivityToPinnedRootTask: No top running activity" + " in rootTask=" + rootTask); return false; } if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { Slog.w(TAG, "moveTopStackActivityToPinnedRootTask: Picture-In-Picture not supported " + "for r=" + r); return false; } moveActivityToPinnedRootTask(r, "moveTopStackActivityToPinnedRootTask"); return true; } void moveActivityToPinnedRootTask(ActivityRecord r, String reason) { mService.deferWindowLayout(); Loading @@ -2153,13 +2129,16 @@ class RootWindowContainer extends WindowContainer<DisplayContent> rootTask = 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. // move the PIP activity into the task. Note that we explicitly defer the task // appear being sent in this case and mark this newly created task to been visible. rootTask = new Task.Builder(mService) .setActivityType(r.getActivityType()) .setOnTop(true) .setActivityInfo(r.info) .setParent(taskDisplayArea) .setIntent(r.intent) .setDeferTaskAppear(true) .setHasBeenVisible(true) .build(); // It's possible the task entering PIP is in freeform, so save the last // non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore Loading @@ -2167,12 +2146,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> rootTask.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds); rootTask.setBounds(task.getBounds()); // Move reparent bounds from original task to the new one. rootTask.mLastRecentsAnimationBounds.set(task.mLastRecentsAnimationBounds); task.mLastRecentsAnimationBounds.setEmpty(); // There are multiple activities in the task and moving the top activity should // reveal/leave the other activities in their original task. // On the other hand, ActivityRecord#onParentChanged takes care of setting the // up-to-dated pinned stack information on this newly created stack. r.reparent(rootTask, MAX_VALUE, reason); // Ensure the leash of new task is in sync with its current bounds after reparent. rootTask.maybeApplyLastRecentsAnimationBounds(); // In the case of this activity entering PIP due to it being moved to the back, // the old activity would have a TRANSIT_TASK_TO_BACK transition that needs to be // ran. But, since its visibility did not change (note how it was STOPPED/not Loading Loading @@ -2201,6 +2187,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // TODO(task-org): Figure-out more structured way to do this long term. r.setWindowingMode(intermediateWindowingMode); rootTask.setWindowingMode(WINDOWING_MODE_PINNED); rootTask.setDeferTaskAppear(false); // Reset the state that indicates it can enter PiP while pausing after we've moved it // to the pinned stack Loading services/core/java/com/android/server/wm/Task.java +31 −4 Original line number Diff line number Diff line Loading @@ -463,6 +463,15 @@ class Task extends WindowContainer<WindowContainer> { int mMinWidth; int mMinHeight; // The bounds of the target when recents animation is finished. // This is originally introduced to carry out the current surface control position and window // crop when a multi-activity task enters pip with autoEnterPip enabled. In such case, // the surface control of the task will be animated in Launcher and then the top activity is // reparented to pinned root task. // Do not forget to reset this to null after reparenting. // TODO: remove this once the recents animation is moved to the Shell final Rect mLastRecentsAnimationBounds = new Rect(); static final int LAYER_RANK_INVISIBLE = -1; // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible) // This number will be assigned when we evaluate OOM scores for all visible tasks. Loading Loading @@ -4158,9 +4167,9 @@ class Task extends WindowContainer<WindowContainer> { private @Nullable PictureInPictureParams getPictureInPictureParams(Task top) { if (top == null) return null; final ActivityRecord rootActivity = top.getRootActivity(); return (rootActivity == null || rootActivity.pictureInPictureArgs.empty()) ? null : new PictureInPictureParams(rootActivity.pictureInPictureArgs); final ActivityRecord topVisibleActivity = top.getTopVisibleActivity(); return (topVisibleActivity == null || topVisibleActivity.pictureInPictureArgs.empty()) ? null : new PictureInPictureParams(topVisibleActivity.pictureInPictureArgs); } /** Loading Loading @@ -4984,7 +4993,7 @@ class Task extends WindowContainer<WindowContainer> { commitPendingTransaction(); } sendTaskAppeared(); if (!mDeferTaskAppear) sendTaskAppeared(); if (!isRootTask()) { getRootTask().setHasBeenVisible(true); } Loading Loading @@ -7589,6 +7598,17 @@ class Task extends WindowContainer<WindowContainer> { reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM); } void maybeApplyLastRecentsAnimationBounds() { if (!mLastRecentsAnimationBounds.isEmpty()) { getPendingTransaction() .setPosition(mSurfaceControl, mLastRecentsAnimationBounds.left, mLastRecentsAnimationBounds.top) .setWindowCrop(mSurfaceControl, mLastRecentsAnimationBounds.width(), mLastRecentsAnimationBounds.height()); mLastRecentsAnimationBounds.setEmpty(); } } private void updateSurfaceBounds() { updateSurfaceSize(getSyncTransaction()); updateSurfacePositionNonOrganized(); Loading Loading @@ -7824,6 +7844,7 @@ class Task extends WindowContainer<WindowContainer> { private boolean mDeferTaskAppear; private IBinder mLaunchCookie; private boolean mOnTop; private boolean mHasBeenVisible; Builder(ActivityTaskManagerService atm) { mAtmService = atm; Loading Loading @@ -7921,6 +7942,11 @@ class Task extends WindowContainer<WindowContainer> { return this; } Builder setHasBeenVisible(boolean hasBeenVisible) { mHasBeenVisible = hasBeenVisible; return this; } private Builder setUserId(int userId) { mUserId = userId; return this; Loading Loading @@ -8114,6 +8140,7 @@ class Task extends WindowContainer<WindowContainer> { } final Task task = buildInner(); task.mHasBeenVisible = mHasBeenVisible; // Set activity type before adding the root task to TaskDisplayArea, so home task can // be cached, see TaskDisplayArea#addRootTaskReferenceIfNeeded(). Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +7 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,13 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { if (Transitions.ENABLE_SHELL_TRANSITIONS) return; final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId); final Point positionInParent = taskInfo.positionInParent; mSyncQueue.runInSync(t -> t.setPosition(leash, positionInParent.x, positionInParent.y)); mSyncQueue.runInSync(t -> { // Reset several properties back. For instance, when an Activity enters PiP with // multiple activities in the same task, a new task will be created from that Activity // and we want reset the leash of the original task. t.setPosition(leash, positionInParent.x, positionInParent.y); t.setWindowCrop(leash, null); }); } @Override Loading
services/core/java/com/android/server/wm/RecentsAnimationController.java +1 −0 Original line number Diff line number Diff line Loading @@ -1084,6 +1084,7 @@ public class RecentsAnimationController implements DeathRecipient { .setPosition(taskSurface, mFinishBounds.left, mFinishBounds.top) .setWindowCrop(taskSurface, mFinishBounds.width(), mFinishBounds.height()) .apply(); mTask.mLastRecentsAnimationBounds.set(mFinishBounds); mFinishBounds.setEmpty(); } else if (!mTask.isAttached()) { // Apply the task's pending transaction in case it is detached and its transaction Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +12 −25 Original line number Diff line number Diff line Loading @@ -2104,30 +2104,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> onTop); } boolean moveTopRootTaskActivityToPinnedRootTask(int rootTaskId) { final Task rootTask = getRootTask(rootTaskId); if (rootTask == null) { throw new IllegalArgumentException( "moveTopStackActivityToPinnedRootTask: Unknown rootTaskId=" + rootTaskId); } final ActivityRecord r = rootTask.topRunningActivity(); if (r == null) { Slog.w(TAG, "moveTopStackActivityToPinnedRootTask: No top running activity" + " in rootTask=" + rootTask); return false; } if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { Slog.w(TAG, "moveTopStackActivityToPinnedRootTask: Picture-In-Picture not supported " + "for r=" + r); return false; } moveActivityToPinnedRootTask(r, "moveTopStackActivityToPinnedRootTask"); return true; } void moveActivityToPinnedRootTask(ActivityRecord r, String reason) { mService.deferWindowLayout(); Loading @@ -2153,13 +2129,16 @@ class RootWindowContainer extends WindowContainer<DisplayContent> rootTask = 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. // move the PIP activity into the task. Note that we explicitly defer the task // appear being sent in this case and mark this newly created task to been visible. rootTask = new Task.Builder(mService) .setActivityType(r.getActivityType()) .setOnTop(true) .setActivityInfo(r.info) .setParent(taskDisplayArea) .setIntent(r.intent) .setDeferTaskAppear(true) .setHasBeenVisible(true) .build(); // It's possible the task entering PIP is in freeform, so save the last // non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore Loading @@ -2167,12 +2146,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> rootTask.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds); rootTask.setBounds(task.getBounds()); // Move reparent bounds from original task to the new one. rootTask.mLastRecentsAnimationBounds.set(task.mLastRecentsAnimationBounds); task.mLastRecentsAnimationBounds.setEmpty(); // There are multiple activities in the task and moving the top activity should // reveal/leave the other activities in their original task. // On the other hand, ActivityRecord#onParentChanged takes care of setting the // up-to-dated pinned stack information on this newly created stack. r.reparent(rootTask, MAX_VALUE, reason); // Ensure the leash of new task is in sync with its current bounds after reparent. rootTask.maybeApplyLastRecentsAnimationBounds(); // In the case of this activity entering PIP due to it being moved to the back, // the old activity would have a TRANSIT_TASK_TO_BACK transition that needs to be // ran. But, since its visibility did not change (note how it was STOPPED/not Loading Loading @@ -2201,6 +2187,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // TODO(task-org): Figure-out more structured way to do this long term. r.setWindowingMode(intermediateWindowingMode); rootTask.setWindowingMode(WINDOWING_MODE_PINNED); rootTask.setDeferTaskAppear(false); // Reset the state that indicates it can enter PiP while pausing after we've moved it // to the pinned stack Loading
services/core/java/com/android/server/wm/Task.java +31 −4 Original line number Diff line number Diff line Loading @@ -463,6 +463,15 @@ class Task extends WindowContainer<WindowContainer> { int mMinWidth; int mMinHeight; // The bounds of the target when recents animation is finished. // This is originally introduced to carry out the current surface control position and window // crop when a multi-activity task enters pip with autoEnterPip enabled. In such case, // the surface control of the task will be animated in Launcher and then the top activity is // reparented to pinned root task. // Do not forget to reset this to null after reparenting. // TODO: remove this once the recents animation is moved to the Shell final Rect mLastRecentsAnimationBounds = new Rect(); static final int LAYER_RANK_INVISIBLE = -1; // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible) // This number will be assigned when we evaluate OOM scores for all visible tasks. Loading Loading @@ -4158,9 +4167,9 @@ class Task extends WindowContainer<WindowContainer> { private @Nullable PictureInPictureParams getPictureInPictureParams(Task top) { if (top == null) return null; final ActivityRecord rootActivity = top.getRootActivity(); return (rootActivity == null || rootActivity.pictureInPictureArgs.empty()) ? null : new PictureInPictureParams(rootActivity.pictureInPictureArgs); final ActivityRecord topVisibleActivity = top.getTopVisibleActivity(); return (topVisibleActivity == null || topVisibleActivity.pictureInPictureArgs.empty()) ? null : new PictureInPictureParams(topVisibleActivity.pictureInPictureArgs); } /** Loading Loading @@ -4984,7 +4993,7 @@ class Task extends WindowContainer<WindowContainer> { commitPendingTransaction(); } sendTaskAppeared(); if (!mDeferTaskAppear) sendTaskAppeared(); if (!isRootTask()) { getRootTask().setHasBeenVisible(true); } Loading Loading @@ -7589,6 +7598,17 @@ class Task extends WindowContainer<WindowContainer> { reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM); } void maybeApplyLastRecentsAnimationBounds() { if (!mLastRecentsAnimationBounds.isEmpty()) { getPendingTransaction() .setPosition(mSurfaceControl, mLastRecentsAnimationBounds.left, mLastRecentsAnimationBounds.top) .setWindowCrop(mSurfaceControl, mLastRecentsAnimationBounds.width(), mLastRecentsAnimationBounds.height()); mLastRecentsAnimationBounds.setEmpty(); } } private void updateSurfaceBounds() { updateSurfaceSize(getSyncTransaction()); updateSurfacePositionNonOrganized(); Loading Loading @@ -7824,6 +7844,7 @@ class Task extends WindowContainer<WindowContainer> { private boolean mDeferTaskAppear; private IBinder mLaunchCookie; private boolean mOnTop; private boolean mHasBeenVisible; Builder(ActivityTaskManagerService atm) { mAtmService = atm; Loading Loading @@ -7921,6 +7942,11 @@ class Task extends WindowContainer<WindowContainer> { return this; } Builder setHasBeenVisible(boolean hasBeenVisible) { mHasBeenVisible = hasBeenVisible; return this; } private Builder setUserId(int userId) { mUserId = userId; return this; Loading Loading @@ -8114,6 +8140,7 @@ class Task extends WindowContainer<WindowContainer> { } final Task task = buildInner(); task.mHasBeenVisible = mHasBeenVisible; // Set activity type before adding the root task to TaskDisplayArea, so home task can // be cached, see TaskDisplayArea#addRootTaskReferenceIfNeeded(). Loading