Merge "Checks if there is a device state override active to determine if the device should be put to sleep or not" into tm-dev

This commit is contained in:
Kenneth Ford
2022-03-03 22:11:55 +00:00
committed by Android (Google) Code Review
3 changed files with 117 additions and 8 deletions

View File

@@ -3939,12 +3939,22 @@ public final class DisplayManagerService extends SystemService {
* Listens to changes in device state and reports the state to LogicalDisplayMapper.
*/
class DeviceStateListener implements DeviceStateManager.DeviceStateCallback {
// Base state corresponds to the physical state of the device
private int mBaseState = DeviceStateManager.INVALID_DEVICE_STATE;
@Override
public void onStateChanged(int deviceState) {
boolean isDeviceStateOverrideActive = deviceState != mBaseState;
synchronized (mSyncRoot) {
mLogicalDisplayMapper.setDeviceStateLocked(deviceState);
mLogicalDisplayMapper
.setDeviceStateLocked(deviceState, isDeviceStateOverrideActive);
}
}
@Override
public void onBaseStateChanged(int state) {
mBaseState = state;
}
};
private class BrightnessPair {

View File

@@ -359,7 +359,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
mDeviceStateToLayoutMap.dumpLocked(ipw);
}
void setDeviceStateLocked(int state) {
void setDeviceStateLocked(int state, boolean isOverrideActive) {
Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
+ ", interactive=" + mInteractive);
// As part of a state transition, we may need to turn off some displays temporarily so that
@@ -370,12 +370,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
resetLayoutLocked(mDeviceState, state, LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION);
}
mPendingDeviceState = state;
final boolean wakeDevice = mDeviceStatesOnWhichToWakeUp.get(mPendingDeviceState)
&& !mDeviceStatesOnWhichToWakeUp.get(mDeviceState)
&& !mInteractive && mBootCompleted;
final boolean sleepDevice = mDeviceStatesOnWhichToSleep.get(mPendingDeviceState)
&& !mDeviceStatesOnWhichToSleep.get(mDeviceState)
&& mInteractive && mBootCompleted;
final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
mInteractive, mBootCompleted);
final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
isOverrideActive, mInteractive, mBootCompleted);
// If all displays are off already, we can just transition here, unless we are trying to
// wake or sleep the device as part of this transition. In that case defer the final
@@ -429,6 +427,53 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
}
/**
* Returns if the device should be woken up or not. Called to check if the device state we are
* moving to is one that should awake the device, as well as if we are moving from a device
* state that shouldn't have been already woken from.
*
* @param pendingState device state we are moving to
* @param currentState device state we are currently in
* @param isInteractive if the device is in an interactive state
* @param isBootCompleted is the device fully booted
*
* @see #shouldDeviceBePutToSleep
* @see #setDeviceStateLocked
*/
@VisibleForTesting
boolean shouldDeviceBeWoken(int pendingState, int currentState, boolean isInteractive,
boolean isBootCompleted) {
return mDeviceStatesOnWhichToWakeUp.get(pendingState)
&& !mDeviceStatesOnWhichToWakeUp.get(currentState)
&& !isInteractive && isBootCompleted;
}
/**
* Returns if the device should be put to sleep or not.
*
* Includes a check to verify that the device state that we are moving to, {@code pendingState},
* is the same as the physical state of the device, {@code baseState}. Different values for
* these parameters indicate a device state override is active, and we shouldn't put the device
* to sleep to provide a better user experience.
*
* @param pendingState device state we are moving to
* @param currentState device state we are currently in
* @param isOverrideActive if a device state override is currently active or not
* @param isInteractive if the device is in an interactive state
* @param isBootCompleted is the device fully booted
*
* @see #shouldDeviceBeWoken
* @see #setDeviceStateLocked
*/
@VisibleForTesting
boolean shouldDeviceBePutToSleep(int pendingState, int currentState, boolean isOverrideActive,
boolean isInteractive, boolean isBootCompleted) {
return mDeviceStatesOnWhichToSleep.get(pendingState)
&& !mDeviceStatesOnWhichToSleep.get(currentState)
&& !isOverrideActive
&& isInteractive && isBootCompleted;
}
private boolean areAllTransitioningDisplaysOffLocked() {
final int count = mLogicalDisplays.size();
for (int i = 0; i < count; i++) {

View File

@@ -28,7 +28,9 @@ import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EV
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.verify;
@@ -70,6 +72,8 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
public class LogicalDisplayMapperTest {
private static int sUniqueTestDisplayId = 0;
private static final int DEVICE_STATE_CLOSED = 0;
private static final int DEVICE_STATE_OPEN = 2;
private DisplayDeviceRepository mDisplayDeviceRepo;
private LogicalDisplayMapper mLogicalDisplayMapper;
@@ -113,6 +117,7 @@ public class LogicalDisplayMapperTest {
mPowerManager = new PowerManager(mContextMock, mIPowerManagerMock, mIThermalServiceMock,
null);
when(mContextMock.getSystemServiceName(PowerManager.class))
.thenReturn(Context.POWER_SERVICE);
when(mContextMock.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
@@ -120,6 +125,12 @@ public class LogicalDisplayMapperTest {
when(mResourcesMock.getBoolean(
com.android.internal.R.bool.config_supportsConcurrentInternalDisplays))
.thenReturn(true);
when(mResourcesMock.getIntArray(
com.android.internal.R.array.config_deviceStatesOnWhichToWakeUp))
.thenReturn(new int[]{1, 2});
when(mResourcesMock.getIntArray(
com.android.internal.R.array.config_deviceStatesOnWhichToSleep))
.thenReturn(new int[]{0});
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
@@ -312,6 +323,49 @@ public class LogicalDisplayMapperTest {
mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
}
@Test
public void testDeviceShouldBeWoken() {
assertTrue(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_OPEN,
DEVICE_STATE_CLOSED,
/* isInteractive= */false,
/* isBootCompleted= */true));
}
@Test
public void testDeviceShouldNotBeWoken() {
assertFalse(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_CLOSED,
DEVICE_STATE_OPEN,
/* isInteractive= */false,
/* isBootCompleted= */true));
}
@Test
public void testDeviceShouldBePutToSleep() {
assertTrue(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED,
DEVICE_STATE_OPEN,
/* isOverrideActive= */false,
/* isInteractive= */true,
/* isBootCompleted= */true));
}
@Test
public void testDeviceShouldNotBePutToSleep() {
assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_OPEN,
DEVICE_STATE_CLOSED,
/* isOverrideActive= */false,
/* isInteractive= */true,
/* isBootCompleted= */true));
}
@Test
public void testDeviceShouldNotBePutToSleepDifferentBaseState() {
assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED,
DEVICE_STATE_OPEN,
/* isOverrideActive= */true,
/* isInteractive= */true,
/* isBootCompleted= */true));
}
/////////////////
// Helper Methods
/////////////////