diff options
author | Hongwei Wang <hwwang@google.com> | 2021-12-05 17:28:59 -0800 |
---|---|---|
committer | Hongwei Wang <hwwang@google.com> | 2021-12-09 21:07:45 -0800 |
commit | d4848611d2ec8f67a2d125a4f57a681bea0fb6d2 (patch) | |
tree | 8498b4fd256e88d444b0ae3051cd70772f164b5e /libs | |
parent | 1ba4fcf07687b37c91e270769554f05087639771 (diff) |
Fix the transition from Split to PiP
- Do not bring split to top on entering PiP
When swiping up to home (or other cases) triggers one of the
split-screen children enters PiP, do not try to bring the other task
to top since the pair should be considered invisible.
- When entering PiP from split screen or non-auto PiP case, use the
alpha information in PictureInPictureSurfaceTransaction to hide the
task which would later be turned back on to avoid flicker.
Bug: 190855091
Bug: 205894095
Video: http://recall/-/aaaaaabFQoRHlzixHdtY/42RWtayanp2qG0mHSf4Q5
Test: manual, enter PiP from split-screen, see Video
Change-Id: I1559748cd583c20d79ee458822d66e7801733d3a
Diffstat (limited to 'libs')
3 files changed, 29 insertions, 2 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 05552aad2303..cf4e56e128bf 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -102,6 +102,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, static final int EXIT_REASON_ROOT_TASK_VANISHED = 6; static final int EXIT_REASON_SCREEN_LOCKED = 7; static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8; + static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9; @IntDef(value = { EXIT_REASON_UNKNOWN, EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW, @@ -112,6 +113,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, EXIT_REASON_ROOT_TASK_VANISHED, EXIT_REASON_SCREEN_LOCKED, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP, + EXIT_REASON_CHILD_TASK_ENTER_PIP, }) @Retention(RetentionPolicy.SOURCE) @interface ExitReason{} @@ -406,6 +408,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return "APP_FINISHED"; case EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW: return "APP_DOES_NOT_SUPPORT_MULTIWINDOW"; + case EXIT_REASON_CHILD_TASK_ENTER_PIP: + return "CHILD_TASK_ENTER_PIP"; default: return "unknown reason, reason int = " + exitReason; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index e30e6c537c93..dd538dc4602c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -35,6 +35,7 @@ import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED; +import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME; @@ -629,8 +630,12 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, }); mShouldUpdateRecents = false; - mSideStage.removeAllTasks(wct, childrenToTop == mSideStage); - mMainStage.deactivate(wct, childrenToTop == mMainStage); + // When the exit split-screen is caused by one of the task enters auto pip, + // we want the tasks to be put to bottom instead of top, otherwise it will end up + // a fullscreen plus a pinned task instead of pinned only at the end of the transition. + final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP; + mSideStage.removeAllTasks(wct, !fromEnteringPip && childrenToTop == mSideStage); + mMainStage.deactivate(wct, !fromEnteringPip && childrenToTop == mMainStage); mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> t .setWindowCrop(mMainStage.mRootLeash, null) @@ -660,6 +665,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, case EXIT_REASON_DRAG_DIVIDER: // Either of the split apps have finished case EXIT_REASON_APP_FINISHED: + // One of the children enters PiP + case EXIT_REASON_CHILD_TASK_ENTER_PIP: return true; default: return false; @@ -749,6 +756,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } + private void onStageChildTaskEnterPip(StageListenerImpl stageListener, int taskId) { + exitSplitScreen(stageListener == mMainStageListener ? mMainStage : mSideStage, + EXIT_REASON_CHILD_TASK_ENTER_PIP); + } + private void updateRecentTasksSplitPair() { if (!mShouldUpdateRecents) { return; @@ -1437,6 +1449,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } @Override + public void onChildTaskEnterPip(int taskId) { + StageCoordinator.this.onStageChildTaskEnterPip(this, taskId); + } + + @Override public void onRootTaskVanished() { reset(); StageCoordinator.this.onStageRootTaskVanished(this); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index cd10b9fde444..2c853c1c474c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; +import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS; @@ -73,6 +74,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onChildTaskStatusChanged(int taskId, boolean present, boolean visible); + void onChildTaskEnterPip(int taskId); + void onRootTaskVanished(); void onNoLongerSupportMultiWindow(); @@ -256,6 +259,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { mChildrenTaskInfo.remove(taskId); mChildrenLeashes.remove(taskId); mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible); + if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) { + mCallbacks.onChildTaskEnterPip(taskId); + } if (ENABLE_SHELL_TRANSITIONS) { // Status is managed/synchronized by the transition lifecycle. return; |