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

Commit 3da19deb authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Prevent displays that are disabled from receiving input

For foldable devices with two displays, both displays often map to the
same layer stack. In this case, the we expect only one of the two
displays to be used at once, and the other should be disabled. When the
device is folded/unfoled, the display that is enabled will change.

When two displays map to the same layer stack, it is currently difficult
to identify the display which the layer stack should be associated with.
Picking the incorrect display will result in issues with input
dispatching. For now, we get around the one-to-many mapping between
layer stacks and displays for input by preventing displays that are
disabled from receiving input, assuming only one display is enabled at a
time for a given layer stack.

Bug: 238122363
Test: None
Change-Id: I7cc5c4296bb8d891c89fc334f13988dd39d936f3
parent 8d386e52
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -523,10 +523,12 @@ final class LogicalDisplay {
        // Set the layer stack.
        device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack);
        // Also inform whether the device is the same one sent to inputflinger for its layerstack.
        // Prevent displays that are disabled from receiving input.
        // TODO(b/188914255): Remove once input can dispatch against device vs layerstack.
        device.setDisplayFlagsLocked(t,
                device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE
                        ? SurfaceControl.DISPLAY_RECEIVES_INPUT : 0);
                (isEnabled() && device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE)
                        ? SurfaceControl.DISPLAY_RECEIVES_INPUT
                        : 0);

        // Set the color mode and allowed display mode.
        if (device == mPrimaryDisplayDevice) {
+41 −5
Original line number Diff line number Diff line
@@ -17,7 +17,11 @@
package com.android.server.display;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.PropertyInvalidatedCache;
@@ -45,18 +49,21 @@ public class LogicalDisplayTest {

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

    @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);

        mDisplayDeviceInfo.copyFrom(new DisplayDeviceInfo());
        mDisplayDeviceInfo.width = DISPLAY_WIDTH;
        mDisplayDeviceInfo.height = DISPLAY_HEIGHT;
        mDisplayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
        when(mDisplayDevice.getDisplayDeviceInfoLocked()).thenReturn(mDisplayDeviceInfo);

        // Disable binder caches in this process.
        PropertyInvalidatedCache.disableForTestMode();
@@ -103,4 +110,33 @@ public class LogicalDisplayTest {
        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
        assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition());
    }

    @Test
    public void testDisplayInputFlags() {
        SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
        verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
        reset(t);

        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
        verify(t).setDisplayFlags(any(), eq(0));
        reset(t);

        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
        verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
        reset(t);

        mLogicalDisplay.setPhase(LogicalDisplay.DISPLAY_PHASE_DISABLED);
        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
        verify(t).setDisplayFlags(any(), eq(0));
        reset(t);

        mLogicalDisplay.setPhase(LogicalDisplay.DISPLAY_PHASE_ENABLED);
        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
        verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
        reset(t);
    }
}