Loading core/java/android/hardware/display/DisplayManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading services/core/java/com/android/server/display/DisplayManagerService.java +11 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading services/core/java/com/android/server/display/LogicalDisplay.java +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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. Loading Loading @@ -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); } Loading services/core/java/com/android/server/wm/DisplayContent.java +4 −0 Original line number Diff line number Diff line Loading @@ -6824,6 +6824,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; Loading services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * 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()); } } Loading
core/java/android/hardware/display/DisplayManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading
services/core/java/com/android/server/display/DisplayManagerService.java +11 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading
services/core/java/com/android/server/display/LogicalDisplay.java +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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. Loading Loading @@ -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); } Loading
services/core/java/com/android/server/wm/DisplayContent.java +4 −0 Original line number Diff line number Diff line Loading @@ -6824,6 +6824,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; Loading
services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * 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()); } }