Merge "Add default selectRootForWindow function for target root id" into sc-dev

This commit is contained in:
Chris Li
2021-02-25 06:37:34 +00:00
committed by Android (Google) Code Review
2 changed files with 93 additions and 27 deletions

View File

@@ -67,39 +67,40 @@ import java.util.function.BiFunction;
* .setImeContainer(imeContainer)
* .setTaskDisplayAreas(rootTdaList);
*
* // Build root hierarchy of front and rear DisplayAreaGroup.
* RootDisplayArea frontRoot = new RootDisplayArea(wmService, "FrontRoot", FEATURE_FRONT_ROOT);
* DisplayAreaPolicyBuilder.HierarchyBuilder frontGroupHierarchy =
* new DisplayAreaPolicyBuilder.HierarchyBuilder(frontRoot)
* // Build root hierarchy of first and second DisplayAreaGroup.
* RootDisplayArea firstRoot = new RootDisplayArea(wmService, "FirstRoot", FEATURE_FIRST_ROOT);
* DisplayAreaPolicyBuilder.HierarchyBuilder firstGroupHierarchy =
* new DisplayAreaPolicyBuilder.HierarchyBuilder(firstRoot)
* // (Optional) .addFeature(...)
* .setTaskDisplayAreas(frontTdaList);
* .setTaskDisplayAreas(firstTdaList);
*
* RootDisplayArea rearRoot = new RootDisplayArea(wmService, "RearRoot", FEATURE_REAR_ROOT);
* DisplayAreaPolicyBuilder.HierarchyBuilder rearGroupHierarchy =
* new DisplayAreaPolicyBuilder.HierarchyBuilder(rearRoot)
* RootDisplayArea secondRoot = new RootDisplayArea(wmService, "SecondRoot",
* FEATURE_REAR_ROOT);
* DisplayAreaPolicyBuilder.HierarchyBuilder secondGroupHierarchy =
* new DisplayAreaPolicyBuilder.HierarchyBuilder(secondRoot)
* // (Optional) .addFeature(...)
* .setTaskDisplayAreas(rearTdaList);
* .setTaskDisplayAreas(secondTdaList);
*
* // Define the function to select root for window to attach.
* BiFunction<WindowToken, Bundle, RootDisplayArea> selectRootForWindowFunc =
* (windowToken, bundle) -> {
* if (bundle == null) {
* (windowToken, options) -> {
* if (options == null) {
* return root;
* }
* // OEMs need to define the condition.
* if (...) {
* return frontRoot;
* return firstRoot;
* }
* if (...) {
* return rearRoot;
* return secondRoot;
* }
* return root;
* };
*
* return new DisplayAreaPolicyBuilder()
* .setRootHierarchy(rootHierarchy)
* .addDisplayAreaGroupHierarchy(frontGroupHierarchy)
* .addDisplayAreaGroupHierarchy(rearGroupHierarchy)
* .addDisplayAreaGroupHierarchy(firstGroupHierarchy)
* .addDisplayAreaGroupHierarchy(secondGroupHierarchy)
* .setSelectRootForWindowFunc(selectRootForWindowFunc)
* .build(wmService, content);
* </pre>
@@ -110,12 +111,12 @@ import java.util.function.BiFunction;
* - WindowedMagnification
* - DisplayArea.Tokens (Wallpapers can be attached here)
* - TaskDisplayArea
* - RootDisplayArea (FrontRoot)
* - RootDisplayArea (FirstRoot)
* - DisplayArea.Tokens (Wallpapers can be attached here)
* - TaskDisplayArea
* - DisplayArea.Tokens (windows above Tasks up to IME can be attached here)
* - DisplayArea.Tokens (windows above IME can be attached here)
* - RootDisplayArea (RearRoot)
* - RootDisplayArea (SecondRoot)
* - DisplayArea.Tokens (Wallpapers can be attached here)
* - TaskDisplayArea
* - DisplayArea.Tokens (windows above Tasks up to IME can be attached here)
@@ -133,14 +134,23 @@ import java.util.function.BiFunction;
* {@link RootDisplayArea}.
*/
class DisplayAreaPolicyBuilder {
/**
* Key to specify the {@link RootDisplayArea} to attach the window to. Should be used by the
* function passed in from {@link #setSelectRootForWindowFunc(BiFunction)}
*/
static final String KEY_ROOT_DISPLAY_AREA_ID = "root_display_area_id";
@Nullable private HierarchyBuilder mRootHierarchyBuilder;
private ArrayList<HierarchyBuilder> mDisplayAreaGroupHierarchyBuilders = new ArrayList<>();
private final ArrayList<HierarchyBuilder> mDisplayAreaGroupHierarchyBuilders =
new ArrayList<>();
/**
* When a window is created, the policy will use this function, which takes window type and
* options, to select the {@link RootDisplayArea} to place that window in. The selected root
* can be either the one of the {@link #mRootHierarchyBuilder} or the one of any of the
* {@link #mDisplayAreaGroupHierarchyBuilders}.
* @see DefaultSelectRootForWindowFunction as an example.
**/
@Nullable private BiFunction<Integer, Bundle, RootDisplayArea> mSelectRootForWindowFunc;
@@ -160,7 +170,10 @@ class DisplayAreaPolicyBuilder {
return this;
}
/** The policy will use this function to find the root to place windows in. */
/**
* The policy will use this function to find the root to place windows in.
* @see DefaultSelectRootForWindowFunction as an example.
*/
DisplayAreaPolicyBuilder setSelectRootForWindowFunc(
BiFunction<Integer, Bundle, RootDisplayArea> selectRootForWindowFunc) {
mSelectRootForWindowFunc = selectRootForWindowFunc;
@@ -169,7 +182,7 @@ class DisplayAreaPolicyBuilder {
/**
* Makes sure the setting meets the requirement:
* 1. {@link mRootHierarchyBuilder} must be set.
* 1. {@link #mRootHierarchyBuilder} must be set.
* 2. {@link RootDisplayArea} and {@link TaskDisplayArea} must have unique ids.
* 3. {@link Feature} below the same {@link RootDisplayArea} must have unique ids.
* 4. There must be exactly one {@link HierarchyBuilder} that contains the IME container.
@@ -309,10 +322,56 @@ class DisplayAreaPolicyBuilder {
hierarchyBuilder.build();
displayAreaGroupRoots.add(hierarchyBuilder.mRoot);
}
// Use the default function if it is not specified otherwise.
if (mSelectRootForWindowFunc == null) {
mSelectRootForWindowFunc = new DefaultSelectRootForWindowFunction(
mRootHierarchyBuilder.mRoot, displayAreaGroupRoots);
}
return new Result(wmService, mRootHierarchyBuilder.mRoot, displayAreaGroupRoots,
mSelectRootForWindowFunc);
}
/**
* The default function to be used for finding {@link RootDisplayArea} for window to be attached
* to if there is no other function set through {@link #setSelectRootForWindowFunc(BiFunction)}.
*
* When a window is created with {@link Bundle} options, this function will select the
* {@link RootDisplayArea} based on the options. Returns {@link #mDisplayRoot} if there is no
* match found.
*/
private static class DefaultSelectRootForWindowFunction implements
BiFunction<Integer, Bundle, RootDisplayArea> {
final RootDisplayArea mDisplayRoot;
final List<RootDisplayArea> mDisplayAreaGroupRoots;
DefaultSelectRootForWindowFunction(RootDisplayArea displayRoot,
List<RootDisplayArea> displayAreaGroupRoots) {
mDisplayRoot = displayRoot;
mDisplayAreaGroupRoots = Collections.unmodifiableList(displayAreaGroupRoots);
}
@Override
public RootDisplayArea apply(Integer windowType, Bundle options) {
if (mDisplayAreaGroupRoots.isEmpty()) {
return mDisplayRoot;
}
// Select the RootDisplayArea set in options.
if (options != null && options.containsKey(KEY_ROOT_DISPLAY_AREA_ID)) {
final int rootId = options.getInt(KEY_ROOT_DISPLAY_AREA_ID);
if (mDisplayRoot.mFeatureId == rootId) {
return mDisplayRoot;
}
for (int i = mDisplayAreaGroupRoots.size() - 1; i >= 0; i--) {
if (mDisplayAreaGroupRoots.get(i).mFeatureId == rootId) {
return mDisplayAreaGroupRoots.get(i);
}
}
}
return mDisplayRoot;
}
}
/**
* Builder to define {@link Feature} and {@link DisplayArea} hierarchy under a
* {@link RootDisplayArea}
@@ -672,15 +731,10 @@ class DisplayAreaPolicyBuilder {
Result(WindowManagerService wmService, RootDisplayArea root,
List<RootDisplayArea> displayAreaGroupRoots,
@Nullable BiFunction<Integer, Bundle, RootDisplayArea>
selectRootForWindowFunc) {
BiFunction<Integer, Bundle, RootDisplayArea> selectRootForWindowFunc) {
super(wmService, root);
mDisplayAreaGroupRoots = Collections.unmodifiableList(displayAreaGroupRoots);
mSelectRootForWindowFunc = selectRootForWindowFunc == null
// Always return the highest level root of the logical display when the func is
// not specified.
? (type, options) -> mRoot
: selectRootForWindowFunc;
mSelectRootForWindowFunc = selectRootForWindowFunc;
// Cache the default TaskDisplayArea for quick access.
mDefaultTaskDisplayArea = mRoot.getItemFromTaskDisplayAreas(taskDisplayArea ->

View File

@@ -38,6 +38,7 @@ import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature;
import static com.android.server.wm.DisplayAreaPolicyBuilder.KEY_ROOT_DISPLAY_AREA_ID;
import static com.google.common.truth.Truth.assertThat;
@@ -595,6 +596,17 @@ public class DisplayAreaPolicyBuilderTest {
assertThat(token.isDescendantOf(mRoot)).isTrue();
assertThat(token.isDescendantOf(mGroupRoot1)).isFalse();
assertThat(token.isDescendantOf(mGroupRoot2)).isFalse();
// When the window has options for target root id, attach it to the target root.
final Bundle options = new Bundle();
options.putInt(KEY_ROOT_DISPLAY_AREA_ID, mGroupRoot2.mFeatureId);
final WindowToken token2 = new WindowToken(mWms, mock(IBinder.class),
TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent,
true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */,
false /* fromClientToken */, options);
policy.addWindow(token2);
assertThat(token2.isDescendantOf(mGroupRoot2)).isTrue();
}
@Test