Loading services/core/java/com/android/server/power/PowerManagerService.java +35 −2 Original line number Diff line number Diff line Loading @@ -148,6 +148,7 @@ import com.android.server.power.batterysaver.BatterySaverPolicy; import com.android.server.power.batterysaver.BatterySaverStateMachine; import com.android.server.power.batterysaver.BatterySavingStats; import com.android.server.power.feature.PowerManagerFlags; import com.android.server.wm.WindowManagerInternal; import dalvik.annotation.optimization.NeverCompile; Loading Loading @@ -354,6 +355,8 @@ public final class PowerManagerService extends SystemService private SettingsObserver mSettingsObserver; private DreamManagerInternal mDreamManager; private LogicalLight mAttentionLight; @Nullable private WindowManagerInternal mWindowManagerInternal; private final InattentiveSleepWarningController mInattentiveSleepWarningOverlayController; private final AmbientDisplaySuppressionController mAmbientDisplaySuppressionController; Loading Loading @@ -763,6 +766,34 @@ public final class PowerManagerService extends SystemService @Override public void onDisplayRemoved(int displayId) { mNotifier.clearScreenTimeoutPolicyListeners(displayId); if (com.android.server.display.feature.flags.Flags.separateTimeouts() && !mFeatureFlags.isLockOnUnplugEnabled()) { return; } // if all the remaining devices are asleep, lock the default display. synchronized (mLock) { for (int i = 0; i < mPowerGroups.size(); i++) { PowerGroup pg = mPowerGroups.valueAt(i); // If a power group remains, that is an adjacent group // and it is awake, then do not lock the device. if (pg.isDefaultOrAdjacentGroup() && pg.getWakefulnessLocked() == WAKEFULNESS_AWAKE) { return; } } } tryToLockNow(); } private void tryToLockNow() { if (mWindowManagerInternal == null) { mWindowManagerInternal = getLocalService(WindowManagerInternal.class); } if (mWindowManagerInternal != null) { mWindowManagerInternal.lockNow(); } } @Override Loading @@ -771,7 +802,8 @@ public final class PowerManagerService extends SystemService } } private final class DisplayGroupPowerChangeListener implements @VisibleForTesting final class DisplayGroupPowerChangeListener implements DisplayManagerInternal.DisplayGroupListener { static final int DISPLAY_GROUP_ADDED = 0; Loading Loading @@ -1376,6 +1408,7 @@ public final class PowerManagerService extends SystemService mPolicy = getLocalService(WindowManagerPolicy.class); mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); mDisplayManager = mContext.getSystemService(DisplayManager.class); mWindowManagerInternal = getLocalService(WindowManagerInternal.class); mAttentionDetector.systemReady(mContext); SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); Loading services/core/java/com/android/server/power/feature/PowerManagerFlags.java +12 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ public class PowerManagerFlags { private final FlagState mMoveWscLoggingToNotifier = new FlagState(Flags.FLAG_MOVE_WSC_LOGGING_TO_NOTIFIER, Flags::moveWscLoggingToNotifier); private final FlagState mLockOnUnplug = new FlagState(Flags.FLAG_LOCK_ON_UNPLUG, Flags::lockOnUnplug); private final FlagState mWakelockAttributionViaWorkchain = new FlagState(Flags.FLAG_WAKELOCK_ATTRIBUTION_VIA_WORKCHAIN, Flags::wakelockAttributionViaWorkchain); Loading Loading @@ -126,6 +130,13 @@ public class PowerManagerFlags { return mWakelockAttributionViaWorkchain.isEnabled(); } /** * @return Whether to lock when all remaining adjacent displays are asleep. */ public boolean isLockOnUnplugEnabled() { return mLockOnUnplug.isEnabled(); } /** * @return Whether the feature to disable the frozen process wakelocks is enabled */ Loading Loading @@ -165,6 +176,7 @@ public class PowerManagerFlags { pw.println(" " + mImproveWakelockLatency); pw.println(" " + mPerDisplayWakeByTouch); pw.println(" " + mMoveWscLoggingToNotifier); pw.println(" " + mLockOnUnplug); pw.println(" " + mWakelockAttributionViaWorkchain); pw.println(" " + mDisableFrozenProcessWakelocks); pw.println(" " + mForceDisableWakelocks); Loading services/core/java/com/android/server/power/feature/power_flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,16 @@ flag { is_fixed_read_only: true } flag { name: "lock_on_unplug" namespace: "lse_desktop_experience" description: "Fixes device locking when all remaining external displays are unplugged" bug: "414558760" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "policy_reason_in_display_power_request" namespace: "wear_frameworks" Loading services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +155 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ import static android.service.dreams.Flags.FLAG_DREAMS_V2; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow; import static com.android.server.deviceidle.Flags.FLAG_DISABLE_WAKELOCKS_IN_LIGHT_IDLE; import static com.android.server.display.feature.flags.Flags.FLAG_SEPARATE_TIMEOUTS; import static com.android.server.power.PowerManagerService.DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; Loading Loading @@ -142,6 +144,7 @@ import com.android.server.power.batterysaver.BatterySaverStateMachine; import com.android.server.power.feature.PowerManagerFlags; import com.android.server.power.feature.flags.Flags; import com.android.server.testutils.OffsettableClock; import com.android.server.wm.WindowManagerInternal; import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; Loading Loading @@ -212,6 +215,7 @@ public class PowerManagerServiceTest { @Mock private PowerManagerService.PowerPropertiesWrapper mPowerPropertiesWrapper; @Mock private DeviceStateManager mDeviceStateManagerMock; @Mock private DeviceConfigParameterProvider mDeviceParameterProvider; @Mock private WindowManagerInternal mWindowManagerInternalMock; @Captor private ArgumentCaptor<DisplayManager.DisplayListener> mDisplayListenerArgumentCaptor; Loading Loading @@ -283,6 +287,7 @@ public class PowerManagerServiceTest { addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock); addLocalServiceMock(DreamManagerInternal.class, mDreamManagerInternalMock); addLocalServiceMock(VirtualDeviceManagerInternal.class, mVirtualDeviceManagerInternalMock); addLocalServiceMock(WindowManagerInternal.class, mWindowManagerInternalMock); mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mResourcesSpy = spy(mContextSpy.getResources()); Loading Loading @@ -1185,7 +1190,7 @@ public class PowerManagerServiceTest { } @Test @RequiresFlagsEnabled(com.android.server.display.feature.flags.Flags.FLAG_SEPARATE_TIMEOUTS) @RequiresFlagsEnabled({com.android.server.display.feature.flags.Flags.FLAG_SEPARATE_TIMEOUTS}) public void testDisplaySleepsIfOtherActiveGroupPresent() { doAnswer(inv -> { when(mDreamManagerInternalMock.isDreaming()).thenReturn(true); Loading Loading @@ -4540,6 +4545,155 @@ public class PowerManagerServiceTest { verify(mNativeWrapperMock, never()).nativeSetAutoSuspend(true); } @RequiresFlagsEnabled({FLAG_SEPARATE_TIMEOUTS, com.android.server.power.feature.flags.Flags.FLAG_LOCK_ON_UNPLUG}) @Test public void testLocksWhenAdjacentSleepingAndUnplug_shouldLock() { final int nonDefaultPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; when(mDisplayManagerInternalMock.getDisplayGroupFlags(nonDefaultPowerGroupId)) .thenReturn(DisplayGroup.FLAG_DEFAULT_GROUP_ADJACENT); PowerGroup pg2 = new PowerGroup(/* groupId= */ nonDefaultPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_ASLEEP, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ true); int displayInNonDefaultGroup = 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = new AtomicReference<>(); long eventTime1 = 10; doAnswer((Answer<Void>) invocation -> { listener.set(invocation.getArgument(0)); return null; }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); createService(); startSystem(); listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId); verify(mDisplayManagerMock).registerDisplayListener( mDisplayListenerArgumentCaptor.capture(), any()); // Verify the global wakefulness is AWAKE assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Transition default display to doze, and verify the global wakefulness mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_DOZING, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.onPowerGroupEventLocked(DISPLAY_GROUP_REMOVED, pg2); mDisplayListenerArgumentCaptor.getValue().onDisplayRemoved(displayInNonDefaultGroup); mDisplayListenerArgumentCaptor.getValue().onDisplayDisconnected(displayInNonDefaultGroup); advanceTime(500); verify(mNotifierMock).clearScreenTimeoutPolicyListeners(displayInNonDefaultGroup); verify(mWindowManagerInternalMock).lockNow(); } @RequiresFlagsEnabled({FLAG_SEPARATE_TIMEOUTS, com.android.server.power.feature.flags.Flags.FLAG_LOCK_ON_UNPLUG}) @Test public void testLocksWhenAwakeAndUnplug_shouldntLock() { final int nonDefaultPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; PowerGroup pg2 = new PowerGroup(/* groupId= */ nonDefaultPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ false); int displayInNonDefaultGroup = 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = new AtomicReference<>(); long eventTime1 = 10; doAnswer((Answer<Void>) invocation -> { listener.set(invocation.getArgument(0)); return null; }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); createService(); startSystem(); listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId); verify(mDisplayManagerMock).registerDisplayListener( mDisplayListenerArgumentCaptor.capture(), any()); // Verify the global wakefulness is AWAKE assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Transition default display to awake, and verify the global wakefulness mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.onPowerGroupEventLocked(DISPLAY_GROUP_REMOVED, pg2); mDisplayListenerArgumentCaptor.getValue().onDisplayRemoved(displayInNonDefaultGroup); mDisplayListenerArgumentCaptor.getValue().onDisplayDisconnected(displayInNonDefaultGroup); advanceTime(500); verify(mNotifierMock).clearScreenTimeoutPolicyListeners(displayInNonDefaultGroup); verify(mWindowManagerInternalMock, never()).lockNow(); } // Default adjacent groups that are awake, should prevent the device from locking. @RequiresFlagsEnabled({FLAG_SEPARATE_TIMEOUTS, com.android.server.power.feature.flags.Flags.FLAG_LOCK_ON_UNPLUG}) @Test public void testLocksWhenSleepingAndUnplug_butTheresAnAwakeAdjacentGroup_shouldntLock() { final int defaultGroupAdjacentPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; final int nonDefaultPowerGroupId = defaultGroupAdjacentPowerGroupId + 1; when(mDisplayManagerInternalMock.getDisplayGroupFlags(defaultGroupAdjacentPowerGroupId)) .thenReturn(DisplayGroup.FLAG_DEFAULT_GROUP_ADJACENT); PowerGroup pg2 = new PowerGroup(/* groupId= */ defaultGroupAdjacentPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ true); PowerGroup pg3 = new PowerGroup(/* groupId= */ nonDefaultPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ false); int displayInAdjacentDefaultGroup = 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = new AtomicReference<>(); long eventTime1 = 10; doAnswer((Answer<Void>) invocation -> { listener.set(invocation.getArgument(0)); return null; }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); createService(); startSystem(); listener.get().onDisplayGroupAdded(defaultGroupAdjacentPowerGroupId); listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId); verify(mDisplayManagerMock).registerDisplayListener( mDisplayListenerArgumentCaptor.capture(), any()); // Verify the global wakefulness is AWAKE assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Transition default display to doze // Transition adjacent display to awake, and verify the global wakefulness mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_DOZING, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); mService.setWakefulnessLocked(defaultGroupAdjacentPowerGroupId, WAKEFULNESS_AWAKE, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.onPowerGroupEventLocked(DISPLAY_GROUP_REMOVED, pg3); mDisplayListenerArgumentCaptor.getValue() .onDisplayRemoved(displayInAdjacentDefaultGroup); mDisplayListenerArgumentCaptor.getValue() .onDisplayDisconnected(displayInAdjacentDefaultGroup); advanceTime(500); verify(mNotifierMock).clearScreenTimeoutPolicyListeners(displayInAdjacentDefaultGroup); verify(mWindowManagerInternalMock, never()).lockNow(); } private void setCachedUidProcState(int uid) { mService.updateUidProcStateInternal(uid, PROCESS_STATE_TOP_SLEEPING); } Loading Loading
services/core/java/com/android/server/power/PowerManagerService.java +35 −2 Original line number Diff line number Diff line Loading @@ -148,6 +148,7 @@ import com.android.server.power.batterysaver.BatterySaverPolicy; import com.android.server.power.batterysaver.BatterySaverStateMachine; import com.android.server.power.batterysaver.BatterySavingStats; import com.android.server.power.feature.PowerManagerFlags; import com.android.server.wm.WindowManagerInternal; import dalvik.annotation.optimization.NeverCompile; Loading Loading @@ -354,6 +355,8 @@ public final class PowerManagerService extends SystemService private SettingsObserver mSettingsObserver; private DreamManagerInternal mDreamManager; private LogicalLight mAttentionLight; @Nullable private WindowManagerInternal mWindowManagerInternal; private final InattentiveSleepWarningController mInattentiveSleepWarningOverlayController; private final AmbientDisplaySuppressionController mAmbientDisplaySuppressionController; Loading Loading @@ -763,6 +766,34 @@ public final class PowerManagerService extends SystemService @Override public void onDisplayRemoved(int displayId) { mNotifier.clearScreenTimeoutPolicyListeners(displayId); if (com.android.server.display.feature.flags.Flags.separateTimeouts() && !mFeatureFlags.isLockOnUnplugEnabled()) { return; } // if all the remaining devices are asleep, lock the default display. synchronized (mLock) { for (int i = 0; i < mPowerGroups.size(); i++) { PowerGroup pg = mPowerGroups.valueAt(i); // If a power group remains, that is an adjacent group // and it is awake, then do not lock the device. if (pg.isDefaultOrAdjacentGroup() && pg.getWakefulnessLocked() == WAKEFULNESS_AWAKE) { return; } } } tryToLockNow(); } private void tryToLockNow() { if (mWindowManagerInternal == null) { mWindowManagerInternal = getLocalService(WindowManagerInternal.class); } if (mWindowManagerInternal != null) { mWindowManagerInternal.lockNow(); } } @Override Loading @@ -771,7 +802,8 @@ public final class PowerManagerService extends SystemService } } private final class DisplayGroupPowerChangeListener implements @VisibleForTesting final class DisplayGroupPowerChangeListener implements DisplayManagerInternal.DisplayGroupListener { static final int DISPLAY_GROUP_ADDED = 0; Loading Loading @@ -1376,6 +1408,7 @@ public final class PowerManagerService extends SystemService mPolicy = getLocalService(WindowManagerPolicy.class); mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); mDisplayManager = mContext.getSystemService(DisplayManager.class); mWindowManagerInternal = getLocalService(WindowManagerInternal.class); mAttentionDetector.systemReady(mContext); SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); Loading
services/core/java/com/android/server/power/feature/PowerManagerFlags.java +12 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ public class PowerManagerFlags { private final FlagState mMoveWscLoggingToNotifier = new FlagState(Flags.FLAG_MOVE_WSC_LOGGING_TO_NOTIFIER, Flags::moveWscLoggingToNotifier); private final FlagState mLockOnUnplug = new FlagState(Flags.FLAG_LOCK_ON_UNPLUG, Flags::lockOnUnplug); private final FlagState mWakelockAttributionViaWorkchain = new FlagState(Flags.FLAG_WAKELOCK_ATTRIBUTION_VIA_WORKCHAIN, Flags::wakelockAttributionViaWorkchain); Loading Loading @@ -126,6 +130,13 @@ public class PowerManagerFlags { return mWakelockAttributionViaWorkchain.isEnabled(); } /** * @return Whether to lock when all remaining adjacent displays are asleep. */ public boolean isLockOnUnplugEnabled() { return mLockOnUnplug.isEnabled(); } /** * @return Whether the feature to disable the frozen process wakelocks is enabled */ Loading Loading @@ -165,6 +176,7 @@ public class PowerManagerFlags { pw.println(" " + mImproveWakelockLatency); pw.println(" " + mPerDisplayWakeByTouch); pw.println(" " + mMoveWscLoggingToNotifier); pw.println(" " + mLockOnUnplug); pw.println(" " + mWakelockAttributionViaWorkchain); pw.println(" " + mDisableFrozenProcessWakelocks); pw.println(" " + mForceDisableWakelocks); Loading
services/core/java/com/android/server/power/feature/power_flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,16 @@ flag { is_fixed_read_only: true } flag { name: "lock_on_unplug" namespace: "lse_desktop_experience" description: "Fixes device locking when all remaining external displays are unplugged" bug: "414558760" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "policy_reason_in_display_power_request" namespace: "wear_frameworks" Loading
services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +155 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ import static android.service.dreams.Flags.FLAG_DREAMS_V2; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow; import static com.android.server.deviceidle.Flags.FLAG_DISABLE_WAKELOCKS_IN_LIGHT_IDLE; import static com.android.server.display.feature.flags.Flags.FLAG_SEPARATE_TIMEOUTS; import static com.android.server.power.PowerManagerService.DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; Loading Loading @@ -142,6 +144,7 @@ import com.android.server.power.batterysaver.BatterySaverStateMachine; import com.android.server.power.feature.PowerManagerFlags; import com.android.server.power.feature.flags.Flags; import com.android.server.testutils.OffsettableClock; import com.android.server.wm.WindowManagerInternal; import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; Loading Loading @@ -212,6 +215,7 @@ public class PowerManagerServiceTest { @Mock private PowerManagerService.PowerPropertiesWrapper mPowerPropertiesWrapper; @Mock private DeviceStateManager mDeviceStateManagerMock; @Mock private DeviceConfigParameterProvider mDeviceParameterProvider; @Mock private WindowManagerInternal mWindowManagerInternalMock; @Captor private ArgumentCaptor<DisplayManager.DisplayListener> mDisplayListenerArgumentCaptor; Loading Loading @@ -283,6 +287,7 @@ public class PowerManagerServiceTest { addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock); addLocalServiceMock(DreamManagerInternal.class, mDreamManagerInternalMock); addLocalServiceMock(VirtualDeviceManagerInternal.class, mVirtualDeviceManagerInternalMock); addLocalServiceMock(WindowManagerInternal.class, mWindowManagerInternalMock); mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mResourcesSpy = spy(mContextSpy.getResources()); Loading Loading @@ -1185,7 +1190,7 @@ public class PowerManagerServiceTest { } @Test @RequiresFlagsEnabled(com.android.server.display.feature.flags.Flags.FLAG_SEPARATE_TIMEOUTS) @RequiresFlagsEnabled({com.android.server.display.feature.flags.Flags.FLAG_SEPARATE_TIMEOUTS}) public void testDisplaySleepsIfOtherActiveGroupPresent() { doAnswer(inv -> { when(mDreamManagerInternalMock.isDreaming()).thenReturn(true); Loading Loading @@ -4540,6 +4545,155 @@ public class PowerManagerServiceTest { verify(mNativeWrapperMock, never()).nativeSetAutoSuspend(true); } @RequiresFlagsEnabled({FLAG_SEPARATE_TIMEOUTS, com.android.server.power.feature.flags.Flags.FLAG_LOCK_ON_UNPLUG}) @Test public void testLocksWhenAdjacentSleepingAndUnplug_shouldLock() { final int nonDefaultPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; when(mDisplayManagerInternalMock.getDisplayGroupFlags(nonDefaultPowerGroupId)) .thenReturn(DisplayGroup.FLAG_DEFAULT_GROUP_ADJACENT); PowerGroup pg2 = new PowerGroup(/* groupId= */ nonDefaultPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_ASLEEP, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ true); int displayInNonDefaultGroup = 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = new AtomicReference<>(); long eventTime1 = 10; doAnswer((Answer<Void>) invocation -> { listener.set(invocation.getArgument(0)); return null; }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); createService(); startSystem(); listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId); verify(mDisplayManagerMock).registerDisplayListener( mDisplayListenerArgumentCaptor.capture(), any()); // Verify the global wakefulness is AWAKE assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Transition default display to doze, and verify the global wakefulness mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_DOZING, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.onPowerGroupEventLocked(DISPLAY_GROUP_REMOVED, pg2); mDisplayListenerArgumentCaptor.getValue().onDisplayRemoved(displayInNonDefaultGroup); mDisplayListenerArgumentCaptor.getValue().onDisplayDisconnected(displayInNonDefaultGroup); advanceTime(500); verify(mNotifierMock).clearScreenTimeoutPolicyListeners(displayInNonDefaultGroup); verify(mWindowManagerInternalMock).lockNow(); } @RequiresFlagsEnabled({FLAG_SEPARATE_TIMEOUTS, com.android.server.power.feature.flags.Flags.FLAG_LOCK_ON_UNPLUG}) @Test public void testLocksWhenAwakeAndUnplug_shouldntLock() { final int nonDefaultPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; PowerGroup pg2 = new PowerGroup(/* groupId= */ nonDefaultPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ false); int displayInNonDefaultGroup = 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = new AtomicReference<>(); long eventTime1 = 10; doAnswer((Answer<Void>) invocation -> { listener.set(invocation.getArgument(0)); return null; }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); createService(); startSystem(); listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId); verify(mDisplayManagerMock).registerDisplayListener( mDisplayListenerArgumentCaptor.capture(), any()); // Verify the global wakefulness is AWAKE assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Transition default display to awake, and verify the global wakefulness mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.onPowerGroupEventLocked(DISPLAY_GROUP_REMOVED, pg2); mDisplayListenerArgumentCaptor.getValue().onDisplayRemoved(displayInNonDefaultGroup); mDisplayListenerArgumentCaptor.getValue().onDisplayDisconnected(displayInNonDefaultGroup); advanceTime(500); verify(mNotifierMock).clearScreenTimeoutPolicyListeners(displayInNonDefaultGroup); verify(mWindowManagerInternalMock, never()).lockNow(); } // Default adjacent groups that are awake, should prevent the device from locking. @RequiresFlagsEnabled({FLAG_SEPARATE_TIMEOUTS, com.android.server.power.feature.flags.Flags.FLAG_LOCK_ON_UNPLUG}) @Test public void testLocksWhenSleepingAndUnplug_butTheresAnAwakeAdjacentGroup_shouldntLock() { final int defaultGroupAdjacentPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; final int nonDefaultPowerGroupId = defaultGroupAdjacentPowerGroupId + 1; when(mDisplayManagerInternalMock.getDisplayGroupFlags(defaultGroupAdjacentPowerGroupId)) .thenReturn(DisplayGroup.FLAG_DEFAULT_GROUP_ADJACENT); PowerGroup pg2 = new PowerGroup(/* groupId= */ defaultGroupAdjacentPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ true); PowerGroup pg3 = new PowerGroup(/* groupId= */ nonDefaultPowerGroupId, /* wakefulnessListener= */ null, mNotifierMock, mDisplayManagerInternalMock, WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */ true, /* eventTime= */ mClock.now(), /* featureFlags= */ null, /* isDefaultGroupAdjacent= */ false); int displayInAdjacentDefaultGroup = 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = new AtomicReference<>(); long eventTime1 = 10; doAnswer((Answer<Void>) invocation -> { listener.set(invocation.getArgument(0)); return null; }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); createService(); startSystem(); listener.get().onDisplayGroupAdded(defaultGroupAdjacentPowerGroupId); listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId); verify(mDisplayManagerMock).registerDisplayListener( mDisplayListenerArgumentCaptor.capture(), any()); // Verify the global wakefulness is AWAKE assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Transition default display to doze // Transition adjacent display to awake, and verify the global wakefulness mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_DOZING, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); mService.setWakefulnessLocked(defaultGroupAdjacentPowerGroupId, WAKEFULNESS_AWAKE, eventTime1, 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.onPowerGroupEventLocked(DISPLAY_GROUP_REMOVED, pg3); mDisplayListenerArgumentCaptor.getValue() .onDisplayRemoved(displayInAdjacentDefaultGroup); mDisplayListenerArgumentCaptor.getValue() .onDisplayDisconnected(displayInAdjacentDefaultGroup); advanceTime(500); verify(mNotifierMock).clearScreenTimeoutPolicyListeners(displayInAdjacentDefaultGroup); verify(mWindowManagerInternalMock, never()).lockNow(); } private void setCachedUidProcState(int uid) { mService.updateUidProcStateInternal(uid, PROCESS_STATE_TOP_SLEEPING); } Loading