diff options
3 files changed, 91 insertions, 68 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java index d4b319a525da..f8c375497b7b 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java @@ -99,23 +99,41 @@ public abstract class DisplayAreaPolicy { // Define the features that will be supported under the root of the whole logical // display. The policy will build the DisplayArea hierarchy based on this. - HierarchyBuilder rootHierarchy = new HierarchyBuilder(root) - // WindowedMagnification should be on the top so that there is only one surface - // to be magnified. - .addFeature(new Feature.Builder(wmService.mPolicy, "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 Feature.Builder(wmService.mPolicy, "HideDisplayCutout", - FEATURE_HIDE_DISPLAY_CUTOUT) - .all() - .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL, TYPE_STATUS_BAR, - TYPE_NOTIFICATION_SHADE) - .build()) + final HierarchyBuilder rootHierarchy = new HierarchyBuilder(root); + if (content.isTrusted()) { + // Only trusted display can have system decorations. + configureTrustedHierarchyBuilder(rootHierarchy, wmService, content); + } + // Set the essential containers (even the display doesn't support IME). + rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList); + + // Instantiate the policy with the hierarchy defined above. This will create and attach + // all the necessary DisplayAreas to the root. + return new DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService); + } + + private void configureTrustedHierarchyBuilder(HierarchyBuilder rootHierarchy, + WindowManagerService wmService, DisplayContent content) { + // WindowedMagnification should be on the top so that there is only one surface + // to be magnified. + rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "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()); + if (content.isDefaultDisplay) { + // Only default display can have cutout. + // See LocalDisplayAdapter.LocalDisplayDevice#getDisplayDeviceInfoLocked. + rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "HideDisplayCutout", + FEATURE_HIDE_DISPLAY_CUTOUT) + .all() + .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL, + TYPE_STATUS_BAR, TYPE_NOTIFICATION_SHADE) + .build()); + } + rootHierarchy .addFeature(new Feature.Builder(wmService.mPolicy, "OneHanded", FEATURE_ONE_HANDED) .all() @@ -131,13 +149,7 @@ public abstract class DisplayAreaPolicy { .addFeature(new Feature.Builder(wmService.mPolicy, "ImePlaceholder", FEATURE_IME_PLACEHOLDER) .and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG) - .build()) - .setImeContainer(imeContainer) - .setTaskDisplayAreas(tdaList); - - // Instantiate the policy with the hierarchy defined above. This will create and attach - // all the necessary DisplayAreas to the root. - return new DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService); + .build()); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java index e47913fba7ab..8e78dce39ac7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java @@ -40,6 +40,7 @@ import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; @@ -100,6 +101,7 @@ public class DisplayAreaPolicyBuilderTest { mRoot = new SurfacelessDisplayAreaRoot(mWms); mImeContainer = new DisplayArea.Tokens(mWms, ABOVE_TASKS, "ImeContainer"); mDisplayContent = mock(DisplayContent.class); + doReturn(true).when(mDisplayContent).isTrusted(); mDefaultTaskDisplayArea = new TaskDisplayArea(mDisplayContent, mWms, "Tasks", FEATURE_DEFAULT_TASK_CONTAINER); mTaskDisplayAreaList = new ArrayList<>(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java index 496b2b744712..d451180c7269 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java @@ -22,15 +22,18 @@ import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.platform.test.annotations.Presubmit; +import android.util.Pair; +import android.view.Display; +import android.view.DisplayInfo; import androidx.test.filters.SmallTest; @@ -38,9 +41,8 @@ import com.android.server.wm.DisplayAreaPolicyBuilderTest.SurfacelessDisplayArea import com.google.android.collect.Lists; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Collections; @@ -54,78 +56,65 @@ import java.util.List; */ @SmallTest @Presubmit -public class DisplayAreaPolicyTests { - - @Rule - public final SystemServicesTestRule mSystemServices = new SystemServicesTestRule(); - - private DisplayAreaPolicyBuilder.Result mPolicy; - private TaskDisplayArea mTaskDisplayArea1; - private TaskDisplayArea mTaskDisplayArea2; - private RootDisplayArea mRoot; - - @Before - public void setUp() throws Exception { - WindowManagerService wms = mSystemServices.getWindowManagerService(); - mRoot = new SurfacelessDisplayAreaRoot(wms); - spyOn(mRoot); - DisplayArea.Tokens ime = new DisplayArea.Tokens(wms, ABOVE_TASKS, "Ime"); - DisplayContent displayContent = mock(DisplayContent.class); - doReturn(true).when(displayContent).isTrusted(); - mTaskDisplayArea1 = new TaskDisplayArea(displayContent, wms, "Tasks1", - FEATURE_DEFAULT_TASK_CONTAINER); - mTaskDisplayArea2 = new TaskDisplayArea(displayContent, wms, "Tasks2", - FEATURE_VENDOR_FIRST); - List<TaskDisplayArea> taskDisplayAreaList = new ArrayList<>(); - taskDisplayAreaList.add(mTaskDisplayArea1); - taskDisplayAreaList.add(mTaskDisplayArea2); - - mPolicy = new DisplayAreaPolicyBuilder() - .setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot) - .setImeContainer(ime) - .setTaskDisplayAreas(taskDisplayAreaList)) - .build(wms); - } +@RunWith(WindowTestRunner.class) +public class DisplayAreaPolicyTests extends WindowTestsBase { @Test public void testGetDefaultTaskDisplayArea() { - assertEquals(mTaskDisplayArea1, mPolicy.getDefaultTaskDisplayArea()); + final Pair<DisplayAreaPolicy, List<TaskDisplayArea>> result = + createPolicyWith2TaskDisplayAreas(); + final DisplayAreaPolicy policy = result.first; + final TaskDisplayArea taskDisplayArea1 = result.second.get(0); + assertEquals(taskDisplayArea1, policy.getDefaultTaskDisplayArea()); } @Test public void testTaskDisplayArea_taskPositionChanged_updatesTaskDisplayAreaPosition() { - final Task stack1 = mTaskDisplayArea1.createRootTask( + final Pair<DisplayAreaPolicy, List<TaskDisplayArea>> result = + createPolicyWith2TaskDisplayAreas(); + final DisplayAreaPolicy policy = result.first; + final TaskDisplayArea taskDisplayArea1 = result.second.get(0); + final TaskDisplayArea taskDisplayArea2 = result.second.get(1); + final Task stack1 = taskDisplayArea1.createRootTask( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final Task stack2 = mTaskDisplayArea2.createRootTask( + final Task stack2 = taskDisplayArea2.createRootTask( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Initial order - assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea1, mTaskDisplayArea2); + assertTaskDisplayAreasOrder(policy, taskDisplayArea1, taskDisplayArea2); // Move stack in tda1 to top stack1.getParent().positionChildAt(POSITION_TOP, stack1, true /* includingParents */); - assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea2, mTaskDisplayArea1); + assertTaskDisplayAreasOrder(policy, taskDisplayArea2, taskDisplayArea1); // Move stack in tda2 to top, but not including parents stack2.getParent().positionChildAt(POSITION_TOP, stack2, false /* includingParents */); - assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea2, mTaskDisplayArea1); + assertTaskDisplayAreasOrder(policy, taskDisplayArea2, taskDisplayArea1); // Move stack in tda1 to bottom stack1.getParent().positionChildAt(POSITION_BOTTOM, stack1, true /* includingParents */); - assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea1, mTaskDisplayArea2); + assertTaskDisplayAreasOrder(policy, taskDisplayArea1, taskDisplayArea2); // Move stack in tda2 to bottom, but not including parents stack2.getParent().positionChildAt(POSITION_BOTTOM, stack2, false /* includingParents */); - assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea1, mTaskDisplayArea2); + assertTaskDisplayAreasOrder(policy, taskDisplayArea1, taskDisplayArea2); + } + + @Test + public void testEmptyFeaturesOnUntrustedDisplay() { + final DisplayInfo info = new DisplayInfo(mDisplayInfo); + info.flags &= ~Display.FLAG_TRUSTED; + final DisplayContent untrustedDisplay = new TestDisplayContent.Builder(mAtm, info).build(); + assertTrue(untrustedDisplay.mFeatures.isEmpty()); } @Test public void testDisplayAreaGroup_taskPositionChanged_updatesDisplayAreaGroupPosition() { - final WindowManagerService wms = mSystemServices.getWindowManagerService(); + final WindowManagerService wms = mWm; final DisplayContent displayContent = mock(DisplayContent.class); doReturn(true).when(displayContent).isTrusted(); final RootDisplayArea root = new SurfacelessDisplayAreaRoot(wms); @@ -203,4 +192,24 @@ public class DisplayAreaPolicyTests { }, false /* traverseTopToBottom */); assertEquals(expectOrder, actualOrder); } + + private Pair<DisplayAreaPolicy, List<TaskDisplayArea>> createPolicyWith2TaskDisplayAreas() { + final SurfacelessDisplayAreaRoot root = new SurfacelessDisplayAreaRoot(mWm); + final DisplayArea.Tokens ime = new DisplayArea.Tokens(mWm, ABOVE_TASKS, "Ime"); + final DisplayContent displayContent = mock(DisplayContent.class); + doReturn(true).when(displayContent).isTrusted(); + final TaskDisplayArea taskDisplayArea1 = new TaskDisplayArea(displayContent, mWm, "Tasks1", + FEATURE_DEFAULT_TASK_CONTAINER); + final TaskDisplayArea taskDisplayArea2 = new TaskDisplayArea(displayContent, mWm, "Tasks2", + FEATURE_VENDOR_FIRST); + final List<TaskDisplayArea> taskDisplayAreaList = new ArrayList<>(); + taskDisplayAreaList.add(taskDisplayArea1); + taskDisplayAreaList.add(taskDisplayArea2); + + return Pair.create(new DisplayAreaPolicyBuilder() + .setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(root) + .setImeContainer(ime) + .setTaskDisplayAreas(taskDisplayAreaList)) + .build(mWm), taskDisplayAreaList); + } } |