Merge "6/n Manage multiple task display area in the policy" into rvc-dev am: ac4b972e7a

Change-Id: Idbce18de16137bd30e29ca29ada5fbd9dacf57ba
This commit is contained in:
Andrii Kulian
2020-04-08 17:37:30 +00:00
committed by Automerger Merge Worker
13 changed files with 85 additions and 57 deletions

View File

@@ -5215,10 +5215,10 @@ package android.window {
method public void onDisplayAreaAppeared(@NonNull android.window.WindowContainerToken);
method public void onDisplayAreaVanished(@NonNull android.window.WindowContainerToken);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int);
field public static final int FEATURE_DEFAULT_TASK_CONTAINER = 1; // 0x1
field public static final int FEATURE_ROOT = 0; // 0x0
field public static final int FEATURE_SYSTEM_FIRST = 0; // 0x0
field public static final int FEATURE_SYSTEM_LAST = 10000; // 0x2710
field public static final int FEATURE_TASK_CONTAINER = 1; // 0x1
field public static final int FEATURE_UNDEFINED = -1; // 0xffffffff
field public static final int FEATURE_VENDOR_FIRST = 10001; // 0x2711
field public static final int FEATURE_WINDOW_TOKENS = 2; // 0x2

View File

@@ -33,8 +33,8 @@ public class DisplayAreaOrganizer extends WindowOrganizer {
public static final int FEATURE_SYSTEM_FIRST = 0;
// The Root display area on a display
public static final int FEATURE_ROOT = FEATURE_SYSTEM_FIRST;
// Display area hosting the task container.
public static final int FEATURE_TASK_CONTAINER = FEATURE_SYSTEM_FIRST + 1;
// Display area hosting the default task container.
public static final int FEATURE_DEFAULT_TASK_CONTAINER = FEATURE_SYSTEM_FIRST + 1;
// Display area hosting non-activity window tokens.
public static final int FEATURE_WINDOW_TOKENS = FEATURE_SYSTEM_FIRST + 2;

View File

@@ -1469,7 +1469,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
if (toDisplay.getDisplayId() != stack.getDisplayId()) {
stack.reparent(toDisplay.getDefaultTaskDisplayArea(), false /* onTop */);
} else {
toDisplay.mTaskContainers.positionStackAtBottom(stack);
toDisplay.getDefaultTaskDisplayArea().positionStackAtBottom(stack);
}
mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);

View File

@@ -54,7 +54,6 @@ import java.util.function.Predicate;
* - BELOW_TASKS: Can only contain BELOW_TASK DisplayAreas and WindowTokens that go below tasks.
* - ABOVE_TASKS: Can only contain ABOVE_TASK DisplayAreas and WindowTokens that go above tasks.
* - ANY: Can contain any kind of DisplayArea, and any kind of WindowToken or the Task container.
* Cannot have a sibling that is of type ANY.
*
* @param <T> type of the children of the DisplayArea.
*/
@@ -274,7 +273,6 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
ANY;
static void checkSiblings(Type bottom, Type top) {
checkState(!(bottom == ANY && top == ANY), "ANY cannot be a sibling of ANY");
checkState(!(bottom != BELOW_TASKS && top == BELOW_TASKS),
bottom + " must be above BELOW_TASKS");
checkState(!(bottom == ABOVE_TASKS && top != ABOVE_TASKS),

View File

@@ -16,9 +16,14 @@
package com.android.server.wm;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
import android.content.res.Resources;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
/**
* Policy that manages DisplayAreas.
*/
@@ -37,9 +42,9 @@ public abstract class DisplayAreaPolicy {
protected final DisplayArea<? extends WindowContainer> mImeContainer;
/**
* The Tasks container. Tasks etc. are automatically added to this container.
* The task display areas. Tasks etc. are automatically added to these containers.
*/
protected final DisplayArea<? extends ActivityStack> mTaskContainers;
protected final List<TaskDisplayArea> mTaskDisplayAreas;
/**
* Construct a new {@link DisplayAreaPolicy}
@@ -48,19 +53,19 @@ public abstract class DisplayAreaPolicy {
* @param content the display content for which the policy applies
* @param root the root display area under which the policy operates
* @param imeContainer the ime container that the policy must attach
* @param taskDisplayArea the task container that the policy must attach
* @param taskDisplayAreas the task display areas that the policy must attach
*
* @see #attachDisplayAreas()
*/
protected DisplayAreaPolicy(WindowManagerService wmService,
DisplayContent content, DisplayArea.Root root,
DisplayArea<? extends WindowContainer> imeContainer,
DisplayArea<? extends ActivityStack> taskDisplayArea) {
List<TaskDisplayArea> taskDisplayAreas) {
mWmService = wmService;
mContent = content;
mRoot = root;
mImeContainer = imeContainer;
mTaskContainers = taskDisplayArea;
mTaskDisplayAreas = taskDisplayAreas;
}
/**
@@ -80,15 +85,32 @@ public abstract class DisplayAreaPolicy {
*/
public abstract void addWindow(WindowToken token);
/**
* @return the number of task display areas on the display.
*/
public int getTaskDisplayAreaCount() {
return mTaskDisplayAreas.size();
}
/**
* @return the task display area at index.
*/
public TaskDisplayArea getTaskDisplayAreaAt(int index) {
return mTaskDisplayAreas.get(index);
}
/** Provider for platform-default display area policy. */
static final class DefaultProvider implements DisplayAreaPolicy.Provider {
@Override
public DisplayAreaPolicy instantiate(WindowManagerService wmService,
DisplayContent content, DisplayArea.Root root,
DisplayArea<? extends WindowContainer> imeContainer,
TaskDisplayArea taskDisplayArea) {
DisplayArea<? extends WindowContainer> imeContainer) {
final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService,
"DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);
final List<TaskDisplayArea> tdaList = new ArrayList<>();
tdaList.add(defaultTaskDisplayArea);
return new DisplayAreaPolicyBuilder()
.build(wmService, content, root, imeContainer, taskDisplayArea);
.build(wmService, content, root, imeContainer, tdaList);
}
}
@@ -107,8 +129,7 @@ public abstract class DisplayAreaPolicy {
*/
DisplayAreaPolicy instantiate(WindowManagerService wmService,
DisplayContent content, DisplayArea.Root root,
DisplayArea<? extends WindowContainer> imeContainer,
TaskDisplayArea taskDisplayArea);
DisplayArea<? extends WindowContainer> imeContainer);
/**
* Instantiate the device-specific {@link Provider}.

View File

@@ -201,8 +201,8 @@ class DisplayAreaPolicyBuilder {
Result(WindowManagerService wmService, DisplayContent content, DisplayArea.Root root,
DisplayArea<? extends WindowContainer> imeContainer,
DisplayArea<? extends ActivityStack> taskDisplayArea, ArrayList<Feature> features) {
super(wmService, content, root, imeContainer, taskDisplayArea);
List<TaskDisplayArea> taskDisplayAreas, ArrayList<Feature> features) {
super(wmService, content, root, imeContainer, taskDisplayAreas);
mFeatures = features;
mAreas = new HashMap<>(features.size());
for (int i = 0; i < mFeatures.size(); i++) {
@@ -267,7 +267,7 @@ class DisplayAreaPolicyBuilder {
areaForLayer[layer].mChildren.add(leafArea);
leafType = type;
if (leafType == LEAF_TYPE_TASK_CONTAINERS) {
leafArea.mExisting = mTaskContainers;
addTaskDisplayAreasToLayer(areaForLayer[layer], layer);
} else if (leafType == LEAF_TYPE_IME_CONTAINERS) {
leafArea.mExisting = mImeContainer;
}
@@ -278,6 +278,17 @@ class DisplayAreaPolicyBuilder {
root.instantiateChildren(mRoot, mAreaForLayer, 0, mAreas);
}
/** Adds all task display areas to the specified layer */
private void addTaskDisplayAreasToLayer(PendingArea parentPendingArea, int layer) {
final int count = mTaskDisplayAreas.size();
for (int i = 0; i < count; i++) {
PendingArea leafArea = new PendingArea(null, layer, parentPendingArea);
leafArea.mExisting = mTaskDisplayAreas.get(i);
leafArea.mMaxLayer = layer;
parentPendingArea.mChildren.add(leafArea);
}
}
@Override
public void addWindow(WindowToken token) {
DisplayArea.Tokens area = findAreaForToken(token);
@@ -317,12 +328,16 @@ class DisplayAreaPolicyBuilder {
return this;
}
protected List<Feature> getFeatures() {
return mFeatures;
}
Result build(WindowManagerService wmService,
DisplayContent content, DisplayArea.Root root,
DisplayArea<? extends WindowContainer> imeContainer,
DisplayArea<? extends ActivityStack> taskDisplayArea) {
List<TaskDisplayArea> taskDisplayAreas) {
return new Result(wmService, content, root, imeContainer, taskDisplayArea, new ArrayList<>(
return new Result(wmService, content, root, imeContainer, taskDisplayAreas, new ArrayList<>(
mFeatures));
}

View File

@@ -72,6 +72,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
@@ -268,8 +269,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
new NonAppWindowContainers("mOverlayContainers", mWmService);
/** The containers below are the only child containers {@link #mWindowContainers} can have. */
// Contains all window containers that are related to apps (Activities)
final TaskDisplayArea mTaskContainers = new TaskDisplayArea(this, mWmService);
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
@@ -971,7 +970,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
super.addChild(mOverlayContainers, null);
mDisplayAreaPolicy = mWmService.mDisplayAreaPolicyProvider.instantiate(
mWmService, this, mRootDisplayArea, mImeWindowsContainers, mTaskContainers);
mWmService, this, mRootDisplayArea, mImeWindowsContainers);
mWindowContainers.addChildren();
// Sets the display content for the children.
@@ -2069,13 +2068,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
protected int getTaskDisplayAreaCount() {
// TODO(multi-display-area): Report actual display area count
return 1;
return mDisplayAreaPolicy.getTaskDisplayAreaCount();
}
protected TaskDisplayArea getTaskDisplayAreaAt(int index) {
// TODO(multi-display-area): Report actual display area values
return mTaskContainers;
return mDisplayAreaPolicy.getTaskDisplayAreaAt(index);
}
ActivityStack getStack(int rootTaskId) {
@@ -2401,7 +2398,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
* or for cases when multi-instance is not supported yet (like Split-screen, PiP or Recents).
*/
TaskDisplayArea getDefaultTaskDisplayArea() {
return mTaskContainers;
return mDisplayAreaPolicy.getTaskDisplayAreaAt(0);
}
@Override

View File

@@ -31,7 +31,6 @@ import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.window.DisplayAreaOrganizer.FEATURE_TASK_CONTAINER;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
@@ -141,8 +140,9 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
*/
private boolean mRemoved;
TaskDisplayArea(DisplayContent displayContent, WindowManagerService service) {
super(service, Type.ANY, "TaskContainers", FEATURE_TASK_CONTAINER);
TaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name,
int displayAreaFeature) {
super(service, Type.ANY, name, displayAreaFeature);
mDisplayContent = displayContent;
mRootWindowContainer = service.mRoot;
mAtmService = service.mAtmService;

View File

@@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
import static com.android.server.wm.DisplayArea.Type.ANY;
@@ -72,7 +73,11 @@ public class DisplayAreaPolicyBuilderTest {
WindowManagerService wms = mSystemServices.getWindowManagerService();
DisplayArea.Root root = new SurfacelessDisplayAreaRoot(wms);
DisplayArea<WindowContainer> ime = new DisplayArea<>(wms, ABOVE_TASKS, "Ime");
DisplayArea<ActivityStack> tasks = new DisplayArea<>(wms, ANY, "Tasks");
DisplayContent displayContent = mock(DisplayContent.class);
TaskDisplayArea taskDisplayArea = new TaskDisplayArea(displayContent, wms, "Tasks",
FEATURE_DEFAULT_TASK_CONTAINER);
List<TaskDisplayArea> taskDisplayAreaList = new ArrayList<>();
taskDisplayAreaList.add(taskDisplayArea);
final Feature foo;
final Feature bar;
@@ -86,7 +91,7 @@ public class DisplayAreaPolicyBuilderTest {
.all()
.except(TYPE_STATUS_BAR)
.build())
.build(wms, mock(DisplayContent.class), root, ime, tasks);
.build(wms, displayContent, root, ime, taskDisplayAreaList);
policy.attachDisplayAreas();
@@ -98,9 +103,9 @@ public class DisplayAreaPolicyBuilderTest {
assertThat(policy.findAreaForToken(tokenOfType(TYPE_STATUS_BAR)),
is(not(decendantOfOneOf(policy.getDisplayAreas(bar)))));
assertThat(tasks,
assertThat(taskDisplayArea,
is(decendantOfOneOf(policy.getDisplayAreas(foo))));
assertThat(tasks,
assertThat(taskDisplayArea,
is(decendantOfOneOf(policy.getDisplayAreas(bar))));
assertThat(ime,
@@ -109,7 +114,8 @@ public class DisplayAreaPolicyBuilderTest {
is(decendantOfOneOf(policy.getDisplayAreas(bar))));
List<DisplayArea<?>> actualOrder = collectLeafAreas(root);
Map<DisplayArea<?>, Set<Integer>> zSets = calculateZSets(policy, root, ime, tasks);
Map<DisplayArea<?>, Set<Integer>> zSets = calculateZSets(policy, root, ime,
taskDisplayArea);
actualOrder = actualOrder.stream().filter(zSets::containsKey).collect(toList());
Map<DisplayArea<?>, Integer> expectedByMinLayer = mapValues(zSets,

View File

@@ -77,8 +77,7 @@ public class DisplayAreaProviderTest {
@Override
public DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,
DisplayArea.Root root, DisplayArea<? extends WindowContainer> imeContainer,
TaskDisplayArea taskDisplayArea) {
DisplayArea.Root root, DisplayArea<? extends WindowContainer> imeContainer) {
throw new RuntimeException("test stub");
}
}

View File

@@ -53,17 +53,6 @@ public class DisplayAreaTest {
assertThrows(IllegalStateException.class, () -> parent.addChild(child, 0));
}
@Test
public void testDisplayArea_positionChanged_throwsIfIncompatibleSibling() {
WindowManagerService wms = mWmsRule.getWindowManagerService();
DisplayArea<WindowContainer> parent = new SurfacelessDisplayArea<>(wms, ANY, "Parent");
DisplayArea<WindowContainer> child1 = new DisplayArea<>(wms, ANY, "Child1");
DisplayArea<WindowContainer> child2 = new DisplayArea<>(wms, ANY, "Child2");
parent.addChild(child1, 0);
assertThrows(IllegalStateException.class, () -> parent.addChild(child2, 0));
}
@Test
public void testType_typeOf() {
WindowManagerService wms = mWmsRule.getWindowManagerService();
@@ -87,10 +76,10 @@ public class DisplayAreaTest {
checkSiblings(BELOW_TASKS, ABOVE_TASKS);
checkSiblings(ANY, ABOVE_TASKS);
checkSiblings(ABOVE_TASKS, ABOVE_TASKS);
checkSiblings(ANY, ANY);
assertThrows(IllegalStateException.class, () -> checkSiblings(ABOVE_TASKS, BELOW_TASKS));
assertThrows(IllegalStateException.class, () -> checkSiblings(ABOVE_TASKS, ANY));
assertThrows(IllegalStateException.class, () -> checkSiblings(ANY, ANY));
assertThrows(IllegalStateException.class, () -> checkSiblings(ANY, BELOW_TASKS));
}

View File

@@ -51,10 +51,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}.
* Tests for the {@link TaskDisplayArea} container.
*
* Build/Install/Run:
* atest WmTests:TaskStackContainersTests
* atest WmTests:TaskDisplayAreaTests
*/
@SmallTest
@Presubmit
@@ -154,8 +154,9 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
ACTIVITY_TYPE_STANDARD, mDisplayContent);
final Task newStack = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);
doReturn(newStack).when(mDisplayContent.mTaskContainers).createStack(anyInt(),
anyInt(), anyBoolean(), any(), any(), anyBoolean());
final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();
doReturn(newStack).when(taskDisplayArea).createStack(anyInt(), anyInt(), anyBoolean(),
any(), any(), anyBoolean());
final int type = ACTIVITY_TYPE_STANDARD;
assertGetOrCreateStack(WINDOWING_MODE_FULLSCREEN, type, candidateTask,
@@ -186,7 +187,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask,
boolean reuseCandidate) {
final TaskDisplayArea taskDisplayArea = (TaskDisplayArea) candidateTask.getParent();
final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();
final ActivityStack stack = taskDisplayArea.getOrCreateStack(windowingMode, activityType,
false /* onTop */, null /* intent */, candidateTask /* candidateTask */);
assertEquals(reuseCandidate, stack == candidateTask);

View File

@@ -43,7 +43,9 @@ class TestDisplayContent extends DisplayContent {
// hard-code to FULLSCREEN for tests.
setWindowingMode(WINDOWING_MODE_FULLSCREEN);
spyOn(this);
spyOn(mTaskContainers);
for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
spyOn(getTaskDisplayAreaAt(i));
}
final DisplayRotation displayRotation = getDisplayRotation();
spyOn(displayRotation);