Loading services/core/java/com/android/server/display/LogicalDisplayMapper.java +27 −4 Original line number Diff line number Diff line Loading @@ -537,10 +537,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return; } if (Flags.changeDefaultDisplayLidClosed() && state.hasProperty( PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED)) { if (Flags.changeDefaultDisplayLidClosed()) { if (mDeviceState.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED) && !state.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED)) { prepareForTransitionOutOfDockedStateLocked(); } else if (!mDeviceState.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED) && state.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED)) { createLayoutWithDefaultSecondaryDisplayLocked(state.getIdentifier()); } } // 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 Loading Loading @@ -1441,6 +1446,24 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { updateLogicalDisplaysLocked(); } /** * If transitioning out of the docked state, enable all the displays that were disabled by this * state. Also, remove its layout so that a fresh one is created the next time, because the * default secondary display might be disconnected in the meantime. */ private void prepareForTransitionOutOfDockedStateLocked() { for (int i = 0; i < mCurrentLayout.size(); i++) { Layout.Display layoutDisplay = mCurrentLayout.getAt(i); DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked( layoutDisplay.getAddress()); if (device == null) { continue; } getDisplayLocked(device).setEnabledLocked(true); } mDeviceStateToLayoutMap.remove(mDeviceState.getIdentifier()); } private void createLayoutWithDefaultSecondaryDisplayLocked(int identifier) { for (int i = 0; i < mLogicalDisplays.size(); i++) { LogicalDisplay display = mLogicalDisplays.valueAt(i); Loading Loading @@ -1480,7 +1503,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { /** * Find a new default secondary display if the current one is being removed. If none can be * found, remove the closed-lid state layout so that the default layout is applied instead. * found, remove the docked state layout so that the default layout is applied instead. * @param removedDisplayDevice The display device being removed * @return True if the current layout has been modified and needs to be re-applied. */ Loading services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java +54 −0 Original line number Diff line number Diff line Loading @@ -1301,6 +1301,60 @@ public class LogicalDisplayMapperTest { verify(mWindowManagerPolicy, never()).onDisplaySwitchStart(DEFAULT_DISPLAY); } @Test @EnableFlags(Flags.FLAG_CHANGE_DEFAULT_DISPLAY_LID_CLOSED) public void testDisplayDeviceAddAndRemove_GoBackToDockedState() { initLogicalDisplayMapper(); when(mIsDisplayAllowedInTopologyMock.test(any(DisplayInfo.class))).thenReturn(true); DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); DisplayDevice device2 = createDisplayDevice(TYPE_EXTERNAL, 600, 800, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); Layout layout = new Layout(); createDefaultDisplay(layout, device1); when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_OPEN.getIdentifier())).thenReturn(layout); LogicalDisplay display1 = add(device1); display1.setCanHostTasksLocked(true); assertEquals(info(display1).address, info(device1).address); assertEquals(DEFAULT_DISPLAY, id(display1)); LogicalDisplay display2 = add(device2); display2.setCanHostTasksLocked(true); assertEquals(info(display2).address, info(device2).address); // We can only have one default display assertEquals(DEFAULT_DISPLAY, id(display1)); mLogicalDisplayMapper.onBootCompleted(); mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_DOCKED); advanceTime(1000); assertEquals(device2, display1.getPrimaryDisplayDeviceLocked()); assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); // Device 1 becomes the default display again mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_OPEN); advanceTime(1000); assertEquals(device1, display1.getPrimaryDisplayDeviceLocked()); // Both displays should be enabled assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); // remove mDisplayDeviceRepo.onDisplayDeviceEvent(device2, DISPLAY_DEVICE_EVENT_REMOVED); advanceTime(1000); assertNull(mLogicalDisplayMapper.getDisplayLocked(device2)); // Go back to the docked state mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_DOCKED); advanceTime(1000); // Display 1 is still the default logical display assertEquals(DEFAULT_DISPLAY, id(display1)); assertEquals(device1, display1.getPrimaryDisplayDeviceLocked()); assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); } @Test public void testEnabledAndDisabledDisplays() { initLogicalDisplayMapper(); Loading Loading
services/core/java/com/android/server/display/LogicalDisplayMapper.java +27 −4 Original line number Diff line number Diff line Loading @@ -537,10 +537,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return; } if (Flags.changeDefaultDisplayLidClosed() && state.hasProperty( PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED)) { if (Flags.changeDefaultDisplayLidClosed()) { if (mDeviceState.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED) && !state.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED)) { prepareForTransitionOutOfDockedStateLocked(); } else if (!mDeviceState.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED) && state.hasProperty(PROPERTY_LAPTOP_HARDWARE_CONFIGURATION_DOCKED)) { createLayoutWithDefaultSecondaryDisplayLocked(state.getIdentifier()); } } // 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 Loading Loading @@ -1441,6 +1446,24 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { updateLogicalDisplaysLocked(); } /** * If transitioning out of the docked state, enable all the displays that were disabled by this * state. Also, remove its layout so that a fresh one is created the next time, because the * default secondary display might be disconnected in the meantime. */ private void prepareForTransitionOutOfDockedStateLocked() { for (int i = 0; i < mCurrentLayout.size(); i++) { Layout.Display layoutDisplay = mCurrentLayout.getAt(i); DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked( layoutDisplay.getAddress()); if (device == null) { continue; } getDisplayLocked(device).setEnabledLocked(true); } mDeviceStateToLayoutMap.remove(mDeviceState.getIdentifier()); } private void createLayoutWithDefaultSecondaryDisplayLocked(int identifier) { for (int i = 0; i < mLogicalDisplays.size(); i++) { LogicalDisplay display = mLogicalDisplays.valueAt(i); Loading Loading @@ -1480,7 +1503,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { /** * Find a new default secondary display if the current one is being removed. If none can be * found, remove the closed-lid state layout so that the default layout is applied instead. * found, remove the docked state layout so that the default layout is applied instead. * @param removedDisplayDevice The display device being removed * @return True if the current layout has been modified and needs to be re-applied. */ Loading
services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java +54 −0 Original line number Diff line number Diff line Loading @@ -1301,6 +1301,60 @@ public class LogicalDisplayMapperTest { verify(mWindowManagerPolicy, never()).onDisplaySwitchStart(DEFAULT_DISPLAY); } @Test @EnableFlags(Flags.FLAG_CHANGE_DEFAULT_DISPLAY_LID_CLOSED) public void testDisplayDeviceAddAndRemove_GoBackToDockedState() { initLogicalDisplayMapper(); when(mIsDisplayAllowedInTopologyMock.test(any(DisplayInfo.class))).thenReturn(true); DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); DisplayDevice device2 = createDisplayDevice(TYPE_EXTERNAL, 600, 800, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); Layout layout = new Layout(); createDefaultDisplay(layout, device1); when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_OPEN.getIdentifier())).thenReturn(layout); LogicalDisplay display1 = add(device1); display1.setCanHostTasksLocked(true); assertEquals(info(display1).address, info(device1).address); assertEquals(DEFAULT_DISPLAY, id(display1)); LogicalDisplay display2 = add(device2); display2.setCanHostTasksLocked(true); assertEquals(info(display2).address, info(device2).address); // We can only have one default display assertEquals(DEFAULT_DISPLAY, id(display1)); mLogicalDisplayMapper.onBootCompleted(); mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_DOCKED); advanceTime(1000); assertEquals(device2, display1.getPrimaryDisplayDeviceLocked()); assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); // Device 1 becomes the default display again mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_OPEN); advanceTime(1000); assertEquals(device1, display1.getPrimaryDisplayDeviceLocked()); // Both displays should be enabled assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked()); // remove mDisplayDeviceRepo.onDisplayDeviceEvent(device2, DISPLAY_DEVICE_EVENT_REMOVED); advanceTime(1000); assertNull(mLogicalDisplayMapper.getDisplayLocked(device2)); // Go back to the docked state mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_DOCKED); advanceTime(1000); // Display 1 is still the default logical display assertEquals(DEFAULT_DISPLAY, id(display1)); assertEquals(device1, display1.getPrimaryDisplayDeviceLocked()); assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked()); } @Test public void testEnabledAndDisabledDisplays() { initLogicalDisplayMapper(); Loading