diff options
| author | 2023-09-20 00:51:34 +0000 | |
|---|---|---|
| committer | 2023-09-20 00:51:34 +0000 | |
| commit | db14390c7d6b3fabedf471add67487f28dbc9804 (patch) | |
| tree | c0e56dfcedf14a7b199e4f75ea579ded88a98cbd | |
| parent | e30506c6f68b952f4bb82e0a807961a1bdfd2c7a (diff) | |
| parent | 7943b5c2fc99a3f25e3e631626cc15a242935294 (diff) | |
Merge "Pause activity before resuming the next one" into main
4 files changed, 83 insertions, 34 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index a5ee19e2d068..cdfc4c87d271 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -879,14 +879,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Skip resolving if the activity is on a pinned TaskFragmentContainer. // TODO(b/243518738): skip resolving for overlay container. - if (container != null) { - final TaskContainer taskContainer = container.getTaskContainer(); - if (taskContainer.isTaskFragmentContainerPinned(container)) { - return true; - } + final TaskContainer taskContainer = container != null ? container.getTaskContainer() : null; + if (container != null && taskContainer != null + && taskContainer.isTaskFragmentContainerPinned(container)) { + return true; } - final TaskContainer taskContainer = container != null ? container.getTaskContainer() : null; if (!isOnReparent && taskContainer != null && taskContainer.getTopNonFinishingTaskFragmentContainer(false /* includePin */) != container) { @@ -895,6 +893,28 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return true; } + // Ensure the top TaskFragments are updated to the right config if activity is resolved + // to a new TaskFragment while pin TF exists. + final boolean handled = resolveActivityToContainerByRule(wct, activity, container, + isOnReparent); + if (handled && taskContainer != null) { + final SplitPinContainer splitPinContainer = taskContainer.getSplitPinContainer(); + if (splitPinContainer != null) { + final TaskFragmentContainer resolvedContainer = getContainerWithActivity(activity); + if (resolvedContainer != null && resolvedContainer.getRunningActivityCount() <= 1) { + updateContainer(wct, splitPinContainer.getSecondaryContainer()); + } + } + } + return handled; + } + + /** + * Resolves the activity to a {@link TaskFragmentContainer} according to the Split-rules. + */ + boolean resolveActivityToContainerByRule(@NonNull WindowContainerTransaction wct, + @NonNull Activity activity, @Nullable TaskFragmentContainer container, + boolean isOnReparent) { /* * We will check the following to see if there is any embedding rule matched: * 1. Whether the new launched activity should always expand. @@ -1301,6 +1321,26 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } } + // Ensure the top TaskFragments are updated to the right config if the intent is resolved + // to a new TaskFragment while pin TF exists. + final TaskFragmentContainer launchingContainer = resolveStartActivityIntentByRule(wct, + taskId, intent, launchingActivity); + if (launchingContainer != null && launchingContainer.getRunningActivityCount() == 0) { + final SplitPinContainer splitPinContainer = + launchingContainer.getTaskContainer().getSplitPinContainer(); + if (splitPinContainer != null) { + updateContainer(wct, splitPinContainer.getSecondaryContainer()); + } + } + return launchingContainer; + } + + /** + * Resolves the intent to a {@link TaskFragmentContainer} according to the Split-rules. + */ + @Nullable + TaskFragmentContainer resolveStartActivityIntentByRule(@NonNull WindowContainerTransaction wct, + int taskId, @NonNull Intent intent, @Nullable Activity launchingActivity) { /* * We will check the following to see if there is any embedding rule matched: * 1. Whether the new activity intent should always expand. diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index e523119ee9a0..9bfc5534ef45 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -795,17 +795,13 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { return false; } - // Try pausing the existing resumed activity in the same TaskFragment if any. - final TaskFragment taskFragment = r.getTaskFragment(); - if (taskFragment != null && taskFragment.getResumedActivity() != null) { - if (taskFragment.startPausing(mUserLeaving, false /* uiSleeping */, r, "realStart")) { - return false; - } + // Try pausing the existing resumed activity in the Task if any. + final Task task = r.getTask(); + if (task.pauseActivityIfNeeded(r, "realStart")) { + return false; } - final Task task = r.getTask(); final Task rootTask = task.getRootTask(); - beginDeferResume(); // The LaunchActivityItem also contains process configuration, so the configuration change // from WindowProcessController#setProcess can be deferred. The major reason is that if diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index de197a164d10..b4b8a74d0d1b 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1262,6 +1262,37 @@ class Task extends TaskFragment { return null; } + boolean pauseActivityIfNeeded(@Nullable ActivityRecord resuming, @NonNull String reason) { + if (!isLeafTask()) { + return false; + } + + final int[] someActivityPaused = {0}; + // Check if the direct child resumed activity in the leaf task needed to be paused if + // the leaf task is not a leaf task fragment. + if (!isLeafTaskFragment()) { + final ActivityRecord top = topRunningActivity(); + final ActivityRecord resumedActivity = getResumedActivity(); + if (resumedActivity != null && top.getTaskFragment() != this) { + // Pausing the resumed activity because it is occluded by other task fragment. + if (startPausing(false /* uiSleeping*/, resuming, reason)) { + someActivityPaused[0]++; + } + } + } + + forAllLeafTaskFragments((taskFrag) -> { + final ActivityRecord resumedActivity = taskFrag.getResumedActivity(); + if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) { + if (taskFrag.startPausing(false /* uiSleeping*/, resuming, reason)) { + someActivityPaused[0]++; + } + } + }, true /* traverseTopToBottom */); + + return someActivityPaused[0] > 0; + } + void updateTaskMovement(boolean toTop, boolean toBottom, int position) { EventLogTags.writeWmTaskMoved(mTaskId, getRootTaskId(), getDisplayId(), toTop ? 1 : 0, position); diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 9af12ad6e766..ae794a89480a 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -1271,27 +1271,9 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { boolean pauseBackTasks(ActivityRecord resuming) { final int[] someActivityPaused = {0}; forAllLeafTasks(leafTask -> { - // Check if the direct child resumed activity in the leaf task needed to be paused if - // the leaf task is not a leaf task fragment. - if (!leafTask.isLeafTaskFragment()) { - final ActivityRecord top = topRunningActivity(); - final ActivityRecord resumedActivity = leafTask.getResumedActivity(); - if (resumedActivity != null && top.getTaskFragment() != leafTask) { - // Pausing the resumed activity because it is occluded by other task fragment. - if (leafTask.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) { - someActivityPaused[0]++; - } - } + if (leafTask.pauseActivityIfNeeded(resuming, "pauseBackTasks")) { + someActivityPaused[0]++; } - - leafTask.forAllLeafTaskFragments((taskFrag) -> { - final ActivityRecord resumedActivity = taskFrag.getResumedActivity(); - if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) { - if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) { - someActivityPaused[0]++; - } - } - }, true /* traverseTopToBottom */); }, true /* traverseTopToBottom */); return someActivityPaused[0] > 0; } |