Merge "Removing RWC#getValidLaunchRootTaskInTaskDisplayArea" into tm-dev

This commit is contained in:
Louis Chang
2022-02-24 14:57:30 +00:00
committed by Android (Google) Code Review
6 changed files with 62 additions and 151 deletions

View File

@@ -18,15 +18,9 @@ package com.android.server.wm;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
@@ -2791,35 +2785,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
Task rootTask = null;
// Next preference for root task goes to the taskDisplayArea candidate.
if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null
&& canLaunchOnDisplay(r, launchParams.mPreferredTaskDisplayArea.getDisplayId())) {
taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
}
if (taskDisplayArea == null && displayId != INVALID_DISPLAY) {
final DisplayContent displayContent = getDisplayContent(displayId);
if (displayContent != null) {
taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
}
if (taskDisplayArea == null && displayId != INVALID_DISPLAY
&& canLaunchOnDisplay(r, displayId)) {
taskDisplayArea = getDisplayContent(displayId).getDefaultTaskDisplayArea();
}
if (taskDisplayArea != null) {
final int tdaDisplayId = taskDisplayArea.getDisplayId();
if (canLaunchOnDisplay(r, tdaDisplayId)) {
if (r != null) {
final Task result = getValidLaunchRootTaskInTaskDisplayArea(
taskDisplayArea, r, candidateTask, options, launchParams);
if (result != null) {
return result;
}
}
// Falling back to default task container
taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea();
rootTask = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
sourceTask, launchParams, launchFlags, activityType, onTop);
if (rootTask != null) {
return rootTask;
}
}
return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
sourceTask, launchParams, launchFlags, activityType, onTop);
}
// Give preference to the root task and display of the input task and activity if they
@@ -2869,103 +2845,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return r.canBeLaunchedOnDisplay(displayId);
}
/**
* Get a topmost root task on the display area, that is a valid launch root task for
* specified activity. If there is no such root task, new dynamic root task can be created.
*
* @param taskDisplayArea Target display area.
* @param r Activity that should be launched there.
* @param candidateTask The possible task the activity might be put in.
* @return Existing root task if there is a valid one, new dynamic root task if it is valid
* or null.
*/
@VisibleForTesting
Task getValidLaunchRootTaskInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea,
@NonNull ActivityRecord r, @Nullable Task candidateTask,
@Nullable ActivityOptions options,
@Nullable LaunchParamsController.LaunchParams launchParams) {
if (!r.canBeLaunchedOnDisplay(taskDisplayArea.getDisplayId())) {
return null;
}
// If {@code r} is already in target display area and its task is the same as the candidate
// task, the intention should be getting a launch root task for the reusable activity, so we
// can use the existing root task.
if (candidateTask != null) {
final TaskDisplayArea attachedTaskDisplayArea = candidateTask.getDisplayArea();
if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) {
return candidateTask.getRootTask();
}
// Or the candidate task is already a root task that can be reused by reparenting
// it to the target display.
if (candidateTask.isRootTask()) {
final Task rootTask = candidateTask.getRootTask();
rootTask.reparent(taskDisplayArea, true /* onTop */);
return rootTask;
}
}
int windowingMode;
if (launchParams != null) {
// When launch params is not null, we always defer to its windowing mode. Sometimes
// it could be unspecified, which indicates it should inherit windowing mode from
// display.
windowingMode = launchParams.mWindowingMode;
} else {
windowingMode = options != null ? options.getLaunchWindowingMode()
: r.getWindowingMode();
}
windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask);
// Return the topmost valid root task on the display.
final int targetWindowingMode = windowingMode;
final Task topmostValidRootTask = taskDisplayArea.getRootTask(rootTask ->
isValidLaunchRootTask(rootTask, r, targetWindowingMode));
if (topmostValidRootTask != null) {
return topmostValidRootTask;
}
// If there is no valid root task on the secondary display area - check if new dynamic root
// task will do.
if (taskDisplayArea != getDisplayContent(taskDisplayArea.getDisplayId())
.getDefaultTaskDisplayArea()) {
final int activityType =
options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
? options.getLaunchActivityType() : r.getActivityType();
return taskDisplayArea.createRootTask(
windowingMode, activityType, true /*onTop*/, options);
}
return null;
}
// TODO: Can probably be consolidated into getLaunchRootTask()...
private boolean isValidLaunchRootTask(Task task, ActivityRecord r, int windowingMode) {
switch (task.getActivityType()) {
case ACTIVITY_TYPE_HOME:
return r.isActivityTypeHome();
case ACTIVITY_TYPE_RECENTS:
return r.isActivityTypeRecents();
case ACTIVITY_TYPE_ASSISTANT:
return r.isActivityTypeAssistant();
case ACTIVITY_TYPE_DREAM:
return r.isActivityTypeDream();
}
if (task.mCreatedByOrganizer) {
// Don't launch directly into task created by organizer...but why can't we?
return false;
}
// There is a 1-to-1 relationship between root task and task when not in
// primary split-windowing mode.
if (task.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
&& r.supportsSplitScreenWindowingModeInDisplayArea(task.getDisplayArea())
&& (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
|| windowingMode == WINDOWING_MODE_UNDEFINED)) {
return true;
}
return false;
}
int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
@Nullable Task task) {
// Preference is given to the activity type for the activity then the task since the type

View File

@@ -941,36 +941,32 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop,
@Nullable Task candidateTask, @Nullable Task sourceTask,
@Nullable ActivityOptions options, int launchFlags) {
final int resolvedWindowingMode =
windowingMode == WINDOWING_MODE_UNDEFINED ? getWindowingMode() : windowingMode;
// Need to pass in a determined windowing mode to see if a new root task should be created,
// so use its parent's windowing mode if it is undefined.
if (!alwaysCreateRootTask(
windowingMode != WINDOWING_MODE_UNDEFINED ? windowingMode : getWindowingMode(),
activityType)) {
Task rootTask = getRootTask(windowingMode, activityType);
if (!alwaysCreateRootTask(resolvedWindowingMode, activityType)) {
Task rootTask = getRootTask(resolvedWindowingMode, activityType);
if (rootTask != null) {
return rootTask;
}
} else if (candidateTask != null) {
final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
final Task launchRootTask = getLaunchRootTask(windowingMode, activityType, options,
sourceTask, launchFlags);
final Task launchRootTask = getLaunchRootTask(resolvedWindowingMode, activityType,
options, sourceTask, launchFlags);
if (launchRootTask != null) {
if (candidateTask.getParent() == null) {
launchRootTask.addChild(candidateTask, position);
} else if (candidateTask.getParent() != launchRootTask) {
candidateTask.reparent(launchRootTask, position);
}
} else if (candidateTask.getDisplayArea() != this || !candidateTask.isRootTask()) {
} else if (candidateTask.getDisplayArea() != this) {
if (candidateTask.getParent() == null) {
addChild(candidateTask, position);
} else {
candidateTask.reparent(this, onTop);
}
}
// Update windowing mode if necessary, e.g. moving a pinned task to fullscreen.
if (candidateTask.getWindowingMode() != windowingMode) {
candidateTask.setWindowingMode(windowingMode);
}
return candidateTask.getRootTask();
}
return new Task.Builder(mAtmService)

View File

@@ -157,12 +157,26 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
// display.
if (launchMode == WINDOWING_MODE_UNDEFINED
&& canInheritWindowingModeFromSource(display, source)) {
launchMode = source.getWindowingMode();
// The source's windowing mode may be different from its task, e.g. activity is set
// to fullscreen and its task is pinned windowing mode when the activity is entering
// pip.
launchMode = source.getTask().getWindowingMode();
if (DEBUG) {
appendLog("inherit-from-source="
+ WindowConfiguration.windowingModeToString(launchMode));
}
}
// If the launch windowing mode is still undefined, inherit from the target task if the
// task is already on the right display area (otherwise, the task may be on a different
// display area that has incompatible windowing mode).
if (launchMode == WINDOWING_MODE_UNDEFINED
&& task != null && task.getTaskDisplayArea() == suggestedDisplayArea) {
launchMode = task.getWindowingMode();
if (DEBUG) {
appendLog("inherit-from-task="
+ WindowConfiguration.windowingModeToString(launchMode));
}
}
// hasInitialBounds is set if either activity options or layout has specified bounds. If
// that's set we'll skip some adjustments later to avoid overriding the initial bounds.
boolean hasInitialBounds = false;

View File

@@ -925,14 +925,10 @@ public class ActivityStarterTests extends WindowTestsBase {
any(), anyBoolean(), anyBoolean(), eq(false));
}
private ActivityRecord createSingleTaskActivityOn(Task stack) {
private ActivityRecord createSingleTaskActivityOn(Task task) {
final ComponentName componentName = ComponentName.createRelative(
DEFAULT_COMPONENT_PACKAGE_NAME,
DEFAULT_COMPONENT_PACKAGE_NAME + ".SingleTaskActivity");
final Task task = new TaskBuilder(mSupervisor)
.setComponent(componentName)
.setParentTaskFragment(stack)
.build();
return new ActivityBuilder(mAtm)
.setComponent(componentName)
.setLaunchMode(LAUNCH_SINGLE_TASK)

View File

@@ -938,7 +938,33 @@ public class RootWindowContainerTests extends WindowTestsBase {
}
@Test
public void testGetValidLaunchRootTaskOnDisplayWithCandidateRootTask() {
public void testGetLaunchRootTaskOnSecondaryTaskDisplayArea() {
// Adding another TaskDisplayArea to the default display.
final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
final TaskDisplayArea taskDisplayArea = new TaskDisplayArea(display,
mWm, "TDA", FEATURE_VENDOR_FIRST);
display.addChild(taskDisplayArea, POSITION_BOTTOM);
// Making sure getting the root task from the preferred TDA
LaunchParamsController.LaunchParams launchParams =
new LaunchParamsController.LaunchParams();
launchParams.mPreferredTaskDisplayArea = taskDisplayArea;
Task root = mRootWindowContainer.getLaunchRootTask(null /* r */, null /* options */,
null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
0 /* launchParams */);
assertEquals(taskDisplayArea, root.getTaskDisplayArea());
// Making sure still getting the root task from the preferred TDA when passing in a
// launching activity.
ActivityRecord r = new ActivityBuilder(mAtm).build();
root = mRootWindowContainer.getLaunchRootTask(r, null /* options */,
null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
0 /* launchParams */);
assertEquals(taskDisplayArea, root.getTaskDisplayArea());
}
@Test
public void testGetOrCreateRootTaskOnDisplayWithCandidateRootTask() {
// Create a root task with an activity on secondary display.
final TestDisplayContent secondaryDisplay = new TestDisplayContent.Builder(mAtm, 300,
600).build();
@@ -947,9 +973,9 @@ public class RootWindowContainerTests extends WindowTestsBase {
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
// Make sure the root task is valid and can be reused on default display.
final Task rootTask = mRootWindowContainer.getValidLaunchRootTaskInTaskDisplayArea(
mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task,
null /* options */, null /* launchParams */);
final Task rootTask = mRootWindowContainer.getDefaultTaskDisplayArea().getOrCreateRootTask(
activity, null /* options */, task, null /* sourceTask */, null /* launchParams */,
0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, true /* onTop */);
assertEquals(task, rootTask);
}

View File

@@ -575,7 +575,7 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
final TestDisplayContent fullscreenDisplay = createNewDisplayContent(
WINDOWING_MODE_FULLSCREEN);
final ActivityRecord source = createSourceActivity(fullscreenDisplay);
source.setWindowingMode(WINDOWING_MODE_FREEFORM);
source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM);
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setSource(source).calculate());
@@ -951,7 +951,7 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
final TestDisplayContent fullscreenDisplay = createNewDisplayContent(
WINDOWING_MODE_FULLSCREEN);
final ActivityRecord source = createSourceActivity(fullscreenDisplay);
source.setWindowingMode(WINDOWING_MODE_FREEFORM);
source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM);
final ActivityOptions options = ActivityOptions.makeBasic();
final Rect expected = new Rect(0, 0, 150, 150);