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
This commit is contained in:
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|||||||
Reference in New Issue
Block a user