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

Commit abf083db authored by Michael Wright's avatar Michael Wright
Browse files

Rear displays should be considered presentation displays.

At the moment, we only want Presentations being shown on displays in the
rear position. In the future, even if we want to show more than just
Presentations, they're still an ideal target for Presentations so we
just implicitly make things with POSITION_REAR also have the
presentation category.

Also, rename position to device position. This is to avoid confusion
with display position, which is the position of the content on the
display device.

Test: atest LogicalDisplayTest
Bug: 267818951
Change-Id: I425add6fd0416ec2dc09c9ea721c0f24e4644d00
parent d6afb318
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -161,7 +161,11 @@ final class LogicalDisplay {

    // Indicates the position of the display, POSITION_UNKNOWN could mean it hasn't been specified,
    // or this is a virtual display etc.
    private int mPosition = Layout.Display.POSITION_UNKNOWN;
    private int mDevicePosition = Layout.Display.POSITION_UNKNOWN;

    // Indicates that something other than the primary display device info has changed and needs to
    // be handled in the next update.
    private boolean mDirty = false;

    /**
     * The ID of the brightness throttling data that should be used. This can change e.g. in
@@ -181,11 +185,14 @@ final class LogicalDisplay {
        mBrightnessThrottlingDataId = DisplayDeviceConfig.DEFAULT_BRIGHTNESS_THROTTLING_DATA_ID;
    }

    public void setPositionLocked(int position) {
        mPosition = position;
    public void setDevicePositionLocked(int position) {
        if (mDevicePosition != position) {
            mDevicePosition = position;
            mDirty = true;
        }
    }
    public int getPositionLocked() {
        return mPosition;
    public int getDevicePositionLocked() {
        return mDevicePosition;
    }

    /**
@@ -343,9 +350,11 @@ final class LogicalDisplay {
        // logical display that they are sharing.  (eg. Adjust size for pixel-perfect
        // mirroring over HDMI.)
        DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked();
        if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo)) {
        if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo) || mDirty) {
            mBaseDisplayInfo.layerStack = mLayerStack;
            mBaseDisplayInfo.flags = 0;
            // Displays default to moving content to the primary display when removed
            mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
            if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
                mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS;
            }
@@ -443,12 +452,20 @@ final class LogicalDisplay {
            mBaseDisplayInfo.installOrientation = deviceInfo.installOrientation;
            mBaseDisplayInfo.displayShape = deviceInfo.displayShape;

            if (mPosition == Layout.Display.POSITION_REAR) {
            if (mDevicePosition == Layout.Display.POSITION_REAR) {
                // A rear display is meant to host a specific experience that is essentially
                // a presentation to another user or users other than the main user since they
                // can't actually see that display. Given that, it's a suitable display for
                // presentations but the content should be destroyed rather than moved to a non-rear
                // display when the rear display is removed.
                mBaseDisplayInfo.flags |= Display.FLAG_REAR;
                mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
                mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
            }

            mPrimaryDisplayDeviceInfo = deviceInfo;
            mInfo.set(null);
            mDirty = false;
        }
    }

@@ -857,7 +874,7 @@ final class LogicalDisplay {
        pw.println("mIsEnabled=" + mIsEnabled);
        pw.println("mIsInTransition=" + mIsInTransition);
        pw.println("mLayerStack=" + mLayerStack);
        pw.println("mPosition=" + mPosition);
        pw.println("mPosition=" + mDevicePosition);
        pw.println("mHasContent=" + mHasContent);
        pw.println("mDesiredDisplayModeSpecs={" + mDesiredDisplayModeSpecs + "}");
        pw.println("mRequestedColorMode=" + mRequestedColorMode);
+1 −1
Original line number Diff line number Diff line
@@ -992,7 +992,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
                newDisplay.swapDisplaysLocked(oldDisplay);
            }

            newDisplay.setPositionLocked(displayLayout.getPosition());
            newDisplay.setDevicePositionLocked(displayLayout.getPosition());
            newDisplay.setLeadDisplayLocked(displayLayout.getLeadDisplayId());
            setLayoutLimitedRefreshRate(newDisplay, device, displayLayout);
            setEnabledLocked(newDisplay, displayLayout.isEnabled());
+2 −2
Original line number Diff line number Diff line
@@ -836,9 +836,9 @@ public class LogicalDisplayMapperTest {
        assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());

        assertEquals(POSITION_UNKNOWN,
                mLogicalDisplayMapper.getDisplayLocked(device1).getPositionLocked());
                mLogicalDisplayMapper.getDisplayLocked(device1).getDevicePositionLocked());
        assertEquals(POSITION_REAR,
                mLogicalDisplayMapper.getDisplayLocked(device2).getPositionLocked());
                mLogicalDisplayMapper.getDisplayLocked(device2).getDevicePositionLocked());
    }

    /////////////////
+32 −3
Original line number Diff line number Diff line
@@ -26,12 +26,15 @@ import static org.mockito.Mockito.when;

import android.app.PropertyInvalidatedCache;
import android.graphics.Point;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;

import androidx.test.filters.SmallTest;

import com.android.server.display.layout.Layout;

import org.junit.Before;
import org.junit.Test;

@@ -47,6 +50,7 @@ public class LogicalDisplayTest {

    private LogicalDisplay mLogicalDisplay;
    private DisplayDevice mDisplayDevice;
    private DisplayDeviceRepository mDeviceRepo;
    private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo();

    @Before
@@ -66,7 +70,7 @@ public class LogicalDisplayTest {
        // Disable binder caches in this process.
        PropertyInvalidatedCache.disableForTestMode();

        DisplayDeviceRepository repo = new DisplayDeviceRepository(
        mDeviceRepo = new DisplayDeviceRepository(
                new DisplayManagerService.SyncRoot(),
                new PersistentDataStore(new PersistentDataStore.Injector() {
                    @Override
@@ -82,8 +86,8 @@ public class LogicalDisplayTest {
                    @Override
                    public void finishWrite(OutputStream os, boolean success) {}
                }));
        repo.onDisplayDeviceEvent(mDisplayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
        mLogicalDisplay.updateLocked(repo);
        mDeviceRepo.onDisplayDeviceEvent(mDisplayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
        mLogicalDisplay.updateLocked(mDeviceRepo);
    }

    @Test
@@ -137,4 +141,29 @@ public class LogicalDisplayTest {
        verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
        reset(t);
    }

    @Test
    public void testRearDisplaysArePresentationDisplaysThatDestroyContentOnRemoval() {
        // Assert that the display isn't a presentation display by default, with a default remove
        // mode
        assertEquals(0, mLogicalDisplay.getDisplayInfoLocked().flags);
        assertEquals(Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY,
                mLogicalDisplay.getDisplayInfoLocked().removeMode);

        // Update position and test to see that it's been updated to a rear, presentation display
        // that destroys content on removal
        mLogicalDisplay.setDevicePositionLocked(Layout.Display.POSITION_REAR);
        mLogicalDisplay.updateLocked(mDeviceRepo);
        assertEquals(Display.FLAG_REAR | Display.FLAG_PRESENTATION,
                mLogicalDisplay.getDisplayInfoLocked().flags);
        assertEquals(Display.REMOVE_MODE_DESTROY_CONTENT,
                mLogicalDisplay.getDisplayInfoLocked().removeMode);

        // And then check the unsetting the position resets both
        mLogicalDisplay.setDevicePositionLocked(Layout.Display.POSITION_UNKNOWN);
        mLogicalDisplay.updateLocked(mDeviceRepo);
        assertEquals(0, mLogicalDisplay.getDisplayInfoLocked().flags);
        assertEquals(Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY,
                mLogicalDisplay.getDisplayInfoLocked().removeMode);
    }
}