Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +46 −6 Original line number Diff line number Diff line Loading @@ -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)) { 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) { Loading @@ -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. Loading Loading @@ -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. Loading services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +4 −8 Original line number Diff line number Diff line Loading @@ -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")) { // 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 Loading services/core/java/com/android/server/wm/Task.java +31 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/core/java/com/android/server/wm/TaskDisplayArea.java +2 −20 Original line number Diff line number Diff line Loading @@ -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")) { 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; } Loading Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +46 −6 Original line number Diff line number Diff line Loading @@ -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)) { 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) { Loading @@ -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. Loading Loading @@ -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. Loading
services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +4 −8 Original line number Diff line number Diff line Loading @@ -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")) { // 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 Loading
services/core/java/com/android/server/wm/Task.java +31 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/core/java/com/android/server/wm/TaskDisplayArea.java +2 −20 Original line number Diff line number Diff line Loading @@ -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")) { 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; } Loading