Add enforcement for unique displayarea id
Fix: 173513713 Test: atest WmTests:DisplayAreaPolicyBuilderTest Change-Id: Ia11be2b4bc49c6c23d17f2501c3fda53c9540720
This commit is contained in:
@@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
|
||||
import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_LAST;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Bundle;
|
||||
@@ -166,32 +167,48 @@ class DisplayAreaPolicyBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Makes sure the setting meets the requirement. */
|
||||
/**
|
||||
* Makes sure the setting meets the requirement:
|
||||
* 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.
|
||||
* 5. There must be exactly one {@link HierarchyBuilder} that contains the default
|
||||
* {@link TaskDisplayArea} with id {@link FEATURE_DEFAULT_TASK_CONTAINER}.
|
||||
* 6. None of the ids is greater than {@link FEATURE_VENDOR_LAST}.
|
||||
*/
|
||||
private void validate() {
|
||||
if (mRootHierarchyBuilder == null) {
|
||||
throw new IllegalStateException("Root must be set for the display area policy.");
|
||||
}
|
||||
|
||||
final Set<Integer> rootIdSet = new ArraySet<>();
|
||||
rootIdSet.add(mRootHierarchyBuilder.mRoot.mFeatureId);
|
||||
final Set<Integer> uniqueIdSet = new ArraySet<>();
|
||||
final Set<Integer> allIdSet = new ArraySet<>();
|
||||
validateIds(mRootHierarchyBuilder, uniqueIdSet, allIdSet);
|
||||
boolean containsImeContainer = mRootHierarchyBuilder.mImeContainer != null;
|
||||
boolean containsDefaultTda = containsDefaultTaskDisplayArea(mRootHierarchyBuilder);
|
||||
for (int i = 0; i < mDisplayAreaGroupHierarchyBuilders.size(); i++) {
|
||||
HierarchyBuilder hierarchyBuilder = mDisplayAreaGroupHierarchyBuilders.get(i);
|
||||
if (!rootIdSet.add(hierarchyBuilder.mRoot.mFeatureId)) {
|
||||
throw new IllegalStateException("There should not be two RootDisplayAreas with id "
|
||||
+ hierarchyBuilder.mRoot.mFeatureId);
|
||||
}
|
||||
validateIds(hierarchyBuilder, uniqueIdSet, allIdSet);
|
||||
|
||||
if (hierarchyBuilder.mTaskDisplayAreas.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"DisplayAreaGroup must contain at least one TaskDisplayArea.");
|
||||
}
|
||||
|
||||
containsImeContainer = containsImeContainer || hierarchyBuilder.mImeContainer != null;
|
||||
if (containsImeContainer) {
|
||||
if (hierarchyBuilder.mImeContainer != null) {
|
||||
throw new IllegalStateException(
|
||||
"Only one DisplayArea hierarchy can contain the IME container");
|
||||
}
|
||||
} else {
|
||||
containsImeContainer = hierarchyBuilder.mImeContainer != null;
|
||||
}
|
||||
|
||||
if (containsDefaultTda) {
|
||||
if (containsDefaultTaskDisplayArea(hierarchyBuilder)) {
|
||||
throw new IllegalStateException("Only one TaskDisplayArea can have the feature "
|
||||
+ "of FEATURE_DEFAULT_TASK_CONTAINER");
|
||||
+ "id of FEATURE_DEFAULT_TASK_CONTAINER");
|
||||
}
|
||||
} else {
|
||||
containsDefaultTda = containsDefaultTaskDisplayArea(hierarchyBuilder);
|
||||
@@ -203,7 +220,8 @@ class DisplayAreaPolicyBuilder {
|
||||
}
|
||||
|
||||
if (!containsDefaultTda) {
|
||||
throw new IllegalStateException("There must be a default TaskDisplayArea.");
|
||||
throw new IllegalStateException("There must be a default TaskDisplayArea with id of "
|
||||
+ "FEATURE_DEFAULT_TASK_CONTAINER.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +236,67 @@ class DisplayAreaPolicyBuilder {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that ids meet requirement.
|
||||
* {@link RootDisplayArea} and {@link TaskDisplayArea} must have unique ids.
|
||||
* {@link Feature} below the same {@link RootDisplayArea} must have unique ids, but
|
||||
* {@link Feature} below different {@link RootDisplayArea} can have the same id so that we can
|
||||
* organize them together.
|
||||
* None of the ids is greater than {@link FEATURE_VENDOR_LAST}
|
||||
*
|
||||
* @param uniqueIdSet ids of {@link RootDisplayArea} and {@link TaskDisplayArea} that must be
|
||||
* unique,
|
||||
* @param allIdSet ids of {@link RootDisplayArea}, {@link TaskDisplayArea} and {@link Feature}.
|
||||
*/
|
||||
private static void validateIds(HierarchyBuilder displayAreaHierarchy,
|
||||
Set<Integer> uniqueIdSet, Set<Integer> allIdSet) {
|
||||
// Root must have unique id.
|
||||
final int rootId = displayAreaHierarchy.mRoot.mFeatureId;
|
||||
if (!allIdSet.add(rootId) || !uniqueIdSet.add(rootId)) {
|
||||
throw new IllegalStateException(
|
||||
"RootDisplayArea must have unique id, but id=" + rootId + " is not unique.");
|
||||
}
|
||||
if (rootId > FEATURE_VENDOR_LAST) {
|
||||
throw new IllegalStateException(
|
||||
"RootDisplayArea should not have an id greater than FEATURE_VENDOR_LAST.");
|
||||
}
|
||||
|
||||
// TDAs must have unique id.
|
||||
for (int i = 0; i < displayAreaHierarchy.mTaskDisplayAreas.size(); i++) {
|
||||
final int taskDisplayAreaId = displayAreaHierarchy.mTaskDisplayAreas.get(i).mFeatureId;
|
||||
if (!allIdSet.add(taskDisplayAreaId) || !uniqueIdSet.add(taskDisplayAreaId)) {
|
||||
throw new IllegalStateException("TaskDisplayArea must have unique id, but id="
|
||||
+ taskDisplayAreaId + " is not unique.");
|
||||
}
|
||||
if (taskDisplayAreaId > FEATURE_VENDOR_LAST) {
|
||||
throw new IllegalStateException("TaskDisplayArea declared in the policy should not"
|
||||
+ "have an id greater than FEATURE_VENDOR_LAST.");
|
||||
}
|
||||
}
|
||||
|
||||
// Features below the same root must have unique ids.
|
||||
final Set<Integer> featureIdSet = new ArraySet<>();
|
||||
for (int i = 0; i < displayAreaHierarchy.mFeatures.size(); i++) {
|
||||
final int featureId = displayAreaHierarchy.mFeatures.get(i).getId();
|
||||
if (uniqueIdSet.contains(featureId)) {
|
||||
throw new IllegalStateException("Feature must not have same id with any "
|
||||
+ "RootDisplayArea or TaskDisplayArea, but id=" + featureId + " is used");
|
||||
}
|
||||
if (!featureIdSet.add(featureId)) {
|
||||
throw new IllegalStateException("Feature below the same root must have unique id, "
|
||||
+ "but id=" + featureId + " is not unique.");
|
||||
}
|
||||
if (featureId > FEATURE_VENDOR_LAST) {
|
||||
throw new IllegalStateException(
|
||||
"Feature should not have an id greater than FEATURE_VENDOR_LAST.");
|
||||
}
|
||||
}
|
||||
|
||||
// Features below different roots can have the same id so that we can organize them
|
||||
// together.
|
||||
allIdSet.addAll(featureIdSet);
|
||||
}
|
||||
|
||||
Result build(WindowManagerService wmService) {
|
||||
validate();
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_LAST;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
|
||||
|
||||
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
|
||||
@@ -114,11 +115,13 @@ public class DisplayAreaPolicyBuilderTest {
|
||||
final Feature bar;
|
||||
DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
|
||||
new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.addFeature(foo = new Feature.Builder(mPolicy, "Foo", 0)
|
||||
.addFeature(foo = new Feature.Builder(mPolicy, "Foo",
|
||||
FEATURE_VENDOR_FIRST)
|
||||
.upTo(TYPE_STATUS_BAR)
|
||||
.and(TYPE_NAVIGATION_BAR)
|
||||
.build())
|
||||
.addFeature(bar = new Feature.Builder(mPolicy, "Bar", 1)
|
||||
.addFeature(bar = new Feature.Builder(mPolicy, "Bar",
|
||||
FEATURE_VENDOR_FIRST + 1)
|
||||
.all()
|
||||
.except(TYPE_STATUS_BAR)
|
||||
.build())
|
||||
@@ -240,12 +243,14 @@ public class DisplayAreaPolicyBuilderTest {
|
||||
final Feature other;
|
||||
DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
|
||||
new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.addFeature(dimmable = new Feature.Builder(mPolicy, "Dimmable", 0)
|
||||
.addFeature(dimmable = new Feature.Builder(mPolicy, "Dimmable",
|
||||
FEATURE_VENDOR_FIRST)
|
||||
.upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
|
||||
.except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
|
||||
.setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)
|
||||
.build())
|
||||
.addFeature(other = new Feature.Builder(mPolicy, "Other", 1)
|
||||
.addFeature(other = new Feature.Builder(mPolicy, "Other",
|
||||
FEATURE_VENDOR_FIRST + 1)
|
||||
.all()
|
||||
.build())
|
||||
.setImeContainer(mImeContainer)
|
||||
@@ -313,9 +318,7 @@ public class DisplayAreaPolicyBuilderTest {
|
||||
builder2.addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(
|
||||
mGroupRoot1)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(Lists.newArrayList(
|
||||
new TaskDisplayArea(mDisplayContent, mWms, "testTda",
|
||||
FEATURE_VENDOR_FIRST + 1))));
|
||||
.setTaskDisplayAreas(Lists.newArrayList(mTda1)));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
|
||||
|
||||
@@ -340,13 +343,146 @@ public class DisplayAreaPolicyBuilderTest {
|
||||
.setTaskDisplayAreas(mTaskDisplayAreaList));
|
||||
builder4.addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(
|
||||
mGroupRoot2)
|
||||
.setTaskDisplayAreas(Lists.newArrayList(
|
||||
new TaskDisplayArea(mDisplayContent, mWms, "testTda",
|
||||
FEATURE_VENDOR_FIRST + 1))));
|
||||
.setTaskDisplayAreas(Lists.newArrayList(mTda1)));
|
||||
|
||||
builder4.build(mWms);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_rootHasUniqueId() {
|
||||
// Root must have different id from all roots.
|
||||
final DisplayAreaPolicyBuilder builder1 = new DisplayAreaPolicyBuilder();
|
||||
builder1.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(mTaskDisplayAreaList));
|
||||
final RootDisplayArea groupRoot1 = new SurfacelessDisplayAreaRoot(mWms, "group1",
|
||||
mRoot.mFeatureId);
|
||||
builder1.addDisplayAreaGroupHierarchy(
|
||||
new DisplayAreaPolicyBuilder.HierarchyBuilder(groupRoot1)
|
||||
.setTaskDisplayAreas(Lists.newArrayList(mTda1)));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder1.build(mWms));
|
||||
|
||||
// Root must have different id from all TDAs.
|
||||
final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
|
||||
builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(Lists.newArrayList(
|
||||
mDefaultTaskDisplayArea,
|
||||
new TaskDisplayArea(mDisplayContent, mWms, "testTda",
|
||||
mRoot.mFeatureId))));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
|
||||
|
||||
// Root must have different id from all features.
|
||||
final DisplayAreaPolicyBuilder builder3 = new DisplayAreaPolicyBuilder();
|
||||
builder3.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(mTaskDisplayAreaList)
|
||||
.addFeature(new Feature.Builder(mPolicy, "testFeature", mRoot.mFeatureId)
|
||||
.all()
|
||||
.build()));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder3.build(mWms));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_taskDisplayAreaHasUniqueId() {
|
||||
// TDA must have different id from all TDAs.
|
||||
final DisplayAreaPolicyBuilder builder = new DisplayAreaPolicyBuilder();
|
||||
final List<TaskDisplayArea> tdaList = Lists.newArrayList(
|
||||
mDefaultTaskDisplayArea,
|
||||
mTda1,
|
||||
new TaskDisplayArea(mDisplayContent, mWms, "tda2", mTda1.mFeatureId));
|
||||
builder.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(tdaList));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder.build(mWms));
|
||||
|
||||
// TDA must have different id from all features.
|
||||
final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
|
||||
builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(Lists.newArrayList(
|
||||
mDefaultTaskDisplayArea,
|
||||
mTda1))
|
||||
.addFeature(new Feature.Builder(mPolicy, "testFeature", mTda1.mFeatureId)
|
||||
.all()
|
||||
.build()));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_featureHasUniqueId() {
|
||||
// Feature must have different id from features below the same root.
|
||||
final DisplayAreaPolicyBuilder builder = new DisplayAreaPolicyBuilder();
|
||||
builder.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(mTaskDisplayAreaList)
|
||||
.addFeature(new Feature.Builder(mPolicy, "feature1", FEATURE_VENDOR_FIRST + 10)
|
||||
.all()
|
||||
.build())
|
||||
.addFeature(new Feature.Builder(mPolicy, "feature2", FEATURE_VENDOR_FIRST + 10)
|
||||
.upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
|
||||
.build()));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder.build(mWms));
|
||||
|
||||
// Features below different root can have the same id.
|
||||
final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
|
||||
builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(mTaskDisplayAreaList)
|
||||
.addFeature(new Feature.Builder(mPolicy, "feature1", FEATURE_VENDOR_FIRST + 10)
|
||||
.all()
|
||||
.build()));
|
||||
builder2.addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(
|
||||
mGroupRoot1)
|
||||
.setTaskDisplayAreas(Lists.newArrayList(mTda1))
|
||||
.addFeature(new Feature.Builder(mPolicy, "feature2", FEATURE_VENDOR_FIRST + 10)
|
||||
.all()
|
||||
.build()));
|
||||
|
||||
builder2.build(mWms);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_idsNotGreaterThanFeatureVendorLast() {
|
||||
// Root id should not be greater than FEATURE_VENDOR_LAST.
|
||||
final DisplayAreaPolicyBuilder builder1 = new DisplayAreaPolicyBuilder();
|
||||
final RootDisplayArea root = new SurfacelessDisplayAreaRoot(mWms, "testRoot",
|
||||
FEATURE_VENDOR_LAST + 1);
|
||||
builder1.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(mTaskDisplayAreaList));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder1.build(mWms));
|
||||
|
||||
// TDA id should not be greater than FEATURE_VENDOR_LAST.
|
||||
final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
|
||||
builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(Lists.newArrayList(
|
||||
mDefaultTaskDisplayArea,
|
||||
new TaskDisplayArea(mDisplayContent, mWms, "testTda",
|
||||
FEATURE_VENDOR_LAST + 1))));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
|
||||
|
||||
// Feature id should not be greater than FEATURE_VENDOR_LAST.
|
||||
final DisplayAreaPolicyBuilder builder3 = new DisplayAreaPolicyBuilder();
|
||||
builder3.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
|
||||
.setImeContainer(mImeContainer)
|
||||
.setTaskDisplayAreas(mTaskDisplayAreaList)
|
||||
.addFeature(new Feature.Builder(mPolicy, "testFeature", FEATURE_VENDOR_LAST + 1)
|
||||
.all()
|
||||
.build()));
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> builder3.build(mWms));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilder_displayAreaGroup_attachDisplayAreas() {
|
||||
final DisplayAreaPolicyBuilder.Result policy = new DisplayAreaPolicyBuilder()
|
||||
|
||||
Reference in New Issue
Block a user