Support rotation on secondary displays (1/N)
- Allow to apply rotation animation on non-default display.
- Separate by display:
Rotation related timeout.
Pause/resume rotation.
- Able to get/watch non-default display orientation/rotation.
Bug: 111361251
Test: atest FrameworksServicesTests:DisplayContentTests
Test: go/wm-smoke
Change-Id: I9533f1b90b9969d455b6dc235c5318e39f63ab12
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 0a77269..75b3556 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2165,6 +2165,24 @@
}
@Override
+ public boolean screenshot(int displayId, Surface outSurface) {
+ synchronized (mSyncRoot) {
+ final LogicalDisplay display = mLogicalDisplays.get(displayId);
+ if (display != null) {
+ final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+ if (device != null) {
+ final IBinder token = device.getDisplayTokenLocked();
+ if (token != null) {
+ SurfaceControl.screenshot(token, outSurface);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
public DisplayInfo getDisplayInfo(int displayId) {
return getDisplayInfoInternal(displayId, Process.myUid());
}
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 1977e12..fff1fa4 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -56,6 +56,7 @@
.setParent(null) // TODO: Work-around for b/69259549
.build();
+ transaction.setLayerStack(surface, dc.getDisplayId());
transaction.setAlpha(surface, 1);
transaction.setLayer(surface, layer);
transaction.show(surface);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0ca8e1a..efe4d6f 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -303,6 +303,7 @@
// Accessed directly by all users.
private boolean mLayoutNeeded;
int pendingLayoutChanges;
+ int mDeferredRotationPauseCount;
// TODO(multi-display): remove some of the usages.
boolean isDefaultDisplay;
/**
@@ -942,6 +943,36 @@
}
/**
+ * Temporarily pauses rotation changes until resumed.
+ *
+ * This can be used to prevent rotation changes from occurring while the user is
+ * performing certain operations, such as drag and drop.
+ *
+ * This call nests and must be matched by an equal number of calls to
+ * {@link #resumeRotationLocked}.
+ */
+ void pauseRotationLocked() {
+ mDeferredRotationPauseCount++;
+ }
+
+ /**
+ * Resumes normal rotation changes after being paused.
+ */
+ void resumeRotationLocked() {
+ if (mDeferredRotationPauseCount <= 0) {
+ return;
+ }
+
+ mDeferredRotationPauseCount--;
+ if (mDeferredRotationPauseCount == 0) {
+ final boolean changed = updateRotationUnchecked();
+ if (changed) {
+ mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
+ }
+ }
+ }
+
+ /**
* Update rotation of the display.
*
* @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
@@ -964,7 +995,7 @@
boolean updateRotationUnchecked(boolean forceUpdate) {
ScreenRotationAnimation screenRotationAnimation;
if (!forceUpdate) {
- if (mService.mDeferredRotationPauseCount > 0) {
+ if (mDeferredRotationPauseCount > 0) {
// Rotation updates have been paused temporarily. Defer the update until
// updates have been resumed.
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
@@ -1065,9 +1096,8 @@
}
mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
- mService.mH.removeMessages(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT);
- mService.mH.sendEmptyMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,
- WINDOW_FREEZE_TIMEOUT_DURATION);
+ mService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,
+ this, WINDOW_FREEZE_TIMEOUT_DURATION);
setLayoutNeeded();
final int[] anim = new int[2];
@@ -1124,9 +1154,8 @@
}, true /* traverseTopToBottom */);
if (rotateSeamlessly) {
- mService.mH.removeMessages(WindowManagerService.H.SEAMLESS_ROTATION_TIMEOUT);
- mService.mH.sendEmptyMessageDelayed(WindowManagerService.H.SEAMLESS_ROTATION_TIMEOUT,
- SEAMLESS_ROTATION_TIMEOUT_DURATION);
+ mService.mH.sendNewMessageDelayed(WindowManagerService.H.SEAMLESS_ROTATION_TIMEOUT,
+ this, SEAMLESS_ROTATION_TIMEOUT_DURATION);
}
for (int i = mService.mRotationWatchers.size() - 1; i >= 0; i--) {
@@ -2282,6 +2311,8 @@
pw.println();
pw.print(prefix); pw.print("mLayoutSeq="); pw.println(mLayoutSeq);
+ pw.print(prefix);
+ pw.print("mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
pw.println();
pw.println(prefix + "Application tokens in top down Z order:");
@@ -2876,7 +2907,7 @@
mWallpaperController.adjustWallpaperWindows(this);
}
- if (isDefaultDisplay && (pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
+ if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
if (mService.updateOrientationFromAppTokensLocked(mDisplayId)) {
setLayoutNeeded();
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index fc370d9..f42e979 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -151,6 +151,7 @@
mDragState.mUid = callerUid;
mDragState.mOriginalAlpha = alpha;
mDragState.mToken = dragToken;
+ mDragState.mDisplayContent = displayContent;
final Display display = displayContent.getDisplay();
if (!mCallback.get().registerInputChannel(
@@ -160,7 +161,6 @@
return null;
}
- mDragState.mDisplayContent = displayContent;
mDragState.mData = data;
mDragState.broadcastDragStartedLocked(touchX, touchY);
mDragState.overridePointerIconLocked(touchSource);
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 1ac9b88..d4046e9 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -255,7 +255,7 @@
if (DEBUG_ORIENTATION) {
Slog.d(TAG_WM, "Pausing rotation during drag");
}
- mService.pauseRotationLocked();
+ mDisplayContent.pauseRotationLocked();
}
void tearDown() {
@@ -274,7 +274,7 @@
if (DEBUG_ORIENTATION) {
Slog.d(TAG_WM, "Resuming rotation after drag");
}
- mService.resumeRotationLocked();
+ mDisplayContent.resumeRotationLocked();
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a709c55..2be4001 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -746,22 +746,7 @@
if (mUpdateRotation) {
if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
- // TODO(multi-display): Update rotation for different displays separately.
- final int displayId = defaultDisplay.getDisplayId();
- if (defaultDisplay.updateRotationUnchecked()) {
- mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
- } else {
- mUpdateRotation = false;
- }
- // Update rotation of VR virtual display separately. Currently this is the only kind of
- // secondary display that can be rotated because of the single-display limitations in
- // PhoneWindowManager.
- final DisplayContent vrDisplay = mService.mVr2dDisplayId != INVALID_DISPLAY
- ? getDisplayContent(mService.mVr2dDisplayId) : null;
- if (vrDisplay != null && vrDisplay.updateRotationUnchecked()) {
- mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mService.mVr2dDisplayId)
- .sendToTarget();
- }
+ mUpdateRotation = updateRotationUnchecked();
}
if (mService.mWaitingForDrawnCallback != null ||
@@ -958,6 +943,19 @@
return displayHasContent;
}
+ boolean updateRotationUnchecked() {
+ boolean changed = false;
+ for (int i = mChildren.size() - 1; i >= 0; i--) {
+ final DisplayContent displayContent = mChildren.get(i);
+ if (displayContent.updateRotationUnchecked()) {
+ changed = true;
+ mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
+ .sendToTarget();
+ }
+ }
+ return changed;
+ }
+
boolean copyAnimToLayoutParams() {
boolean doRequest = false;
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index fa8a5c6..2f189a6 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -268,24 +268,18 @@
.setSecure(isSecure)
.build();
- // capture a screenshot into the surface we just created
- // TODO(multidisplay): we should use the proper display
- final int displayId = SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN;
- final IBinder displayHandle = SurfaceControl.getBuiltInDisplay(displayId);
- // This null check below is to guard a race condition where WMS didn't have a chance to
- // respond to display disconnection before handling rotation , that surfaceflinger may
- // return a null handle here because it doesn't think that display is valid anymore.
- if (displayHandle != null) {
- Surface sur = new Surface();
- sur.copyFrom(mSurfaceControl);
- SurfaceControl.screenshot(displayHandle, sur);
+ // Capture a screenshot into the surface we just created.
+ final int displayId = display.getDisplayId();
+ final Surface surface = new Surface();
+ surface.copyFrom(mSurfaceControl);
+ if (mService.mDisplayManagerInternal.screenshot(displayId, surface)) {
t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
t.setAlpha(mSurfaceControl, 0);
t.show(mSurfaceControl);
- sur.destroy();
} else {
- Slog.w(TAG, "Built-in display " + displayId + " is null.");
+ Slog.w(TAG, "Unable to take screenshot of display " + displayId);
}
+ surface.destroy();
} catch (OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate freeze surface", e);
}
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 30f46a0..bd7e61c 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -97,7 +97,7 @@
private final WindowManagerService mService;
private final IActivityTaskManager mActivityManager;
private WindowPositionerEventReceiver mInputEventReceiver;
- private Display mDisplay;
+ private DisplayContent mDisplayContent;
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
private Rect mTmpRect = new Rect();
private int mSideMargin;
@@ -250,8 +250,8 @@
return;
}
- mDisplay = display;
- mDisplay.getMetrics(mDisplayMetrics);
+ mDisplayContent = displayContent;
+ display.getMetrics(mDisplayMetrics);
final InputChannel[] channels = InputChannel.openInputChannelPair(TAG);
mServerChannel = channels[0];
mClientChannel = channels[1];
@@ -267,7 +267,7 @@
WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null, null,
- mDisplay.getDisplayId());
+ display.getDisplayId());
mDragWindowHandle.name = TAG;
mDragWindowHandle.inputChannel = mServerChannel;
mDragWindowHandle.layer = mService.getDragLayerLocked();
@@ -292,7 +292,7 @@
mDragWindowHandle.frameLeft = 0;
mDragWindowHandle.frameTop = 0;
final Point p = new Point();
- mDisplay.getRealSize(p);
+ display.getRealSize(p);
mDragWindowHandle.frameRight = p.x;
mDragWindowHandle.frameBottom = p.y;
@@ -300,12 +300,12 @@
if (DEBUG_ORIENTATION) {
Slog.d(TAG, "Pausing rotation during re-position");
}
- mService.pauseRotationLocked();
+ mDisplayContent.pauseRotationLocked();
mSideMargin = dipToPixel(SIDE_MARGIN_DIP, mDisplayMetrics);
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, mDisplayMetrics);
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, mDisplayMetrics);
- mDisplay.getRealSize(mMaxVisibleSize);
+ display.getRealSize(mMaxVisibleSize);
mDragEnded = false;
}
@@ -331,14 +331,14 @@
mDragWindowHandle = null;
mDragApplicationHandle = null;
- mDisplay = null;
mDragEnded = true;
// Resume rotations after a drag.
if (DEBUG_ORIENTATION) {
Slog.d(TAG, "Resuming rotation after re-position");
}
- mService.resumeRotationLocked();
+ mDisplayContent.resumeRotationLocked();
+ mDisplayContent = null;
}
void startDrag(WindowState win, boolean resize, boolean preserveOrientation, float startX,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 54703b3..f09ef86 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -583,7 +583,6 @@
}
ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
- int mDeferredRotationPauseCount;
final WallpaperVisibilityListeners mWallpaperVisibilityListeners =
new WallpaperVisibilityListeners();
@@ -3820,37 +3819,6 @@
updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
}
- /**
- * Temporarily pauses rotation changes until resumed.
- *
- * This can be used to prevent rotation changes from occurring while the user is
- * performing certain operations, such as drag and drop.
- *
- * This call nests and must be matched by an equal number of calls to
- * {@link #resumeRotationLocked}.
- */
- void pauseRotationLocked() {
- mDeferredRotationPauseCount += 1;
- }
-
- /**
- * Resumes normal rotation changes after being paused.
- */
- void resumeRotationLocked() {
- if (mDeferredRotationPauseCount > 0) {
- mDeferredRotationPauseCount -= 1;
- if (mDeferredRotationPauseCount == 0) {
- // TODO(multi-display): Update rotation for different displays separately.
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- final boolean changed = displayContent.updateRotationUnchecked();
- if (changed) {
- mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
- .sendToTarget();
- }
- }
- }
- }
-
private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:"
+ " alwaysSendConfiguration=" + alwaysSendConfiguration
@@ -3904,6 +3872,15 @@
@Override
public int watchRotation(IRotationWatcher watcher, int displayId) {
+ final DisplayContent displayContent;
+ synchronized (mWindowMap) {
+ displayContent = mRoot.getDisplayContent(displayId);
+ }
+ if (displayContent == null) {
+ throw new IllegalArgumentException("Trying to register rotation event "
+ + "for invalid display: " + displayId);
+ }
+
final IBinder watcherBinder = watcher.asBinder();
IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
@Override
@@ -3931,7 +3908,7 @@
// Client died, no cleanup needed.
}
- return getDefaultDisplayRotation();
+ return displayContent.getRotation();
}
}
@@ -4716,9 +4693,9 @@
} break;
case WINDOW_FREEZE_TIMEOUT: {
- // TODO(multidisplay): Can non-default displays rotate?
+ final DisplayContent displayContent = (DisplayContent) msg.obj;
synchronized (mWindowMap) {
- getDefaultDisplayContentLocked().onWindowFreezeTimeout();
+ displayContent.onWindowFreezeTimeout();
}
break;
}
@@ -5031,11 +5008,9 @@
}
break;
case SEAMLESS_ROTATION_TIMEOUT: {
- // Rotation only supported on primary display.
- // TODO(multi-display)
- synchronized(mWindowMap) {
- final DisplayContent dc = getDefaultDisplayContentLocked();
- dc.onSeamlessRotationTimeout();
+ final DisplayContent displayContent = (DisplayContent) msg.obj;
+ synchronized (mWindowMap) {
+ displayContent.onSeamlessRotationTimeout();
}
}
break;
@@ -5075,6 +5050,12 @@
Slog.v(TAG_WM, "handleMessage: exit");
}
}
+
+ /** Remove the previous messages with the same 'what' and 'obj' then send the new one. */
+ void sendNewMessageDelayed(int what, Object obj, long delayMillis) {
+ removeMessages(what, obj);
+ sendMessageDelayed(obtainMessage(what, obj), delayMillis);
+ }
}
void destroyPreservedSurfaceLocked() {
@@ -5538,8 +5519,7 @@
mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
// XXX should probably keep timeout from
// when we first froze the display.
- mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
- mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
+ mH.sendNewMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, w.getDisplayContent(),
WINDOW_FREEZE_TIMEOUT_DURATION);
}
}
@@ -5786,8 +5766,7 @@
}
mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
- // TODO(multidisplay): rotation on non-default displays
- if (CUSTOM_SCREEN_ROTATION && displayContent.isDefaultDisplay) {
+ if (CUSTOM_SCREEN_ROTATION) {
mExitAnimId = exitAnim;
mEnterAnimId = enterAnim;
ScreenRotationAnimation screenRotationAnimation =
@@ -6472,7 +6451,6 @@
pw.print(defaultDisplayContent.getLastWindowForcedOrientation());
pw.print(" mLastOrientation=");
pw.println(defaultDisplayContent.getLastOrientation());
- pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
pw.print(" Animation settings: disabled="); pw.print(mAnimationsDisabled);
pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index ec068db..898ff4a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -35,6 +35,8 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -349,34 +351,36 @@
*/
@Test
public void testMaxUiWidth() throws Exception {
+ // Prevent base display metrics for test from being updated to the value of real display.
+ final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
final int baseWidth = 1440;
final int baseHeight = 2560;
final int baseDensity = 300;
- mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+ displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
final int maxWidth = 300;
final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
- mDisplayContent.setMaxUiWidth(maxWidth);
- verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
+ displayContent.setMaxUiWidth(maxWidth);
+ verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
// Assert setting values again does not change;
- mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
- verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
+ displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+ verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
final int smallerWidth = 200;
final int smallerHeight = 400;
final int smallerDensity = 100;
// Specify smaller dimension, verify that it is honored
- mDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
- verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+ displayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
+ verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
// Verify that setting the max width to a greater value than the base width has no effect
- mDisplayContent.setMaxUiWidth(maxWidth);
- verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+ displayContent.setMaxUiWidth(maxWidth);
+ verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
}
/**
@@ -463,22 +467,42 @@
@Test
public void testDisplayCutout_rot90() throws Exception {
synchronized (sWm.getWindowManagerLock()) {
- final DisplayContent dc = createNewDisplay();
- dc.mInitialDisplayWidth = 200;
- dc.mInitialDisplayHeight = 400;
- Rect r1 = new Rect(80, 0, 120, 10);
+ // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
+ // if the device has no cutout).
+ final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
+ // Rotation may use real display info to compute bound, so here also uses the
+ // same width and height.
+ final int displayWidth = dc.mInitialDisplayWidth;
+ final int displayHeight = dc.mInitialDisplayHeight;
+ final int cutoutWidth = 40;
+ final int cutoutHeight = 10;
+ final int left = (displayWidth - cutoutWidth) / 2;
+ final int top = 0;
+ final int right = (displayWidth + cutoutWidth) / 2;
+ final int bottom = cutoutHeight;
+
+ final Rect r1 = new Rect(left, top, right, bottom);
final DisplayCutout cutout = new WmDisplayCutout(
fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom), null)
- .computeSafeInsets(200, 400).getDisplayCutout();
+ .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
dc.mInitialDisplayCutout = cutout;
dc.setRotation(Surface.ROTATION_90);
dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
- final Rect r = new Rect(0, 80, 10, 120);
+ // ----o---------- -------------
+ // | | | | |
+ // | ------o | o---
+ // | | | |
+ // | | -> | |
+ // | | ---o
+ // | | |
+ // | | -------------
+ final Rect r = new Rect(top, left, bottom, right);
assertEquals(new WmDisplayCutout(
fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
- .computeSafeInsets(400, 200).getDisplayCutout(), dc.getDisplayInfo().displayCutout);
+ .computeSafeInsets(displayHeight, displayWidth)
+ .getDisplayCutout(), dc.getDisplayInfo().displayCutout);
}
}
@@ -540,6 +564,16 @@
assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
}
+ /**
+ * Create DisplayContent that does not update display base/initial values from device to keep
+ * the values set by test.
+ */
+ private DisplayContent createDisplayNoUpdateDisplayInfo() {
+ final DisplayContent displayContent = spy(createNewDisplay());
+ doNothing().when(displayContent).updateDisplayInfo();
+ return displayContent;
+ }
+
private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
final LinkedList<WindowState> actualWindows = new LinkedList<>();