summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java390
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java101
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java11
6 files changed, 461 insertions, 59 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1d2cd0a0a350..c2fe93110b1b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -995,7 +995,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
getPendingTransaction().apply();
// Setup the policy and build the display area hierarchy.
- mDisplayAreaPolicy = mWmService.mDisplayAreaPolicyProvider.instantiate(
+ mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
mWmService, this /* content */, this /* root */, mImeWindowsContainers);
// Sets the display content for the children.
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index cf6468d66b57..6242fe9a1444 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1152,10 +1152,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
/**
* Check if this container or its parent will handle orientation changes from descendants. It's
- * different from the return value of {@link #onDescendantOrientationChanged(IBinder,
- * WindowContainer)} in the sense that the return value of this method tells if this
- * container or its parent will handle the request eventually, while the return value of the
- * other method is if it handled the request synchronously.
+ * different from the return value of {@link #onDescendantOrientationChanged(WindowContainer)}
+ * in the sense that the return value of this method tells if this container or its parent will
+ * handle the request eventually, while the return value of the other method is if it handled
+ * the request synchronously.
*
* @return {@code true} if it handles or will handle orientation change in the future; {@code
* false} if it won't handle the change at anytime.
@@ -1221,7 +1221,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
/**
- * Calls {@link #setOrientation(int, IBinder, WindowContainer)} with {@code null} to the last 2
+ * Calls {@link #setOrientation(int, WindowContainer)} with {@code null} to the last 2
* parameters.
*
* @param orientation the specified orientation.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d4efa8a7ab91..a4dc21842f1b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -459,7 +459,7 @@ public class WindowManagerService extends IWindowManager.Stub
final WindowTracing mWindowTracing;
- final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
+ private final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
final private KeyguardDisableHandler mKeyguardDisableHandler;
// TODO: eventually unify all keyguard state in a common place instead of having it spread over
@@ -1378,6 +1378,10 @@ public class WindowManagerService extends IWindowManager.Stub
mStartingSurfaceController = new StartingSurfaceController(this);
}
+ DisplayAreaPolicy.Provider getDisplayAreaPolicyProvider() {
+ return mDisplayAreaPolicyProvider;
+ }
+
private void setGlobalShadowSettings() {
final TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
float lightY = a.getDimension(R.styleable.Lighting_lightY, 0);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
new file mode 100644
index 000000000000..73e886f67cd3
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.content.ActivityInfoProto.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.view.Surface.ROTATION_90;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
+import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
+import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.SizeCompatTests.prepareUnresizable;
+import static com.android.server.wm.SizeCompatTests.rotateDisplay;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.view.Display;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for the Dual DisplayAreaGroup device behavior.
+ *
+ * Build/Install/Run:
+ * atest WmTests:DualDisplayAreaGroupPolicyTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
+ private static final int FEATURE_FIRST_ROOT = FEATURE_VENDOR_FIRST;
+ private static final int FEATURE_FIRST_TASK_CONTAINER = FEATURE_DEFAULT_TASK_CONTAINER;
+ private static final int FEATURE_SECOND_ROOT = FEATURE_VENDOR_FIRST + 1;
+ private static final int FEATURE_SECOND_TASK_CONTAINER = FEATURE_VENDOR_FIRST + 2;
+
+ private DualDisplayContent mDisplay;
+ private DisplayAreaGroup mFirstRoot;
+ private DisplayAreaGroup mSecondRoot;
+ private TaskDisplayArea mFirstTda;
+ private TaskDisplayArea mSecondTda;
+ private Task mFirstTask;
+ private Task mSecondTask;
+ private ActivityRecord mFirstActivity;
+ private ActivityRecord mSecondActivity;
+
+ @Before
+ public void setUp() {
+ // Let the Display to be created with the DualDisplay policy.
+ final DisplayAreaPolicy.Provider policyProvider = new DualDisplayTestPolicyProvider();
+ doReturn(policyProvider).when(mWm).getDisplayAreaPolicyProvider();
+
+ // Display: 1920x1200 (landscape). First and second display are both 860x1200 (portrait).
+ mDisplay = (DualDisplayContent) new DualDisplayContent.Builder(mAtm, 1920, 1200).build();
+ mFirstRoot = mDisplay.mFirstRoot;
+ mSecondRoot = mDisplay.mSecondRoot;
+ mFirstTda = mDisplay.getTaskDisplayArea(FEATURE_FIRST_TASK_CONTAINER);
+ mSecondTda = mDisplay.getTaskDisplayArea(FEATURE_SECOND_TASK_CONTAINER);
+ mFirstTask = new TaskBuilder(mSupervisor)
+ .setTaskDisplayArea(mFirstTda)
+ .setCreateActivity(true)
+ .build()
+ .getBottomMostTask();
+ mSecondTask = new TaskBuilder(mSupervisor)
+ .setTaskDisplayArea(mSecondTda)
+ .setCreateActivity(true)
+ .build()
+ .getBottomMostTask();
+ mFirstActivity = mFirstTask.getTopNonFinishingActivity();
+ mSecondActivity = mSecondTask.getTopNonFinishingActivity();
+
+ spyOn(mDisplay);
+ spyOn(mFirstRoot);
+ spyOn(mSecondRoot);
+ }
+
+ @Test
+ public void testNotIgnoreOrientationRequest_differentOrientationFromDisplay_reversesRequest() {
+ mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+ mDisplay.setLastFocusedTaskDisplayArea(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+ assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT);
+ assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+ assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+ assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
+ }
+
+ @Test
+ public void testNotIgnoreOrientationRequest_onlyRespectsFocusedTaskDisplayArea() {
+ mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+ mDisplay.setLastFocusedTaskDisplayArea(mFirstTda);
+
+ // Second TDA is not focused, so Display won't get the request
+ prepareUnresizable(mSecondActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+ assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSPECIFIED);
+
+ // First TDA is focused, so Display gets the request
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+ assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT);
+ }
+
+ @Test
+ public void testIgnoreOrientationRequest_displayDoesNotReceiveOrientationChange() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.setLastFocusedTaskDisplayArea(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+ verify(mFirstRoot).onDescendantOrientationChanged(any());
+ verify(mDisplay, never()).onDescendantOrientationChanged(any());
+ }
+
+ @Test
+ public void testLaunchPortraitApp_fillsDisplayAreaGroup() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.setLastFocusedTaskDisplayArea(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT);
+ final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+ final Rect taskBounds = new Rect(mFirstTask.getBounds());
+ final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+ // DAG is portrait (860x1200), so Task and Activity fill DAG.
+ assertThat(mFirstTask.isTaskLetterboxed()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+ assertThat(taskBounds).isEqualTo(dagBounds);
+ assertThat(activityBounds).isEqualTo(taskBounds);
+ }
+
+ @Test
+ public void testLaunchPortraitApp_sizeCompatAfterRotation() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.setLastFocusedTaskDisplayArea(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT);
+ final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+ final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+ rotateDisplay(mDisplay, ROTATION_90);
+ final Rect newDagBounds = new Rect(mFirstRoot.getBounds());
+ final Rect newTaskBounds = new Rect(mFirstTask.getBounds());
+ final Rect activitySizeCompatBounds = new Rect(mFirstActivity.getBounds());
+ final Rect activityConfigBounds =
+ new Rect(mFirstActivity.getConfiguration().windowConfiguration.getBounds());
+
+ // DAG is landscape (1200x860), Task fills parent
+ assertThat(mFirstTask.isTaskLetterboxed()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isTrue();
+ assertThat(newDagBounds.width()).isEqualTo(dagBounds.height());
+ assertThat(newDagBounds.height()).isEqualTo(dagBounds.width());
+ assertThat(newTaskBounds).isEqualTo(newDagBounds);
+
+ // Activity config bounds is unchanged, size compat bounds is (860x[860x860/1200=616])
+ assertThat(mFirstActivity.getSizeCompatScale()).isLessThan(1f);
+ assertThat(activityConfigBounds.width()).isEqualTo(activityBounds.width());
+ assertThat(activityConfigBounds.height()).isEqualTo(activityBounds.height());
+ assertThat(activitySizeCompatBounds.height()).isEqualTo(newTaskBounds.height());
+ assertThat(activitySizeCompatBounds.width()).isEqualTo(
+ newTaskBounds.height() * newTaskBounds.height() / newTaskBounds.width());
+ }
+
+ @Test
+ public void testLaunchLandscapeApp_taskIsLetterboxInDisplayAreaGroup() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.setLastFocusedTaskDisplayArea(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+ final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+ final Rect taskBounds = new Rect(mFirstTask.getBounds());
+ final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+ // DAG is portrait (860x1200), so Task is letterbox (860x[860x860/1200=616])
+ assertThat(mFirstTask.isTaskLetterboxed()).isTrue();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+ assertThat(taskBounds.width()).isEqualTo(dagBounds.width());
+ assertThat(taskBounds.height())
+ .isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height());
+ assertThat(activityBounds).isEqualTo(taskBounds);
+ }
+
+ @Test
+ public void testLaunchLandscapeApp_taskLetterboxBecomesActivityLetterboxAfterRotation() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.setLastFocusedTaskDisplayArea(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+ final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+ final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+ rotateDisplay(mDisplay, ROTATION_90);
+ final Rect newDagBounds = new Rect(mFirstRoot.getBounds());
+ final Rect newTaskBounds = new Rect(mFirstTask.getBounds());
+ final Rect newActivityBounds = new Rect(mFirstActivity.getBounds());
+
+ // DAG is landscape (1200x860), Task fills parent
+ // Task letterbox size
+ assertThat(mFirstTask.isTaskLetterboxed()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isTrue();
+ assertThat(newDagBounds.width()).isEqualTo(dagBounds.height());
+ assertThat(newDagBounds.height()).isEqualTo(dagBounds.width());
+ assertThat(newTaskBounds).isEqualTo(newDagBounds);
+
+ // Because we don't scale up, there is no size compat bounds and app bounds is the same as
+ // the previous bounds.
+ assertThat(mFirstActivity.hasSizeCompatBounds()).isFalse();
+ assertThat(newActivityBounds.width()).isEqualTo(activityBounds.width());
+ assertThat(newActivityBounds.height()).isEqualTo(activityBounds.height());
+ }
+
+ /** Display with two {@link DisplayAreaGroup}. Each of them take half of the screen. */
+ private static class DualDisplayContent extends TestDisplayContent {
+ final DisplayAreaGroup mFirstRoot;
+ final DisplayAreaGroup mSecondRoot;
+ final Rect mLastDisplayBounds;
+
+ /** Please use the {@link Builder} to create. */
+ DualDisplayContent(RootWindowContainer rootWindowContainer,
+ Display display) {
+ super(rootWindowContainer, display);
+
+ mFirstRoot = getGroupRoot(FEATURE_FIRST_ROOT);
+ mSecondRoot = getGroupRoot(FEATURE_SECOND_ROOT);
+ mLastDisplayBounds = new Rect(getBounds());
+ updateDisplayAreaGroupBounds();
+ }
+
+ DisplayAreaGroup getGroupRoot(int rootFeatureId) {
+ DisplayArea da = getDisplayArea(rootFeatureId);
+ assertThat(da).isInstanceOf(DisplayAreaGroup.class);
+ return (DisplayAreaGroup) da;
+ }
+
+ TaskDisplayArea getTaskDisplayArea(int tdaFeatureId) {
+ DisplayArea da = getDisplayArea(tdaFeatureId);
+ assertThat(da).isInstanceOf(TaskDisplayArea.class);
+ return (TaskDisplayArea) da;
+ }
+
+ DisplayArea getDisplayArea(int featureId) {
+ final DisplayArea displayArea =
+ getItemFromDisplayAreas(da -> da.mFeatureId == featureId ? da : null);
+ assertThat(displayArea).isNotNull();
+ return displayArea;
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newParentConfig) {
+ super.onConfigurationChanged(newParentConfig);
+
+ final Rect curBounds = getBounds();
+ if (mLastDisplayBounds != null && !mLastDisplayBounds.equals(curBounds)) {
+ mLastDisplayBounds.set(curBounds);
+ updateDisplayAreaGroupBounds();
+ }
+ }
+
+ /** Updates first and second {@link DisplayAreaGroup} to take half of the screen. */
+ private void updateDisplayAreaGroupBounds() {
+ if (mFirstRoot == null || mSecondRoot == null) {
+ return;
+ }
+
+ final Rect bounds = mLastDisplayBounds;
+ Rect groupBounds1, groupBounds2;
+ if (bounds.width() >= bounds.height()) {
+ groupBounds1 = new Rect(bounds.left, bounds.top,
+ (bounds.right + bounds.left) / 2, bounds.bottom);
+
+ groupBounds2 = new Rect((bounds.right + bounds.left) / 2, bounds.top,
+ bounds.right, bounds.bottom);
+ } else {
+ groupBounds1 = new Rect(bounds.left, bounds.top,
+ bounds.right, (bounds.top + bounds.bottom) / 2);
+
+ groupBounds2 = new Rect(bounds.left,
+ (bounds.top + bounds.bottom) / 2, bounds.right, bounds.bottom);
+ }
+ mFirstRoot.setBounds(groupBounds1);
+ mSecondRoot.setBounds(groupBounds2);
+ }
+
+ static class Builder extends TestDisplayContent.Builder {
+
+ Builder(ActivityTaskManagerService service, int width, int height) {
+ super(service, width, height);
+ }
+
+ @Override
+ TestDisplayContent createInternal(Display display) {
+ return new DualDisplayContent(mService.mRootWindowContainer, display);
+ }
+ }
+ }
+
+ /** Policy to create a dual {@link DisplayAreaGroup} policy in test. */
+ private static class DualDisplayTestPolicyProvider implements DisplayAreaPolicy.Provider {
+
+ @Override
+ public DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,
+ RootDisplayArea root, DisplayArea.Tokens imeContainer) {
+ // Root
+ // Include FEATURE_WINDOWED_MAGNIFICATION because it will be used as the screen rotation
+ // layer
+ DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
+ new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
+ .setImeContainer(imeContainer)
+ .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(
+ wmService.mPolicy,
+ "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION)
+ .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
+ .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
+ .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)
+ .build());
+
+ // First
+ final RootDisplayArea firstRoot = new DisplayAreaGroup(wmService, "FirstRoot",
+ FEATURE_FIRST_ROOT);
+ final TaskDisplayArea firstTaskDisplayArea = new TaskDisplayArea(content, wmService,
+ "FirstTaskDisplayArea", FEATURE_FIRST_TASK_CONTAINER);
+ final List<TaskDisplayArea> firstTdaList = new ArrayList<>();
+ firstTdaList.add(firstTaskDisplayArea);
+ DisplayAreaPolicyBuilder.HierarchyBuilder firstHierarchy =
+ new DisplayAreaPolicyBuilder.HierarchyBuilder(firstRoot)
+ .setTaskDisplayAreas(firstTdaList);
+
+ // Second
+ final RootDisplayArea secondRoot = new DisplayAreaGroup(wmService, "SecondRoot",
+ FEATURE_SECOND_ROOT);
+ final TaskDisplayArea secondTaskDisplayArea = new TaskDisplayArea(content, wmService,
+ "SecondTaskDisplayArea", FEATURE_SECOND_TASK_CONTAINER);
+ final List<TaskDisplayArea> secondTdaList = new ArrayList<>();
+ secondTdaList.add(secondTaskDisplayArea);
+ DisplayAreaPolicyBuilder.HierarchyBuilder secondHierarchy =
+ new DisplayAreaPolicyBuilder.HierarchyBuilder(secondRoot)
+ .setTaskDisplayAreas(secondTdaList);
+
+ return new DisplayAreaPolicyBuilder()
+ .setRootHierarchy(rootHierarchy)
+ .addDisplayAreaGroupHierarchy(firstHierarchy)
+ .addDisplayAreaGroupHierarchy(secondHierarchy)
+ .build(wmService);
+ }
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index da00198030e4..dd6e490b8282 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -92,7 +92,7 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mVisibleRequested = true;
mActivity.setSavedState(null /* savedState */);
mActivity.setState(Task.ActivityState.RESUMED, "testRestart");
- prepareUnresizable(1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+ prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
final Rect originalOverrideBounds = new Rect(mActivity.getBounds());
resizeDisplay(mTask.mDisplayContent, 600, 1200);
@@ -115,7 +115,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Put app window into freeform and then make it a compat app.
final Rect bounds = new Rect(100, 100, 400, 600);
mTask.setBounds(bounds);
- prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertEquals(bounds, mActivity.getBounds());
// The activity should be able to accept negative x position [-150, 100 - 150, 600].
@@ -145,7 +145,7 @@ public class SizeCompatTests extends WindowTestsBase {
final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds();
final float aspectRatio = 1.2f;
mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = aspectRatio;
- prepareUnresizable(-1f, SCREEN_ORIENTATION_UNSPECIFIED);
+ prepareUnresizable(mActivity, -1f, SCREEN_ORIENTATION_UNSPECIFIED);
final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
// The parent configuration doesn't change since the first resolved configuration, so the
@@ -205,7 +205,7 @@ public class SizeCompatTests extends WindowTestsBase {
@Test
public void testFixedScreenBoundsWhenDisplaySizeChanged() {
setUpDisplaySizeWithApp(1000, 2500);
- prepareUnresizable(-1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
final Rect origBounds = new Rect(mActivity.getBounds());
@@ -262,7 +262,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpDisplaySizeWithApp(displayWidth, 1000);
final float maxAspect = 1.5f;
- prepareUnresizable(maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
+ prepareUnresizable(mActivity, maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
assertFitted();
final Rect bounds = mActivity.getBounds();
@@ -286,7 +286,7 @@ public class SizeCompatTests extends WindowTestsBase {
public void testAspectRatioMatchParentBoundsAndImeAttachable() {
setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2000)
.setSystemDecorations(true).build());
- prepareUnresizable(2f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+ prepareUnresizable(mActivity, 2f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
assertFitted();
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
@@ -307,7 +307,7 @@ public class SizeCompatTests extends WindowTestsBase {
@Test
public void testMoveToDifferentOrientDisplay() {
setUpDisplaySizeWithApp(1000, 2500);
- prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
final Rect configBounds = mActivity.getWindowConfiguration().getBounds();
@@ -352,7 +352,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2500)
.setNotch(notchHeight).build());
// Bounds=[0, 0 - 1000, 1460], AppBounds=[0, 60 - 1000, 1460].
- prepareUnresizable(1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, 1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
@@ -381,7 +381,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpDisplaySizeWithApp(1000, 2500);
final float maxAspect = 1.4f;
- prepareUnresizable(maxAspect, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, maxAspect, SCREEN_ORIENTATION_PORTRAIT);
// The display aspect ratio 2.5 > 1.4 (max of activity), so the size is fitted.
assertFitted();
@@ -415,7 +415,7 @@ public class SizeCompatTests extends WindowTestsBase {
Configuration c = new Configuration(mTask.getRequestedOverrideConfiguration());
c.screenLayout = fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR;
mTask.onRequestedOverrideConfigurationChanged(c);
- prepareUnresizable(1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
+ prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
// The initial configuration should inherit from parent.
assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR,
@@ -433,7 +433,7 @@ public class SizeCompatTests extends WindowTestsBase {
@Test
public void testResetNonVisibleActivity() {
setUpDisplaySizeWithApp(1000, 2500);
- prepareUnresizable(1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
+ prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
final DisplayContent display = mTask.mDisplayContent;
// Resize the display so the activity is in size compatibility mode.
resizeDisplay(display, 900, 1800);
@@ -472,7 +472,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpDisplaySizeWithApp(1000, 2000);
ActivityRecord activity = mActivity;
activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
- prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
final ArrayList<IBinder> compatTokens = new ArrayList<>();
@@ -545,7 +545,7 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN);
mActivity.mDisplayContent.mOpeningApps.add(mActivity);
final float maxAspect = 1.8f;
- prepareUnresizable(maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
+ prepareUnresizable(mActivity, maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
assertFitted();
assertTrue(mActivity.isFixedRotationTransforming());
@@ -576,7 +576,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertFalse(statusBarController.isTransparentAllowed(w));
// Make the activity fill the display.
- prepareUnresizable(10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
+ prepareUnresizable(mActivity, 10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
// Refresh the letterbox.
mActivity.mRootWindowContainer.performSurfacePlacement();
@@ -593,11 +593,11 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
- prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- final Rect displayBounds = mActivity.mDisplayContent.getBounds();
- final Rect taskBounds = mTask.getBounds();
- final Rect activityBounds = mActivity.getBounds();
+ final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+ final Rect taskBounds = new Rect(mTask.getBounds());
+ final Rect activityBounds = new Rect(mActivity.getBounds());
// Display shouldn't be rotated.
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED,
@@ -622,15 +622,15 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
- prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- final Rect activityBounds = mActivity.getBounds();
+ final Rect activityBounds = new Rect(mActivity.getBounds());
// Rotate display to portrait.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
- final Rect displayBounds = mActivity.mDisplayContent.getBounds();
- final Rect newActivityBounds = mActivity.getBounds();
+ final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+ final Rect newActivityBounds = new Rect(mActivity.getBounds());
assertTrue(displayBounds.width() < displayBounds.height());
// App should be in size compat.
@@ -647,10 +647,10 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
- prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- Rect displayBounds = mActivity.mDisplayContent.getBounds();
- Rect activityBounds = mActivity.getBounds();
+ Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+ Rect activityBounds = new Rect(mActivity.getBounds());
// App should launch in fullscreen.
assertFalse(mTask.isTaskLetterboxed());
@@ -660,8 +660,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Rotate display to landscape.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
- displayBounds = mActivity.mDisplayContent.getBounds();
- activityBounds = mActivity.getBounds();
+ displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+ activityBounds = new Rect(mActivity.getBounds());
assertTrue(displayBounds.width() > displayBounds.height());
// App should be in size compat.
@@ -682,7 +682,7 @@ public class SizeCompatTests extends WindowTestsBase {
display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
- prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
assertTrue(mTask.isTaskLetterboxed());
assertFalse(mActivity.inSizeCompatMode());
@@ -701,9 +701,9 @@ public class SizeCompatTests extends WindowTestsBase {
verify(mTask).onDescendantOrientationChanged(same(newActivity));
verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
- final Rect displayBounds = display.getBounds();
- final Rect taskBounds = mTask.getBounds();
- final Rect newActivityBounds = newActivity.getBounds();
+ final Rect displayBounds = new Rect(display.getBounds());
+ final Rect taskBounds = new Rect(mTask.getBounds());
+ final Rect newActivityBounds = new Rect(newActivity.getBounds());
// Task and app bounds should be 700x1400 with the ratio as the display.
assertTrue(mTask.isTaskLetterboxed());
@@ -722,7 +722,7 @@ public class SizeCompatTests extends WindowTestsBase {
display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
- prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
assertTrue(mTask.isTaskLetterboxed());
assertFalse(mActivity.inSizeCompatMode());
@@ -742,9 +742,9 @@ public class SizeCompatTests extends WindowTestsBase {
verify(mTask).onDescendantOrientationChanged(same(newActivity));
verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
- final Rect displayBounds = display.getBounds();
- final Rect taskBounds = mTask.getBounds();
- final Rect newActivityBounds = newActivity.getBounds();
+ final Rect displayBounds = new Rect(display.getBounds());
+ final Rect taskBounds = new Rect(mTask.getBounds());
+ final Rect newActivityBounds = new Rect(newActivity.getBounds());
// Task bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio.
assertTrue(mTask.isTaskLetterboxed());
@@ -765,7 +765,7 @@ public class SizeCompatTests extends WindowTestsBase {
display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app.
- prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+ prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
clearInvocations(mActivity);
assertTrue(mTask.isTaskLetterboxed());
@@ -829,26 +829,31 @@ public class SizeCompatTests extends WindowTestsBase {
displayContent.getConfiguration().uiMode);
}
+ static void prepareUnresizable(ActivityRecord activity, int screenOrientation) {
+ prepareUnresizable(activity, -1 /* maxAspect */, screenOrientation);
+ }
+
/**
- * Setup {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
+ * Setups {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
* orientation.
*/
- private void prepareUnresizable(float maxAspect, int screenOrientation) {
- mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
- mActivity.mVisibleRequested = true;
+ static void prepareUnresizable(ActivityRecord activity, float maxAspect,
+ int screenOrientation) {
+ activity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+ activity.mVisibleRequested = true;
if (maxAspect >= 0) {
- mActivity.info.maxAspectRatio = maxAspect;
+ activity.info.maxAspectRatio = maxAspect;
}
if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
- mActivity.info.screenOrientation = screenOrientation;
- mActivity.setRequestedOrientation(screenOrientation);
+ activity.info.screenOrientation = screenOrientation;
+ activity.setRequestedOrientation(screenOrientation);
}
// Make sure to use the provided configuration to construct the size compat fields.
- mActivity.clearSizeCompatMode();
- mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
+ activity.clearSizeCompatMode();
+ activity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
// Make sure the display configuration reflects the change of activity.
- if (mActivity.mDisplayContent.updateOrientation()) {
- mActivity.mDisplayContent.sendNewConfiguration();
+ if (activity.mDisplayContent.updateOrientation()) {
+ activity.mDisplayContent.sendNewConfiguration();
}
}
@@ -869,7 +874,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertFalse(mActivity.hasSizeCompatBounds());
}
- private static Configuration rotateDisplay(DisplayContent display, int rotation) {
+ static Configuration rotateDisplay(DisplayContent display, int rotation) {
final Configuration c = new Configuration();
display.getDisplayRotation().setRotation(rotation);
display.computeScreenConfiguration(c);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index e95efe785e8c..b1065914a925 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -37,7 +37,8 @@ import android.view.DisplayInfo;
class TestDisplayContent extends DisplayContent {
- private TestDisplayContent(RootWindowContainer rootWindowContainer, Display display) {
+ /** Please use the {@link Builder} to create, visible for use in test builder overrides only. */
+ TestDisplayContent(RootWindowContainer rootWindowContainer, Display display) {
super(display, rootWindowContainer);
// Normally this comes from display-properties as exposed by WM. Without that, just
// hard-code to FULLSCREEN for tests.
@@ -72,7 +73,7 @@ class TestDisplayContent extends DisplayContent {
private boolean mCanRotate = true;
private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
private int mPosition = POSITION_BOTTOM;
- private final ActivityTaskManagerService mService;
+ protected final ActivityTaskManagerService mService;
private boolean mSystemDecorations = false;
Builder(ActivityTaskManagerService service, int width, int height) {
@@ -125,14 +126,16 @@ class TestDisplayContent extends DisplayContent {
mInfo.logicalDensityDpi = dpi;
return this;
}
+ TestDisplayContent createInternal(Display display) {
+ return new TestDisplayContent(mService.mRootWindowContainer, display);
+ }
TestDisplayContent build() {
SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
final int displayId = SystemServicesTestRule.sNextDisplayId++;
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
- final TestDisplayContent newDisplay =
- new TestDisplayContent(mService.mRootWindowContainer, display);
+ final TestDisplayContent newDisplay = createInternal(display);
// disable the normal system decorations
final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy();
spyOn(displayPolicy);