From 945f7301f00c825552840dc320ad7981c2706731 Mon Sep 17 00:00:00 2001 From: chaviw Date: Mon, 24 Feb 2020 14:35:33 -0800 Subject: [PATCH] Added displayPosition in LogicalDisplay Allow WindowManager to get display position from DisplayManager. This will allow display animations to work since we need to know the initial position of the display to correctly handle animations Test: LogicalDisplayTest Bug: 149490428 Change-Id: I5de2495982294ffa0437d8e87a43bf1d2fd0d86a --- .../display/DisplayManagerInternal.java | 11 +++ .../server/display/DisplayManagerService.java | 11 +++ .../server/display/LogicalDisplay.java | 18 +++++ .../com/android/server/wm/DisplayContent.java | 4 + .../server/display/LogicalDisplayTest.java | 81 +++++++++++++++++++ 5 files changed, 125 insertions(+) create mode 100644 services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index ea2b9e79d99c8..1c42db9a3f8d6 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -17,6 +17,7 @@ package android.hardware.display; import android.annotation.Nullable; +import android.graphics.Point; import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; @@ -80,6 +81,16 @@ public abstract class DisplayManagerInternal { */ public abstract DisplayInfo getDisplayInfo(int displayId); + /** + * Returns the position of the display's projection. + * + * @param displayId The logical display id. + * @return The x, y coordinates of the display, or null if the display does not exist. The + * return object must be treated as immutable. + */ + @Nullable + public abstract Point getDisplayPosition(int displayId); + /** * Registers a display transaction listener to provide the client a chance to * update its surfaces within the same transaction as any display layout updates. diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index a23205124f74f..677555659186f 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -2482,6 +2482,17 @@ public final class DisplayManagerService extends SystemService { return getDisplayInfoInternal(displayId, Process.myUid()); } + @Override + public Point getDisplayPosition(int displayId) { + synchronized (mSyncRoot) { + LogicalDisplay display = mLogicalDisplays.get(displayId); + if (display != null) { + return display.getDisplayPosition(); + } + return null; + } + } + @Override public void registerDisplayTransactionListener(DisplayTransactionListener listener) { if (listener == null) { diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 3a5aa93d205dc..0261f388f7cbe 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -16,6 +16,7 @@ package com.android.server.display; +import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManagerInternal; import android.view.Display; @@ -97,6 +98,11 @@ final class LogicalDisplay { private int mDisplayOffsetX; private int mDisplayOffsetY; + /** + * The position of the display projection sent to SurfaceFlinger + */ + private final Point mDisplayPosition = new Point(); + /** * {@code true} if display scaling is disabled, or {@code false} if the default scaling mode * is used. @@ -334,6 +340,16 @@ final class LogicalDisplay { } } + /** + * Returns the position of the display's projection. + * + * @return The x, y coordinates of the display. The return object must be treated as immutable. + */ + Point getDisplayPosition() { + // Allocate a new object to avoid a data race. + return new Point(mDisplayPosition); + } + /** * Applies the layer stack and transformation to the given display device * so that it shows the contents of this logical display. @@ -445,6 +461,8 @@ final class LogicalDisplay { } else { // Surface.ROTATION_270 mTempDisplayRect.offset(-mDisplayOffsetY, mDisplayOffsetX); } + + mDisplayPosition.set(mTempDisplayRect.left, mTempDisplayRect.top); device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect); } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 55b7be779690b..2d8f093016e55 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5481,6 +5481,10 @@ class DisplayContent extends WindowContainer displayDevices = new ArrayList<>(); + displayDevices.add(mDisplayDevice); + mLogicalDisplay.updateLocked(displayDevices); + } + + @Test + public void testGetDisplayPosition() { + Point expectedPosition = new Point(); + + SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class); + mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition()); + + expectedPosition.set(20, 40); + mLogicalDisplay.setDisplayOffsetsLocked(20, 40); + mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition()); + + expectedPosition.set(40, -20); + DisplayInfo displayInfo = new DisplayInfo(); + displayInfo.logicalWidth = DISPLAY_HEIGHT; + displayInfo.logicalHeight = DISPLAY_WIDTH; + displayInfo.rotation = Surface.ROTATION_90; + mLogicalDisplay.setDisplayInfoOverrideFromWindowManagerLocked(displayInfo); + mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition()); + } +}