diff options
3 files changed, 58 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java index fc6403d2dfb7..188672ade408 100644 --- a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java +++ b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java @@ -94,6 +94,10 @@ class DeviceStateToLayoutMap { return layout; } + int size() { + return mLayoutMap.size(); + } + /** * Reads display-layout-configuration files to get the layouts to use for this device. */ diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index da6e3151197a..a66cbb85e37a 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -405,12 +405,23 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { void setDeviceStateLocked(int state, boolean isOverrideActive) { Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState + ", 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 // 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 // temporarily turned off. resetLayoutLocked(mDeviceState, state, /* transitionValue= */ true); - mPendingDeviceState = state; final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState, mInteractive, mBootCompleted); final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState, @@ -457,6 +468,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { void onBootCompleted() { synchronized (mSyncRoot) { 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 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device); 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); return display; } diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java index c6a0b0f936a5..a9b7143b1810 100644 --- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -18,6 +18,7 @@ package com.android.server.display; import static android.view.Display.DEFAULT_DISPLAY; 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_VIRTUAL; @@ -177,7 +178,7 @@ public class LogicalDisplayMapperTest { @Test public void testDisplayDeviceAddAndRemove_NonInternalTypes() { - testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_EXTERNAL); + testDisplayDeviceAddAndRemove_NonInternal(TYPE_EXTERNAL); testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_WIFI); testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_OVERLAY); testDisplayDeviceAddAndRemove_NonInternal(TYPE_VIRTUAL); @@ -222,7 +223,7 @@ public class LogicalDisplayMapperTest { @Test 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); // add @@ -272,7 +273,7 @@ public class LogicalDisplayMapperTest { public void testGetDisplayIdsLocked() { add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 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)); int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID, @@ -558,7 +559,7 @@ public class LogicalDisplayMapperTest { layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, true, true, mIdProducer); layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, - false, false, mIdProducer); + false, true, mIdProducer); when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout); layout = new Layout(); @@ -569,6 +570,8 @@ public class LogicalDisplayMapperTest { when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(layout); when(mDeviceStateToLayoutMapSpy.get(2)).thenReturn(layout); + when(mDeviceStateToLayoutMapSpy.size()).thenReturn(4); + LogicalDisplay display1 = add(device1); assertEquals(info(display1).address, info(device1).address); assertEquals(DEFAULT_DISPLAY, id(display1)); @@ -580,8 +583,14 @@ public class LogicalDisplayMapperTest { mLogicalDisplayMapper.setDeviceStateLocked(0, false); advanceTime(1000); + // The new state is not applied until the boot is completed assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).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(device2).isInTransitionLocked()); @@ -722,6 +731,23 @@ public class LogicalDisplayMapperTest { 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 ///////////////// |