summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Louis Chang <louischang@google.com> 2023-09-20 00:51:34 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-09-20 00:51:34 +0000
commitdb14390c7d6b3fabedf471add67487f28dbc9804 (patch)
treec0e56dfcedf14a7b199e4f75ea579ded88a98cbd
parente30506c6f68b952f4bb82e0a807961a1bdfd2c7a (diff)
parent7943b5c2fc99a3f25e3e631626cc15a242935294 (diff)
Merge "Pause activity before resuming the next one" into main
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java52
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java12
-rw-r--r--services/core/java/com/android/server/wm/Task.java31
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java22
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;
}