diff options
| author | 2023-08-18 13:18:48 +0000 | |
|---|---|---|
| committer | 2023-08-18 13:18:48 +0000 | |
| commit | 9a58f977014de3d4498a14efece3fe33ea6c0b56 (patch) | |
| tree | 5deddd1e09a05a3b3b06b93883cbb2ccd15778ac | |
| parent | 722b67cf7d1c60464742bf65fccffacefed2f291 (diff) | |
| parent | 8b6dc421decf2b3a7293b2f90652f56b6e12be3e (diff) | |
Merge "[MediaProjection][ConcurrentDisplays] mirroring rotation fix" into udc-qpr-dev
3 files changed, 132 insertions, 5 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 94bff893b5a8..4700720736b5 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -370,8 +370,9 @@ public abstract class DisplayManagerInternal { /** * Returns the default size of the surface associated with the display, or null if the surface - * is not provided for layer mirroring by SurfaceFlinger. - * Only used for mirroring started from MediaProjection. + * is not provided for layer mirroring by SurfaceFlinger. Size is rotated to reflect the current + * display device orientation. + * Used for mirroring from MediaProjection, or a physical display based on display flags. */ public abstract Point getDisplaySurfaceDefaultSize(int displayId); diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index d57dc471694e..8642fb888556 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -16,6 +16,9 @@ package com.android.server.display; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; + import android.annotation.Nullable; import android.content.Context; import android.graphics.Point; @@ -132,12 +135,15 @@ abstract class DisplayDevice { /** * Returns the default size of the surface associated with the display, or null if the surface * is not provided for layer mirroring by SurfaceFlinger. For non virtual displays, this will - * be the actual display device's size. + * be the actual display device's size, reflecting the current rotation. */ @Nullable public Point getDisplaySurfaceDefaultSizeLocked() { DisplayDeviceInfo displayDeviceInfo = getDisplayDeviceInfoLocked(); - return new Point(displayDeviceInfo.width, displayDeviceInfo.height); + final boolean isRotated = mCurrentOrientation == ROTATION_90 + || mCurrentOrientation == ROTATION_270; + return isRotated ? new Point(displayDeviceInfo.height, displayDeviceInfo.width) + : new Point(displayDeviceInfo.width, displayDeviceInfo.height); } /** @@ -358,7 +364,7 @@ abstract class DisplayDevice { } boolean isRotated = (mCurrentOrientation == Surface.ROTATION_90 - || mCurrentOrientation == Surface.ROTATION_270); + || mCurrentOrientation == ROTATION_270); DisplayDeviceInfo info = getDisplayDeviceInfoLocked(); viewport.deviceWidth = isRotated ? info.height : info.width; viewport.deviceHeight = isRotated ? info.width : info.height; diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java new file mode 100644 index 000000000000..4fd8f26d91a8 --- /dev/null +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2023 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 android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_180; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; + +import static com.google.common.truth.Truth.assertThat; + +import android.graphics.Point; +import android.graphics.Rect; +import android.platform.test.annotations.Presubmit; +import android.view.SurfaceControl; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Tests for the {@link DisplayDevice} class. + * + * Build/Install/Run: + * atest DisplayServicesTests:DisplayDeviceTest + */ +@SmallTest +@Presubmit +@RunWith(AndroidJUnit4.class) +public class DisplayDeviceTest { + private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo(); + private static final int WIDTH = 500; + private static final int HEIGHT = 900; + private static final Point PORTRAIT_SIZE = new Point(WIDTH, HEIGHT); + private static final Point LANDSCAPE_SIZE = new Point(HEIGHT, WIDTH); + + @Mock + private SurfaceControl.Transaction mMockTransaction; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mDisplayDeviceInfo.width = WIDTH; + mDisplayDeviceInfo.height = HEIGHT; + mDisplayDeviceInfo.rotation = ROTATION_0; + } + + @Test + public void testGetDisplaySurfaceDefaultSizeLocked_notRotated() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE); + } + + @Test + public void testGetDisplaySurfaceDefaultSizeLocked_rotation0() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + displayDevice.setProjectionLocked(mMockTransaction, ROTATION_0, new Rect(), new Rect()); + assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE); + } + + @Test + public void testGetDisplaySurfaceDefaultSizeLocked_rotation90() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + displayDevice.setProjectionLocked(mMockTransaction, ROTATION_90, new Rect(), new Rect()); + assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE); + } + + @Test + public void testGetDisplaySurfaceDefaultSizeLocked_rotation180() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + displayDevice.setProjectionLocked(mMockTransaction, ROTATION_180, new Rect(), new Rect()); + assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE); + } + + @Test + public void testGetDisplaySurfaceDefaultSizeLocked_rotation270() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + displayDevice.setProjectionLocked(mMockTransaction, ROTATION_270, new Rect(), new Rect()); + assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE); + } + + private static class FakeDisplayDevice extends DisplayDevice { + private final DisplayDeviceInfo mDisplayDeviceInfo; + + FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo) { + super(null, null, "", InstrumentationRegistry.getInstrumentation().getContext()); + mDisplayDeviceInfo = displayDeviceInfo; + } + + @Override + public boolean hasStableUniqueId() { + return false; + } + + @Override + public DisplayDeviceInfo getDisplayDeviceInfoLocked() { + return mDisplayDeviceInfo; + } + } +} |