summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java11
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java11
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java18
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java81
5 files changed, 125 insertions, 0 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 571537c3cc22..462110f5a795 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;
@@ -90,6 +91,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 4a66d3ab2c37..a87fb8b5c301 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2516,6 +2516,17 @@ public final class DisplayManagerService extends SystemService {
}
@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) {
throw new IllegalArgumentException("listener must not be null");
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 3a5aa93d205d..0261f388f7cb 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;
@@ -98,6 +99,11 @@ final class LogicalDisplay {
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.
* @see #isDisplayScalingDisabled()
@@ -335,6 +341,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 7931cd58d977..a93b962c33b4 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5433,6 +5433,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return mDisplayPolicy.getSystemUiContext();
}
+ Point getDisplayPosition() {
+ return mWmService.mDisplayManagerInternal.getDisplayPosition(getDisplayId());
+ }
+
class RemoteInsetsControlTarget implements InsetsControlTarget {
private final IDisplayWindowInsetsController mRemoteInsetsController;
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
new file mode 100644
index 000000000000..301a9fe64d5e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.display;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Point;
+import android.view.DisplayInfo;
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+public class LogicalDisplayTest {
+ private static final int DISPLAY_ID = 0;
+ private static final int LAYER_STACK = 0;
+ private static final int DISPLAY_WIDTH = 100;
+ private static final int DISPLAY_HEIGHT = 200;
+
+ private LogicalDisplay mLogicalDisplay;
+ private DisplayDevice mDisplayDevice;
+
+ @Before
+ public void setUp() {
+ // Share classloader to allow package private access.
+ System.setProperty("dexmaker.share_classloader", "true");
+ mDisplayDevice = mock(DisplayDevice.class);
+ DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
+ displayDeviceInfo.width = DISPLAY_WIDTH;
+ displayDeviceInfo.height = DISPLAY_HEIGHT;
+ displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+ mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice);
+ when(mDisplayDevice.getDisplayDeviceInfoLocked()).thenReturn(displayDeviceInfo);
+
+ ArrayList<DisplayDevice> 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());
+ }
+}