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

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

Fix boot animation when device is folded

- Initialize internal logical displays as disabled
- Postpone device state transition until boot is completed

Bug: 193821864
Test: atest LogicalDisplayMapperTest
Change-Id: I5a7c7c3fe6d07d22733d98c2ff2dbe6a9392f05c
parent 85a3f505
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -94,6 +94,10 @@ class DeviceStateToLayoutMap {
        return layout;
        return layout;
    }
    }


    int size() {
        return mLayoutMap.size();
    }

    /**
    /**
     * Reads display-layout-configuration files to get the layouts to use for this device.
     * Reads display-layout-configuration files to get the layouts to use for this device.
     */
     */
+24 −1
Original line number Original line Diff line number Diff line
@@ -405,12 +405,23 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    void setDeviceStateLocked(int state, boolean isOverrideActive) {
    void setDeviceStateLocked(int state, boolean isOverrideActive) {
        Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
        Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
                + ", interactive=" + mInteractive + ", mBootCompleted=" + mBootCompleted);
                + ", interactive=" + mInteractive + ", mBootCompleted=" + mBootCompleted);
        mPendingDeviceState = state;

        if (!mBootCompleted) {
            // The boot animation might still be in progress, we do not want to switch states now
            // as the boot animation would end up with an incorrect size.
            if (DEBUG) {
                Slog.d(TAG, "Postponing transition to state: " + mPendingDeviceState
                        + " until boot is completed");
            }
            return;
        }

        // As part of a state transition, we may need to turn off some displays temporarily so that
        // As part of a state transition, we may need to turn off some displays temporarily so that
        // the transition is smooth. Plus, on some devices, only one internal displays can be
        // the transition is smooth. Plus, on some devices, only one internal displays can be
        // on at a time. We use LogicalDisplay.setIsInTransition to mark a display that needs to be
        // on at a time. We use LogicalDisplay.setIsInTransition to mark a display that needs to be
        // temporarily turned off.
        // temporarily turned off.
        resetLayoutLocked(mDeviceState, state, /* transitionValue= */ true);
        resetLayoutLocked(mDeviceState, state, /* transitionValue= */ true);
        mPendingDeviceState = state;
        final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
        final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
                mInteractive, mBootCompleted);
                mInteractive, mBootCompleted);
        final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
        final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
@@ -457,6 +468,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    void onBootCompleted() {
    void onBootCompleted() {
        synchronized (mSyncRoot) {
        synchronized (mSyncRoot) {
            mBootCompleted = true;
            mBootCompleted = true;
            if (mPendingDeviceState != DeviceStateManager.INVALID_DEVICE_STATE) {
                setDeviceStateLocked(mPendingDeviceState, false);
            }
        }
        }
    }
    }


@@ -982,6 +996,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        final int layerStack = assignLayerStackLocked(displayId);
        final int layerStack = assignLayerStackLocked(displayId);
        final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
        final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
        display.updateLocked(mDisplayDeviceRepo);
        display.updateLocked(mDisplayDeviceRepo);

        final DisplayInfo info = display.getDisplayInfoLocked();
        if (info.type == Display.TYPE_INTERNAL && mDeviceStateToLayoutMap.size() > 1) {
            // If this is an internal display and the device uses a display layout configuration,
            // the display should be disabled as later we will receive a device state update, which
            // will tell us which internal displays should be enabled and which should be disabled.
            display.setEnabledLocked(false);
        }

        mLogicalDisplays.put(displayId, display);
        mLogicalDisplays.put(displayId, display);
        return display;
        return display;
    }
    }
+30 −4
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.display;


import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static android.view.Display.TYPE_EXTERNAL;
import static android.view.Display.TYPE_INTERNAL;
import static android.view.Display.TYPE_INTERNAL;
import static android.view.Display.TYPE_VIRTUAL;
import static android.view.Display.TYPE_VIRTUAL;


@@ -177,7 +178,7 @@ public class LogicalDisplayMapperTest {


    @Test
    @Test
    public void testDisplayDeviceAddAndRemove_NonInternalTypes() {
    public void testDisplayDeviceAddAndRemove_NonInternalTypes() {
        testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_EXTERNAL);
        testDisplayDeviceAddAndRemove_NonInternal(TYPE_EXTERNAL);
        testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_WIFI);
        testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_WIFI);
        testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_OVERLAY);
        testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_OVERLAY);
        testDisplayDeviceAddAndRemove_NonInternal(TYPE_VIRTUAL);
        testDisplayDeviceAddAndRemove_NonInternal(TYPE_VIRTUAL);
@@ -222,7 +223,7 @@ public class LogicalDisplayMapperTest {


    @Test
    @Test
    public void testDisplayDeviceAddAndRemove_OneExternalDefault() {
    public void testDisplayDeviceAddAndRemove_OneExternalDefault() {
        DisplayDevice device = createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800,
        DisplayDevice device = createDisplayDevice(TYPE_EXTERNAL, 600, 800,
                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);


        // add
        // add
@@ -272,7 +273,7 @@ public class LogicalDisplayMapperTest {
    public void testGetDisplayIdsLocked() {
    public void testGetDisplayIdsLocked() {
        add(createDisplayDevice(TYPE_INTERNAL, 600, 800,
        add(createDisplayDevice(TYPE_INTERNAL, 600, 800,
                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
        add(createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800, 0));
        add(createDisplayDevice(TYPE_EXTERNAL, 600, 800, 0));
        add(createDisplayDevice(TYPE_VIRTUAL, 600, 800, 0));
        add(createDisplayDevice(TYPE_VIRTUAL, 600, 800, 0));


        int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID,
        int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID,
@@ -558,7 +559,7 @@ public class LogicalDisplayMapperTest {
        layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address,
        layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address,
                true, true, mIdProducer);
                true, true, mIdProducer);
        layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address,
        layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address,
                false, false, mIdProducer);
                false, true, mIdProducer);
        when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);
        when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);


        layout = new Layout();
        layout = new Layout();
@@ -569,6 +570,8 @@ public class LogicalDisplayMapperTest {
        when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(layout);
        when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(layout);
        when(mDeviceStateToLayoutMapSpy.get(2)).thenReturn(layout);
        when(mDeviceStateToLayoutMapSpy.get(2)).thenReturn(layout);


        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(4);

        LogicalDisplay display1 = add(device1);
        LogicalDisplay display1 = add(device1);
        assertEquals(info(display1).address, info(device1).address);
        assertEquals(info(display1).address, info(device1).address);
        assertEquals(DEFAULT_DISPLAY, id(display1));
        assertEquals(DEFAULT_DISPLAY, id(display1));
@@ -580,8 +583,14 @@ public class LogicalDisplayMapperTest {


        mLogicalDisplayMapper.setDeviceStateLocked(0, false);
        mLogicalDisplayMapper.setDeviceStateLocked(0, false);
        advanceTime(1000);
        advanceTime(1000);
        // The new state is not applied until the boot is completed
        assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
        assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
        assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
        assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());

        mLogicalDisplayMapper.onBootCompleted();
        advanceTime(1000);
        assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
        assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
        assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isInTransitionLocked());
        assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isInTransitionLocked());
        assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked());
        assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked());


@@ -722,6 +731,23 @@ public class LogicalDisplayMapperTest {
        assertEquals(3, threeDisplaysEnabled.length);
        assertEquals(3, threeDisplaysEnabled.length);
    }
    }


    @Test
    public void testCreateNewLogicalDisplay() {
        DisplayDevice device1 = createDisplayDevice(TYPE_EXTERNAL, 600, 800,
                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(1);
        LogicalDisplay display1 = add(device1);

        assertTrue(display1.isEnabledLocked());

        DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(2);
        LogicalDisplay display2 = add(device2);

        assertFalse(display2.isEnabledLocked());
    }

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