Added TaskWindowContainerController
For linking TaskRecord in AMS to Task window container in WMS.
Bug: 30060889
Test: bit FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests
Test: bit FrameworksServicesTests:com.android.server.wm.TaskWindowContainerControllerTests
Test: Existing test pass and manual testing.
Change-Id: I16248f3e96e5087ba24198a48a3bd10a12ae76a6
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 8bd7c90..a0bb192 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -89,6 +89,8 @@
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
+import static java.lang.Integer.MAX_VALUE;
+import static java.lang.Integer.MIN_VALUE;
import android.Manifest;
import android.annotation.NonNull;
@@ -175,7 +177,6 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Objects;
import java.util.Set;
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
@@ -1923,7 +1924,7 @@
}
if (stackId != currentStack.mStackId) {
currentStack = moveTaskToStackUncheckedLocked(task, stackId, ON_TOP,
- !FORCE_FOCUS, reason);
+ !FORCE_FOCUS, reason, true /* allowStackOnTop */);
stackId = currentStack.mStackId;
// moveTaskToStackUncheckedLocked() should already placed the task on top,
// still need moveTaskToFrontLocked() below for any transition settings.
@@ -1936,9 +1937,7 @@
// WM resizeTask must be done after the task is moved to the correct stack,
// because Task's setBounds() also updates dim layer's bounds, but that has
// dependency on the stack.
- mWindowManager.resizeTask(task.taskId, task.mBounds,
- task.getOverrideConfiguration(), false /* relayout */,
- false /* forced */);
+ task.resizeWindowContainer();
}
}
}
@@ -2164,8 +2163,10 @@
continueUpdateBounds(HOME_STACK_ID);
for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
final int taskId = mResizingTasksDuringAnimation.valueAt(i);
- if (anyTaskForIdLocked(taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID) != null) {
- mWindowManager.setTaskDockedResizing(taskId, false);
+ final TaskRecord task =
+ anyTaskForIdLocked(taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+ if (task != null) {
+ task.setTaskDockedResizing(false);
}
}
mResizingTasksDuringAnimation.clear();
@@ -2211,7 +2212,7 @@
// display because it no longer contains any tasks.
mAllowDockedStackResize = false;
}
- final ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
+ ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
final boolean isFullscreenStackVisible = fullscreenStack != null &&
fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
final ArrayList<TaskRecord> tasks = stack.getAllTasks();
@@ -2228,15 +2229,18 @@
}
moveTaskToStackLocked(tasks.get(i).taskId,
FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/,
- "moveTasksToFullscreenStack", ANIMATE, DEFER_RESUME);
+ "moveTasksToFullscreenStack - onTop", ANIMATE, DEFER_RESUME,
+ true /* allowStackOnTop */);
}
ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
resumeFocusedStackTopActivityLocked();
} else {
- for (int i = size - 1; i >= 0; i--) {
- positionTaskInStackLocked(tasks.get(i).taskId,
- FULLSCREEN_WORKSPACE_STACK_ID, 0 /* position */);
+ for (int i = 0; i < size; i++) {
+ moveTaskToStackLocked(tasks.get(i).taskId, FULLSCREEN_WORKSPACE_STACK_ID,
+ true /* onTop */, false /* forceFocus */,
+ "moveTasksToFullscreenStack - NOT_onTop", !ANIMATE, DEFER_RESUME,
+ false /* allowStackOnTop */);
}
}
} finally {
@@ -2337,71 +2341,6 @@
}
}
- boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow,
- boolean deferResume) {
- if (!task.isResizeable()) {
- Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
- return true;
- }
-
- // If this is a forced resize, let it go through even if the bounds is not changing,
- // as we might need a relayout due to surface size change (to/from fullscreen).
- final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
- if (Objects.equals(task.mBounds, bounds) && !forced) {
- // Nothing to do here...
- return true;
- }
- bounds = TaskRecord.validateBounds(bounds);
-
- if (!mWindowManager.isValidTaskId(task.taskId)) {
- // Task doesn't exist in window manager yet (e.g. was restored from recents).
- // All we can do for now is update the bounds so it can be used when the task is
- // added to window manager.
- task.updateOverrideConfiguration(bounds);
- if (task.getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
- // re-restore the task so it can have the proper stack association.
- restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID);
- }
- return true;
- }
-
- if (!task.canResizeToBounds(bounds)) {
- throw new IllegalArgumentException("resizeTaskLocked: Can not resize task=" + task
- + " to bounds=" + bounds + " resizeMode=" + task.mResizeMode);
- }
-
- // Do not move the task to another stack here.
- // This method assumes that the task is already placed in the right stack.
- // we do not mess with that decision and we only do the resize!
-
- Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId);
-
- final boolean updatedConfig = task.updateOverrideConfiguration(bounds);
- // This variable holds information whether the configuration didn't change in a significant
- // way and the activity was kept the way it was. If it's false, it means the activity had
- // to be relaunched due to configuration change.
- boolean kept = true;
- if (updatedConfig) {
- final ActivityRecord r = task.topRunningActivityLocked();
- if (r != null) {
- kept = r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindow);
-
- if (!deferResume) {
- // All other activities must be made visible with their correct configuration.
- ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
- if (!kept) {
- resumeFocusedStackTopActivityLocked();
- }
- }
- }
- }
- mWindowManager.resizeTask(task.taskId, task.mBounds, task.getOverrideConfiguration(), kept,
- forced);
-
- Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
- return kept;
- }
-
ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
@@ -2415,7 +2354,7 @@
}
/**
- * Removes the stack associed with the given {@param stackId}. If the {@param stackId} is the
+ * Removes the stack associated with the given {@param stackId}. If the {@param stackId} is the
* pinned stack, then its tasks are not explicitly removed when the stack is destroyed, but
* instead moved back onto the fullscreen stack.
*/
@@ -2437,8 +2376,7 @@
final int insertPosition = isFullscreenStackVisible
? Math.max(0, fullscreenStack.getChildCount() - 1)
: fullscreenStack.getChildCount();
- positionTaskInStackLocked(tasks.get(i).taskId, FULLSCREEN_WORKSPACE_STACK_ID,
- insertPosition);
+ fullscreenStack.positionChildAt(tasks.get(i).taskId, insertPosition);
}
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
resumeFocusedStackTopActivityLocked();
@@ -2568,7 +2506,7 @@
* or is not a static stack).
* @return true if the task has been restored successfully.
*/
- private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
+ boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
if (!StackId.isStaticStack(stackId)) {
// If stack is not static (or stack id is invalid) - use the default one.
// This means that tasks that were on external displays will be restored on the
@@ -2603,10 +2541,8 @@
}
stack.addTask(task, false /* toTop */, "restoreRecentTask");
- final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds();
- mWindowManager.addTask(task.taskId, stack.mStackId, task.userId, bounds,
- task.getOverrideConfiguration(), task.mResizeMode, task.isHomeTask(),
- task.isOnTopLauncher(), false /* toTop */, true /* showForAllUsers */);
+ // TODO: move call for creation here and other place into Stack.addTask()
+ task.createWindowContainer(false /* toTop */, true /* showForAllUsers */);
if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
"Added restored task=" + task + " to stack=" + stack);
final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -2660,10 +2596,13 @@
* @param toTop True if the task should be placed at the top of the stack.
* @param forceFocus if focus should be moved to the new stack
* @param reason Reason the task is been moved.
+ * @param allowStackOnTop If stack movement should be moved to the top due to the addition of
+ * the task to the stack. E.g. Moving the stack to the front because it
+ * should be focused because it now contains the focused activity.
* @return The stack the task was moved to.
*/
- ActivityStack moveTaskToStackUncheckedLocked(
- TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
+ ActivityStack moveTaskToStackUncheckedLocked(TaskRecord task, int stackId, boolean toTop,
+ boolean forceFocus, String reason, boolean allowStackOnTop) {
if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) {
throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't "
@@ -2694,15 +2633,15 @@
// if a docked stack is created below which will lead to the stack we are moving from and
// its resizeable tasks being resized.
task.mTemporarilyUnresizable = true;
- final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop);
+ final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop && allowStackOnTop);
task.mTemporarilyUnresizable = false;
- mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop);
- stack.addTask(task, toTop, reason);
+ task.reparentWindowContainer(stack.mStackId, toTop ? MAX_VALUE : MIN_VALUE);
+ stack.addTask(task, toTop, reason, allowStackOnTop);
// If the task had focus before (or we're requested to move focus),
// move focus to the new stack by moving the stack to the front.
stack.moveToFrontAndResumeStateIfNeeded(
- r, forceFocus || wasFocused || wasFront, wasResumed, reason);
+ r, allowStackOnTop && (forceFocus || wasFocused || wasFront), wasResumed, reason);
return stack;
}
@@ -2710,11 +2649,11 @@
boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
String reason, boolean animate) {
return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate,
- false /* deferResume */);
+ false /* deferResume */, true /* allowStackOnTop */);
}
boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
- String reason, boolean animate, boolean deferResume) {
+ String reason, boolean animate, boolean deferResume, boolean allowStackOnTop) {
final TaskRecord task = anyTaskForIdLocked(taskId);
if (task == null) {
Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
@@ -2754,7 +2693,7 @@
boolean kept = true;
try {
final ActivityStack stack = moveTaskToStackUncheckedLocked(
- task, stackId, toTop, forceFocus, reason + " moveTaskToStack");
+ task, stackId, toTop, forceFocus, reason + " moveTaskToStack", allowStackOnTop);
stackId = stack.mStackId;
if (!animate) {
@@ -2766,19 +2705,18 @@
// Make sure the task has the appropriate bounds/size for the stack it is in.
if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
- kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
- !mightReplaceWindow, deferResume);
+ kept = task.resize(stack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
+ deferResume);
} else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
Rect bounds = task.getLaunchBounds();
if (bounds == null) {
stack.layoutTaskInStack(task, null);
bounds = task.mBounds;
}
- kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow,
- deferResume);
+ kept = task.resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
} else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
- kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
- !mightReplaceWindow, deferResume);
+ kept = task.resize(stack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
+ deferResume);
}
} finally {
mWindowManager.continueSurfaceLayout();
@@ -2908,28 +2846,6 @@
return true;
}
- /** @see ActivityManagerService#positionTaskInStack(int, int, int). */
- void positionTaskInStackLocked(int taskId, int stackId, int position) {
- final TaskRecord task = anyTaskForIdLocked(taskId);
- if (task == null) {
- Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
- return;
- }
- final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
-
- task.updateOverrideConfigurationForStack(stack);
-
- // TODO: Return final position from WM for AM to use instead of duplicating computations in
- // ActivityStack#insertTaskAtPosition.
- mWindowManager.positionTaskInStack(
- taskId, stackId, position, task.mBounds, task.getOverrideConfiguration());
- stack.positionTask(task, position);
- // The task might have already been running and its visibility needs to be synchronized with
- // the visibility of the stack / windows.
- stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- resumeFocusedStackTopActivityLocked();
- }
-
ActivityRecord findTaskLocked(ActivityRecord r) {
mTmpFindTaskResult.r = null;
mTmpFindTaskResult.matchedByRootAffinity = false;
@@ -3352,7 +3268,7 @@
stack.switchUserLocked(userId);
TaskRecord task = stack.topTask();
if (task != null) {
- mWindowManager.moveTaskToTop(task.taskId);
+ task.moveWindowContainerToTop(true /* includingParents */);
}
}
}
@@ -3813,7 +3729,7 @@
: task.getTopActivity() != null ? task.getTopActivity().packageName
: "unknown";
taskBounds[i] = new Rect();
- mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
+ task.getWindowContainerBounds(taskBounds[i]);
taskUserIds[i] = task.userId;
}
info.taskIds = taskIds;
@@ -4768,11 +4684,11 @@
/**
* Puts a task into resizing mode during the next app transition.
*
- * @param taskId the id of the task to put into resizing mode
+ * @param task The task to put into resizing mode
*/
- private void setResizingDuringAnimation(int taskId) {
- mResizingTasksDuringAnimation.add(taskId);
- mWindowManager.setTaskDockedResizing(taskId, true);
+ private void setResizingDuringAnimation(TaskRecord task) {
+ mResizingTasksDuringAnimation.add(task.taskId);
+ task.setTaskDockedResizing(true);
}
final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
@@ -4837,7 +4753,7 @@
// the window renders full-screen with the background filling the void. Also only
// call this at the end to make sure that tasks exists on the window manager side.
if (launchStackId == DOCKED_STACK_ID) {
- setResizingDuringAnimation(taskId);
+ setResizingDuringAnimation(task);
}
mService.mActivityStarter.postStartActivityUncheckedProcessing(task.getTopActivity(),
@@ -4854,7 +4770,7 @@
int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
null, null, 0, 0, bOptions, userId, null, task);
if (launchStackId == DOCKED_STACK_ID) {
- setResizingDuringAnimation(task.taskId);
+ setResizingDuringAnimation(task);
}
return result;
}