Loading services/core/java/com/android/server/wm/DisplayArea.java +11 −2 Original line number Diff line number Diff line Loading @@ -266,11 +266,20 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { * Top-most DisplayArea under DisplayContent. */ public static class Root extends DisplayArea<DisplayArea> { Root(WindowManagerService wms) { super(wms, Type.ANY, "DisplayArea.Root", FEATURE_ROOT); } } /** * DisplayArea that can be dimmed. */ static class Dimmable extends DisplayArea<DisplayArea> { private final Dimmer mDimmer = new Dimmer(this); private final Rect mTmpDimBoundsRect = new Rect(); Root(WindowManagerService wms) { super(wms, Type.ANY, "DisplayArea.Root", FEATURE_ROOT); Dimmable(WindowManagerService wms, Type type, String name, int featureId) { super(wms, type, name, featureId); } @Override Loading services/core/java/com/android/server/wm/DisplayAreaPolicy.java +3 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,9 @@ public abstract class DisplayAreaPolicy { "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION) .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) // Make the DA dimmable so that the magnify window also mirrors the dim // layer .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new) .build()) .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy, "OneHanded", FEATURE_ONE_HANDED) Loading services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java +23 −4 Original line number Diff line number Diff line Loading @@ -68,6 +68,12 @@ class DisplayAreaPolicyBuilder { private final ArrayList<Feature> mFeatures = new ArrayList<>(); /** Supplier interface to provide a new created {@link DisplayArea}. */ interface NewDisplayAreaSupplier { DisplayArea create(WindowManagerService wms, DisplayArea.Type type, String name, int featureId); } /** * A feature that requires {@link DisplayArea DisplayArea(s)}. */ Loading @@ -75,11 +81,14 @@ class DisplayAreaPolicyBuilder { private final String mName; private final int mId; private final boolean[] mWindowLayers; private final NewDisplayAreaSupplier mNewDisplayAreaSupplier; private Feature(String name, int id, boolean[] windowLayers) { private Feature(String name, int id, boolean[] windowLayers, NewDisplayAreaSupplier newDisplayAreaSupplier) { mName = name; mId = id; mWindowLayers = windowLayers; mNewDisplayAreaSupplier = newDisplayAreaSupplier; } /** Loading @@ -104,6 +113,7 @@ class DisplayAreaPolicyBuilder { private final String mName; private final int mId; private final boolean[] mLayers; private NewDisplayAreaSupplier mNewDisplayAreaSupplier = DisplayArea::new; /** * Build a new feature that applies to a set of window types as specified by the builder Loading Loading @@ -168,8 +178,17 @@ class DisplayAreaPolicyBuilder { return this; } /** * Sets the function to create new {@link DisplayArea} for this feature. By default, it * uses {@link DisplayArea}'s constructor. */ Builder setNewDisplayAreaSupplier(NewDisplayAreaSupplier newDisplayAreaSupplier) { mNewDisplayAreaSupplier = newDisplayAreaSupplier; return this; } Feature build() { return new Feature(mName, mId, mLayers.clone()); return new Feature(mName, mId, mLayers.clone(), mNewDisplayAreaSupplier); } private void set(int type, boolean value) { Loading Loading @@ -416,8 +435,8 @@ class DisplayAreaPolicyBuilder { } return leaf; } else { return new DisplayArea(parent.mWmService, type, mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer, mFeature.mId); return mFeature.mNewDisplayAreaSupplier.create(parent.mWmService, type, mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer, mFeature.mId); } } } Loading services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java +64 −28 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; Loading @@ -32,10 +33,12 @@ import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.testng.Assert.assertFalse; import static java.util.stream.Collectors.toList; Loading @@ -48,6 +51,7 @@ import androidx.test.filters.FlakyTest; import org.hamcrest.CustomTypeSafeMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -61,6 +65,10 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; /** * Build/Install/Run: * atest WmTests:DisplayAreaPolicyBuilderTest */ @Presubmit public class DisplayAreaPolicyBuilderTest { Loading @@ -68,19 +76,28 @@ public class DisplayAreaPolicyBuilderTest { public final SystemServicesTestRule mSystemServices = new SystemServicesTestRule(); private TestWindowManagerPolicy mPolicy = new TestWindowManagerPolicy(null, null); private WindowManagerService mWms; private DisplayArea.Root mRoot; private DisplayArea<WindowContainer> mImeContainer; private DisplayContent mDisplayContent; private TaskDisplayArea mDefaultTaskDisplayArea; private List<TaskDisplayArea> mTaskDisplayAreaList; @Before public void setup() { mWms = mSystemServices.getWindowManagerService(); mRoot = new SurfacelessDisplayAreaRoot(mWms); mImeContainer = new DisplayArea<>(mWms, ABOVE_TASKS, "Ime"); mDisplayContent = mock(DisplayContent.class); mDefaultTaskDisplayArea = new TaskDisplayArea(mDisplayContent, mWms, "Tasks", FEATURE_DEFAULT_TASK_CONTAINER); mTaskDisplayAreaList = new ArrayList<>(); mTaskDisplayAreaList.add(mDefaultTaskDisplayArea); } @Test @FlakyTest(bugId = 149760939) public void testBuilder() { WindowManagerService wms = mSystemServices.getWindowManagerService(); DisplayArea.Root root = new SurfacelessDisplayAreaRoot(wms); DisplayArea<WindowContainer> ime = new DisplayArea<>(wms, ABOVE_TASKS, "Ime"); 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; Loading @@ -93,7 +110,7 @@ public class DisplayAreaPolicyBuilderTest { .all() .except(TYPE_STATUS_BAR) .build()) .build(wms, displayContent, root, ime, taskDisplayAreaList); .build(mWms, mDisplayContent, mRoot, mImeContainer, mTaskDisplayAreaList); policy.attachDisplayAreas(); Loading @@ -105,19 +122,19 @@ public class DisplayAreaPolicyBuilderTest { assertThat(policy.findAreaForToken(tokenOfType(TYPE_STATUS_BAR)), is(not(decendantOfOneOf(policy.getDisplayAreas(bar))))); assertThat(taskDisplayArea, assertThat(mDefaultTaskDisplayArea, is(decendantOfOneOf(policy.getDisplayAreas(foo)))); assertThat(taskDisplayArea, assertThat(mDefaultTaskDisplayArea, is(decendantOfOneOf(policy.getDisplayAreas(bar)))); assertThat(ime, assertThat(mImeContainer, is(decendantOfOneOf(policy.getDisplayAreas(foo)))); assertThat(ime, assertThat(mImeContainer, is(decendantOfOneOf(policy.getDisplayAreas(bar)))); List<DisplayArea<?>> actualOrder = collectLeafAreas(root); Map<DisplayArea<?>, Set<Integer>> zSets = calculateZSets(policy, root, ime, taskDisplayArea); List<DisplayArea<?>> actualOrder = collectLeafAreas(mRoot); Map<DisplayArea<?>, Set<Integer>> zSets = calculateZSets(policy, mRoot, mImeContainer, mDefaultTaskDisplayArea); actualOrder = actualOrder.stream().filter(zSets::containsKey).collect(toList()); Map<DisplayArea<?>, Integer> expectedByMinLayer = mapValues(zSets, Loading @@ -131,20 +148,11 @@ public class DisplayAreaPolicyBuilderTest { @Test public void testBuilder_defaultPolicy_hasOneHandedFeature() { WindowManagerService wms = mSystemServices.getWindowManagerService(); DisplayArea.Root root = new SurfacelessDisplayAreaRoot(wms); DisplayArea<WindowContainer> ime = new DisplayArea<>(wms, ABOVE_TASKS, "Ime"); 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 DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources( resourcesWithProvider("")); final DisplayAreaPolicyBuilder.Result defaultPolicy = (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(wms, displayContent, root, ime); (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(mWms, mDisplayContent, mRoot, mImeContainer); final List<Feature> features = defaultPolicy.getFeatures(); boolean hasOneHandedFeature = false; for (int i = 0; i < features.size(); i++) { Loading @@ -154,6 +162,34 @@ public class DisplayAreaPolicyBuilderTest { assertTrue(hasOneHandedFeature); } @Test public void testBuilder_createCustomizedDisplayAreaForFeature() { final Feature dimmable; final Feature other; DisplayAreaPolicyBuilder.Result policy = new DisplayAreaPolicyBuilder() .addFeature(dimmable = new Feature.Builder(mPolicy, "Dimmable", 0) .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new) .build()) .addFeature(other = new Feature.Builder(mPolicy, "Other", 1) .all() .build()) .build(mWms, mDisplayContent, mRoot, mImeContainer, mTaskDisplayAreaList); policy.attachDisplayAreas(); List<DisplayArea<? extends WindowContainer>> dimmableDAs = policy.getDisplayAreas(dimmable.getId()); List<DisplayArea<? extends WindowContainer>> otherDAs = policy.getDisplayAreas(other.getId()); assertEquals(1, dimmableDAs.size()); assertTrue(dimmableDAs.get(0) instanceof DisplayArea.Dimmable); for (DisplayArea otherDA : otherDAs) { assertFalse(otherDA instanceof DisplayArea.Dimmable); } } private static Resources resourcesWithProvider(String provider) { Resources mock = mock(Resources.class); when(mock.getString( Loading Loading
services/core/java/com/android/server/wm/DisplayArea.java +11 −2 Original line number Diff line number Diff line Loading @@ -266,11 +266,20 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { * Top-most DisplayArea under DisplayContent. */ public static class Root extends DisplayArea<DisplayArea> { Root(WindowManagerService wms) { super(wms, Type.ANY, "DisplayArea.Root", FEATURE_ROOT); } } /** * DisplayArea that can be dimmed. */ static class Dimmable extends DisplayArea<DisplayArea> { private final Dimmer mDimmer = new Dimmer(this); private final Rect mTmpDimBoundsRect = new Rect(); Root(WindowManagerService wms) { super(wms, Type.ANY, "DisplayArea.Root", FEATURE_ROOT); Dimmable(WindowManagerService wms, Type type, String name, int featureId) { super(wms, type, name, featureId); } @Override Loading
services/core/java/com/android/server/wm/DisplayAreaPolicy.java +3 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,9 @@ public abstract class DisplayAreaPolicy { "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION) .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) // Make the DA dimmable so that the magnify window also mirrors the dim // layer .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new) .build()) .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy, "OneHanded", FEATURE_ONE_HANDED) Loading
services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java +23 −4 Original line number Diff line number Diff line Loading @@ -68,6 +68,12 @@ class DisplayAreaPolicyBuilder { private final ArrayList<Feature> mFeatures = new ArrayList<>(); /** Supplier interface to provide a new created {@link DisplayArea}. */ interface NewDisplayAreaSupplier { DisplayArea create(WindowManagerService wms, DisplayArea.Type type, String name, int featureId); } /** * A feature that requires {@link DisplayArea DisplayArea(s)}. */ Loading @@ -75,11 +81,14 @@ class DisplayAreaPolicyBuilder { private final String mName; private final int mId; private final boolean[] mWindowLayers; private final NewDisplayAreaSupplier mNewDisplayAreaSupplier; private Feature(String name, int id, boolean[] windowLayers) { private Feature(String name, int id, boolean[] windowLayers, NewDisplayAreaSupplier newDisplayAreaSupplier) { mName = name; mId = id; mWindowLayers = windowLayers; mNewDisplayAreaSupplier = newDisplayAreaSupplier; } /** Loading @@ -104,6 +113,7 @@ class DisplayAreaPolicyBuilder { private final String mName; private final int mId; private final boolean[] mLayers; private NewDisplayAreaSupplier mNewDisplayAreaSupplier = DisplayArea::new; /** * Build a new feature that applies to a set of window types as specified by the builder Loading Loading @@ -168,8 +178,17 @@ class DisplayAreaPolicyBuilder { return this; } /** * Sets the function to create new {@link DisplayArea} for this feature. By default, it * uses {@link DisplayArea}'s constructor. */ Builder setNewDisplayAreaSupplier(NewDisplayAreaSupplier newDisplayAreaSupplier) { mNewDisplayAreaSupplier = newDisplayAreaSupplier; return this; } Feature build() { return new Feature(mName, mId, mLayers.clone()); return new Feature(mName, mId, mLayers.clone(), mNewDisplayAreaSupplier); } private void set(int type, boolean value) { Loading Loading @@ -416,8 +435,8 @@ class DisplayAreaPolicyBuilder { } return leaf; } else { return new DisplayArea(parent.mWmService, type, mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer, mFeature.mId); return mFeature.mNewDisplayAreaSupplier.create(parent.mWmService, type, mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer, mFeature.mId); } } } Loading
services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java +64 −28 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; Loading @@ -32,10 +33,12 @@ import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.testng.Assert.assertFalse; import static java.util.stream.Collectors.toList; Loading @@ -48,6 +51,7 @@ import androidx.test.filters.FlakyTest; import org.hamcrest.CustomTypeSafeMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -61,6 +65,10 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; /** * Build/Install/Run: * atest WmTests:DisplayAreaPolicyBuilderTest */ @Presubmit public class DisplayAreaPolicyBuilderTest { Loading @@ -68,19 +76,28 @@ public class DisplayAreaPolicyBuilderTest { public final SystemServicesTestRule mSystemServices = new SystemServicesTestRule(); private TestWindowManagerPolicy mPolicy = new TestWindowManagerPolicy(null, null); private WindowManagerService mWms; private DisplayArea.Root mRoot; private DisplayArea<WindowContainer> mImeContainer; private DisplayContent mDisplayContent; private TaskDisplayArea mDefaultTaskDisplayArea; private List<TaskDisplayArea> mTaskDisplayAreaList; @Before public void setup() { mWms = mSystemServices.getWindowManagerService(); mRoot = new SurfacelessDisplayAreaRoot(mWms); mImeContainer = new DisplayArea<>(mWms, ABOVE_TASKS, "Ime"); mDisplayContent = mock(DisplayContent.class); mDefaultTaskDisplayArea = new TaskDisplayArea(mDisplayContent, mWms, "Tasks", FEATURE_DEFAULT_TASK_CONTAINER); mTaskDisplayAreaList = new ArrayList<>(); mTaskDisplayAreaList.add(mDefaultTaskDisplayArea); } @Test @FlakyTest(bugId = 149760939) public void testBuilder() { WindowManagerService wms = mSystemServices.getWindowManagerService(); DisplayArea.Root root = new SurfacelessDisplayAreaRoot(wms); DisplayArea<WindowContainer> ime = new DisplayArea<>(wms, ABOVE_TASKS, "Ime"); 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; Loading @@ -93,7 +110,7 @@ public class DisplayAreaPolicyBuilderTest { .all() .except(TYPE_STATUS_BAR) .build()) .build(wms, displayContent, root, ime, taskDisplayAreaList); .build(mWms, mDisplayContent, mRoot, mImeContainer, mTaskDisplayAreaList); policy.attachDisplayAreas(); Loading @@ -105,19 +122,19 @@ public class DisplayAreaPolicyBuilderTest { assertThat(policy.findAreaForToken(tokenOfType(TYPE_STATUS_BAR)), is(not(decendantOfOneOf(policy.getDisplayAreas(bar))))); assertThat(taskDisplayArea, assertThat(mDefaultTaskDisplayArea, is(decendantOfOneOf(policy.getDisplayAreas(foo)))); assertThat(taskDisplayArea, assertThat(mDefaultTaskDisplayArea, is(decendantOfOneOf(policy.getDisplayAreas(bar)))); assertThat(ime, assertThat(mImeContainer, is(decendantOfOneOf(policy.getDisplayAreas(foo)))); assertThat(ime, assertThat(mImeContainer, is(decendantOfOneOf(policy.getDisplayAreas(bar)))); List<DisplayArea<?>> actualOrder = collectLeafAreas(root); Map<DisplayArea<?>, Set<Integer>> zSets = calculateZSets(policy, root, ime, taskDisplayArea); List<DisplayArea<?>> actualOrder = collectLeafAreas(mRoot); Map<DisplayArea<?>, Set<Integer>> zSets = calculateZSets(policy, mRoot, mImeContainer, mDefaultTaskDisplayArea); actualOrder = actualOrder.stream().filter(zSets::containsKey).collect(toList()); Map<DisplayArea<?>, Integer> expectedByMinLayer = mapValues(zSets, Loading @@ -131,20 +148,11 @@ public class DisplayAreaPolicyBuilderTest { @Test public void testBuilder_defaultPolicy_hasOneHandedFeature() { WindowManagerService wms = mSystemServices.getWindowManagerService(); DisplayArea.Root root = new SurfacelessDisplayAreaRoot(wms); DisplayArea<WindowContainer> ime = new DisplayArea<>(wms, ABOVE_TASKS, "Ime"); 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 DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources( resourcesWithProvider("")); final DisplayAreaPolicyBuilder.Result defaultPolicy = (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(wms, displayContent, root, ime); (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(mWms, mDisplayContent, mRoot, mImeContainer); final List<Feature> features = defaultPolicy.getFeatures(); boolean hasOneHandedFeature = false; for (int i = 0; i < features.size(); i++) { Loading @@ -154,6 +162,34 @@ public class DisplayAreaPolicyBuilderTest { assertTrue(hasOneHandedFeature); } @Test public void testBuilder_createCustomizedDisplayAreaForFeature() { final Feature dimmable; final Feature other; DisplayAreaPolicyBuilder.Result policy = new DisplayAreaPolicyBuilder() .addFeature(dimmable = new Feature.Builder(mPolicy, "Dimmable", 0) .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new) .build()) .addFeature(other = new Feature.Builder(mPolicy, "Other", 1) .all() .build()) .build(mWms, mDisplayContent, mRoot, mImeContainer, mTaskDisplayAreaList); policy.attachDisplayAreas(); List<DisplayArea<? extends WindowContainer>> dimmableDAs = policy.getDisplayAreas(dimmable.getId()); List<DisplayArea<? extends WindowContainer>> otherDAs = policy.getDisplayAreas(other.getId()); assertEquals(1, dimmableDAs.size()); assertTrue(dimmableDAs.get(0) instanceof DisplayArea.Dimmable); for (DisplayArea otherDA : otherDAs) { assertFalse(otherDA instanceof DisplayArea.Dimmable); } } private static Resources resourcesWithProvider(String provider) { Resources mock = mock(Resources.class); when(mock.getString( Loading