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

Commit fbdde763 authored by Piotr Wilczyński's avatar Piotr Wilczyński
Browse files

Start on cover display if folded

- put displays in the transition phase even if it's the initial state change
- initialize displays as disabled and enable if needed

Bug: 200885213
Test: atest LogicalDisplayMapperTest
Change-Id: Ifaa46027bad8ff0945db9da5c30f2f31b6c8d10c
parent 94bd703e
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -167,6 +167,12 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo,
            @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
            @NonNull Handler handler) {
        this(context, repo, listener, syncRoot, handler, new DeviceStateToLayoutMap());
    }

    LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo,
            @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
            @NonNull Handler handler, DeviceStateToLayoutMap deviceStateToLayoutMap) {
        mSyncRoot = syncRoot;
        mPowerManager = context.getSystemService(PowerManager.class);
        mInteractive = mPowerManager.isInteractive();
@@ -181,7 +187,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        mDeviceStatesOnWhichToSleep = toSparseBooleanArray(context.getResources().getIntArray(
                com.android.internal.R.array.config_deviceStatesOnWhichToSleep));
        mDisplayDeviceRepo.addListener(this);
        mDeviceStateToLayoutMap = new DeviceStateToLayoutMap();
        mDeviceStateToLayoutMap = deviceStateToLayoutMap;
    }

    @Override
@@ -369,9 +375,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        // the transition is smooth. Plus, on some devices, only one internal displays can be
        // on at a time. We use DISPLAY_PHASE_LAYOUT_TRANSITION to mark a display that needs to be
        // temporarily turned off.
        if (mDeviceState != DeviceStateManager.INVALID_DEVICE_STATE) {
        resetLayoutLocked(mDeviceState, state, LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION);
        }
        mPendingDeviceState = state;
        final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
                mInteractive, mBootCompleted);
@@ -891,8 +895,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
                newDisplay.swapDisplaysLocked(oldDisplay);
            }

            if (!displayLayout.isEnabled()) {
                setDisplayPhase(newDisplay, LogicalDisplay.DISPLAY_PHASE_DISABLED);
            if (displayLayout.isEnabled()) {
                setDisplayPhase(newDisplay, LogicalDisplay.DISPLAY_PHASE_ENABLED);
            }
        }

@@ -912,7 +916,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
        display.updateLocked(mDisplayDeviceRepo);
        mLogicalDisplays.put(displayId, display);
        setDisplayPhase(display, LogicalDisplay.DISPLAY_PHASE_ENABLED);
        setDisplayPhase(display, LogicalDisplay.DISPLAY_PHASE_DISABLED);
        return display;
    }

+60 −1
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED;
import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED;
import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED;
import static com.android.server.display.LogicalDisplay.DISPLAY_PHASE_DISABLED;
import static com.android.server.display.LogicalDisplay.DISPLAY_PHASE_ENABLED;
import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED;
import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED;

@@ -53,6 +55,8 @@ import android.view.DisplayInfo;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

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

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -85,6 +89,7 @@ public class LogicalDisplayMapperTest {
    @Mock Resources mResourcesMock;
    @Mock IPowerManager mIPowerManagerMock;
    @Mock IThermalService mIThermalServiceMock;
    @Mock DeviceStateToLayoutMap mDeviceStateToLayoutMapMock;

    @Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor;

@@ -130,11 +135,13 @@ public class LogicalDisplayMapperTest {
        when(mResourcesMock.getIntArray(
                com.android.internal.R.array.config_deviceStatesOnWhichToSleep))
                .thenReturn(new int[]{0});
        when(mDeviceStateToLayoutMapMock.get(-1)).thenReturn(new Layout());

        mLooper = new TestLooper();
        mHandler = new Handler(mLooper.getLooper());
        mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mDisplayDeviceRepo,
                mListenerMock, new DisplayManagerService.SyncRoot(), mHandler);
                mListenerMock, new DisplayManagerService.SyncRoot(), mHandler,
                mDeviceStateToLayoutMapMock);
    }


@@ -413,6 +420,58 @@ public class LogicalDisplayMapperTest {
                /* isBootCompleted= */true));
    }

    @Test
    public void testDeviceStateLocked() {
        DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
                DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
        DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
                DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);

        Layout layout = new Layout();
        layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, true, true);
        layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, false, false);
        when(mDeviceStateToLayoutMapMock.get(0)).thenReturn(layout);

        layout = new Layout();
        layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, false, false);
        layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, true, true);
        when(mDeviceStateToLayoutMapMock.get(1)).thenReturn(layout);
        when(mDeviceStateToLayoutMapMock.get(2)).thenReturn(layout);

        LogicalDisplay display1 = add(device1);
        assertEquals(info(display1).address, info(device1).address);
        assertEquals(DEFAULT_DISPLAY, id(display1));

        LogicalDisplay display2 = add(device2);
        assertEquals(info(display2).address, info(device2).address);
        // We can only have one default display
        assertEquals(DEFAULT_DISPLAY, id(display1));

        mLogicalDisplayMapper.setDeviceStateLocked(0, false);
        mLooper.moveTimeForward(1000);
        mLooper.dispatchAll();
        assertEquals(DISPLAY_PHASE_ENABLED,
                mLogicalDisplayMapper.getDisplayLocked(device1).getPhase());
        assertEquals(DISPLAY_PHASE_DISABLED,
                mLogicalDisplayMapper.getDisplayLocked(device2).getPhase());

        mLogicalDisplayMapper.setDeviceStateLocked(1, false);
        mLooper.moveTimeForward(1000);
        mLooper.dispatchAll();
        assertEquals(DISPLAY_PHASE_DISABLED,
                mLogicalDisplayMapper.getDisplayLocked(device1).getPhase());
        assertEquals(DISPLAY_PHASE_ENABLED,
                mLogicalDisplayMapper.getDisplayLocked(device2).getPhase());

        mLogicalDisplayMapper.setDeviceStateLocked(2, false);
        mLooper.moveTimeForward(1000);
        mLooper.dispatchAll();
        assertEquals(DISPLAY_PHASE_DISABLED,
                mLogicalDisplayMapper.getDisplayLocked(device1).getPhase());
        assertEquals(DISPLAY_PHASE_ENABLED,
                mLogicalDisplayMapper.getDisplayLocked(device2).getPhase());
    }

    /////////////////
    // Helper Methods
    /////////////////