Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f542678 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Transform displayMetrics if needed" into udc-dev

parents ce3d2fa0 32f5bd10
Loading
Loading
Loading
Loading
+50 −6
Original line number Diff line number Diff line
@@ -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
+96 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}