Merge "Transform displayMetrics if needed" into udc-dev

This commit is contained in:
Treehugger Robot
2023-06-14 23:16:45 +00:00
committed by Android (Google) Code Review
2 changed files with 146 additions and 6 deletions

View File

@@ -28,6 +28,7 @@ import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.Display;
import android.view.DisplayAddress;
import android.view.Surface;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -36,6 +37,7 @@ import androidx.window.extensions.core.util.function.Consumer;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import java.util.Objects;
@@ -229,27 +231,41 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
* @since {@link WindowExtensions#VENDOR_API_LEVEL_3}
*/
@Override
@NonNull
public DisplayMetrics getRearDisplayMetrics() {
DisplayMetrics metrics = null;
DisplayMetrics rearDisplayMetrics = null;
// DISPLAY_CATEGORY_REAR displays are only available when you are in the concurrent
// display state, so we have to look through all displays to match the address
Display[] displays = mDisplayManager.getDisplays(
final Display[] displays = mDisplayManager.getDisplays(
DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
final Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
for (int i = 0; i < displays.length; i++) {
DisplayAddress.Physical address =
(DisplayAddress.Physical) displays[i].getAddress();
if (mRearDisplayAddress == address.getPhysicalDisplayId()) {
metrics = new DisplayMetrics();
displays[i].getRealMetrics(metrics);
rearDisplayMetrics = new DisplayMetrics();
final Display rearDisplay = displays[i];
// We must always retrieve the metrics for the rear display regardless of if it is
// the default display or not.
rearDisplay.getRealMetrics(rearDisplayMetrics);
// TODO(b/287170025): This should be something like if (!rearDisplay.isEnabled)
// instead. Currently when the rear display is disabled, its state is STATE_OFF.
if (rearDisplay.getDisplayId() != Display.DEFAULT_DISPLAY) {
rotateRearDisplayMetricsIfNeeded(defaultDisplay.getRotation(),
rearDisplay.getRotation(), rearDisplayMetrics);
}
break;
}
}
synchronized (mLock) {
// Update the rear display metrics with our latest value if one was received
if (metrics != null) {
mRearDisplayMetrics = metrics;
if (rearDisplayMetrics != null) {
mRearDisplayMetrics = rearDisplayMetrics;
}
return Objects.requireNonNullElseGet(mRearDisplayMetrics, DisplayMetrics::new);
@@ -540,6 +556,34 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
return mLastReportedRearDisplayPresentationStatus;
}
@VisibleForTesting
static void rotateRearDisplayMetricsIfNeeded(
@Surface.Rotation int defaultDisplayRotation,
@Surface.Rotation int rearDisplayRotation,
@NonNull DisplayMetrics inOutMetrics) {
// If the rear display has a non-zero rotation, it means the backing DisplayContent /
// DisplayRotation is fresh.
if (rearDisplayRotation != Surface.ROTATION_0) {
return;
}
// If the default display is 0 or 180, the rear display must also be 0 or 180.
if (defaultDisplayRotation == Surface.ROTATION_0
|| defaultDisplayRotation == Surface.ROTATION_180) {
return;
}
final int heightPixels = inOutMetrics.heightPixels;
final int widthPixels = inOutMetrics.widthPixels;
inOutMetrics.widthPixels = heightPixels;
inOutMetrics.heightPixels = widthPixels;
final int noncompatHeightPixels = inOutMetrics.noncompatHeightPixels;
final int noncompatWidthPixels = inOutMetrics.noncompatWidthPixels;
inOutMetrics.noncompatWidthPixels = noncompatHeightPixels;
inOutMetrics.noncompatHeightPixels = noncompatWidthPixels;
}
/**
* Callback for the {@link DeviceStateRequest} to be notified of when the request has been
* activated or cancelled. This callback provides information to the client library

View File

@@ -0,0 +1,96 @@
/*
* 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 androidx.window.extensions.area;
import static org.junit.Assert.assertEquals;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
import android.view.Surface;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
public class WindowAreaComponentImplTests {
private final DisplayMetrics mTestDisplayMetrics = new DisplayMetrics();
@Before
public void setup() {
mTestDisplayMetrics.widthPixels = 1;
mTestDisplayMetrics.heightPixels = 2;
mTestDisplayMetrics.noncompatWidthPixels = 3;
mTestDisplayMetrics.noncompatHeightPixels = 4;
}
/**
* Cases where the rear display metrics does not need to be transformed.
*/
@Test
public void testRotateRearDisplayMetrics_noTransformNeeded() {
final DisplayMetrics originalMetrics = new DisplayMetrics();
originalMetrics.setTo(mTestDisplayMetrics);
WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded(
Surface.ROTATION_0, Surface.ROTATION_0, mTestDisplayMetrics);
assertEquals(originalMetrics, mTestDisplayMetrics);
WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded(
Surface.ROTATION_180, Surface.ROTATION_180, mTestDisplayMetrics);
assertEquals(originalMetrics, mTestDisplayMetrics);
WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded(
Surface.ROTATION_0, Surface.ROTATION_180, mTestDisplayMetrics);
assertEquals(originalMetrics, mTestDisplayMetrics);
WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded(
Surface.ROTATION_180, Surface.ROTATION_0, mTestDisplayMetrics);
assertEquals(originalMetrics, mTestDisplayMetrics);
}
/**
* Cases where the rear display metrics need to be transformed.
*/
@Test
public void testRotateRearDisplayMetrics_transformNeeded() {
DisplayMetrics originalMetrics = new DisplayMetrics();
originalMetrics.setTo(mTestDisplayMetrics);
DisplayMetrics expectedMetrics = new DisplayMetrics();
expectedMetrics.setTo(mTestDisplayMetrics);
expectedMetrics.widthPixels = mTestDisplayMetrics.heightPixels;
expectedMetrics.heightPixels = mTestDisplayMetrics.widthPixels;
expectedMetrics.noncompatWidthPixels = mTestDisplayMetrics.noncompatHeightPixels;
expectedMetrics.noncompatHeightPixels = mTestDisplayMetrics.noncompatWidthPixels;
WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded(
Surface.ROTATION_90, Surface.ROTATION_0, mTestDisplayMetrics);
assertEquals(expectedMetrics, mTestDisplayMetrics);
mTestDisplayMetrics.setTo(originalMetrics);
WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded(
Surface.ROTATION_270, Surface.ROTATION_0, mTestDisplayMetrics);
assertEquals(expectedMetrics, mTestDisplayMetrics);
}
}