From ee2134b0bd6197e0c0f26bea08e931067c3dab18 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Wed, 7 Jun 2023 11:52:44 +0000 Subject: [PATCH] Update correct split task Id to RecentsTaskController... Otherwise there will show incorrect/non-exist task pair which doesn't align with StageCoordinate, also can launch incorrect tasks. After switch to shell transition, we cannot determine which one is the top visibile task because the TaskInfo#isVisible will always be true for both open and close task before transition finish, so getTopVisibleChildTaskId can choose the close task as top task during transition, which will accidentally add or remove correct task pair to RecentTasksController, thus create the strange pair in #getRecentTasks. Add a field isVisibleRequested in TaskInfo, so there should always one visible task in a stage, to fix the confuse situation. Bug: 286204636 Test: follow issus description. Test: verify split bounds doesn't change after pair-to-pair switch. Test: Create two pair, drag app from taskbar to one of the pair, do pair-to-pair switch, enter recents. Verify previous pair still exists, and no extra pair shows up in recents. Change-Id: Id468ee889b90411d53fcae574ed65bfa7ab795d2 --- core/java/android/app/TaskInfo.java | 10 ++++++++++ .../android/wm/shell/splitscreen/StageCoordinator.java | 2 +- .../wm/shell/splitscreen/StageTaskListener.java | 8 +++++--- services/core/java/com/android/server/wm/Task.java | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index 4b8cfd5d32155..c4e49954f7457 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -333,6 +333,12 @@ public class TaskInfo { */ public boolean isVisible; + /** + * Whether this task is request visible. + * @hide + */ + public boolean isVisibleRequested; + /** * Whether this task is sleeping due to sleeping display. * @hide @@ -518,6 +524,7 @@ public class TaskInfo { && Objects.equals(taskDescription, that.taskDescription) && isFocused == that.isFocused && isVisible == that.isVisible + && isVisibleRequested == that.isVisibleRequested && isSleeping == that.isSleeping && Objects.equals(mTopActivityLocusId, that.mTopActivityLocusId) && parentTaskId == that.parentTaskId @@ -591,6 +598,7 @@ public class TaskInfo { parentTaskId = source.readInt(); isFocused = source.readBoolean(); isVisible = source.readBoolean(); + isVisibleRequested = source.readBoolean(); isSleeping = source.readBoolean(); topActivityInSizeCompat = source.readBoolean(); topActivityEligibleForLetterboxEducation = source.readBoolean(); @@ -644,6 +652,7 @@ public class TaskInfo { dest.writeInt(parentTaskId); dest.writeBoolean(isFocused); dest.writeBoolean(isVisible); + dest.writeBoolean(isVisibleRequested); dest.writeBoolean(isSleeping); dest.writeBoolean(topActivityInSizeCompat); dest.writeBoolean(topActivityEligibleForLetterboxEducation); @@ -687,6 +696,7 @@ public class TaskInfo { + " parentTaskId=" + parentTaskId + " isFocused=" + isFocused + " isVisible=" + isVisible + + " isVisibleRequested=" + isVisibleRequested + " isSleeping=" + isSleeping + " topActivityInSizeCompat=" + topActivityInSizeCompat + " topActivityEligibleForLetterboxEducation= " 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 fd871ed8c8cee..9d278b721becd 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 @@ -1636,7 +1636,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mLogger.logSideStageAppChange(getSideStagePosition(), mSideStage.getTopChildTaskUid(), mSplitLayout.isLandscape()); } - if (present && visible) { + if (present) { updateRecentTasksSplitPair(); } 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 60628e62ec11c..a01eddbc9b9fb 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 @@ -127,7 +127,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { * Returns the top visible child task's id. */ int getTopVisibleChildTaskId() { - final ActivityManager.RunningTaskInfo taskInfo = getChildTaskInfo(t -> t.isVisible); + final ActivityManager.RunningTaskInfo taskInfo = getChildTaskInfo(t -> t.isVisible + && t.isVisibleRequested); return taskInfo != null ? taskInfo.taskId : INVALID_TASK_ID; } @@ -183,7 +184,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { final int taskId = taskInfo.taskId; mChildrenLeashes.put(taskId, leash); mChildrenTaskInfo.put(taskId, taskInfo); - mCallbacks.onChildTaskStatusChanged(taskId, true /* present */, taskInfo.isVisible); + mCallbacks.onChildTaskStatusChanged(taskId, true /* present */, + taskInfo.isVisible && taskInfo.isVisibleRequested); if (ENABLE_SHELL_TRANSITIONS) { // Status is managed/synchronized by the transition lifecycle. return; @@ -223,7 +225,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } mChildrenTaskInfo.put(taskInfo.taskId, taskInfo); mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */, - taskInfo.isVisible); + taskInfo.isVisible && taskInfo.isVisibleRequested); if (!ENABLE_SHELL_TRANSITIONS) { updateChildTaskSurface( taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 7104739068e4b..ceb80d6a1a8b9 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3443,6 +3443,7 @@ class Task extends TaskFragment { : INVALID_TASK_ID; info.isFocused = isFocused(); info.isVisible = hasVisibleChildren(); + info.isVisibleRequested = isVisibleRequested(); info.isSleeping = shouldSleepActivities(); info.isLetterboxDoubleTapEnabled = top != null && top.mLetterboxUiController.isLetterboxDoubleTapEducationEnabled();