Loading services/core/java/com/android/server/UiModeManagerService.java +34 −26 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.UiModeManager.ContrastUtils.CONTRAST_DEFAULT_VALUE; import static android.app.UiModeManager.DEFAULT_PRIORITY; import static android.app.UiModeManager.FORCE_INVERT_TYPE_DARK; import static android.app.UiModeManager.FORCE_INVERT_TYPE_OFF; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF; import static android.app.UiModeManager.MODE_NIGHT_AUTO; import static android.app.UiModeManager.MODE_NIGHT_CUSTOM; Loading Loading @@ -98,9 +99,10 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import androidx.annotation.VisibleForTesting; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.DisableCarModeActivity; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; Loading Loading @@ -482,6 +484,11 @@ final class UiModeManagerService extends SystemService { mCurrentUser = currentUserId; } @VisibleForTesting Boolean[] getNightModeOverrides() { return new Boolean[]{mOverrideNightModeOn, mOverrideNightModeOff}; } @Override public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { mCurrentUser = to.getUserIdentifier(); Loading Loading @@ -1590,6 +1597,9 @@ final class UiModeManagerService extends SystemService { private void onCustomTimeUpdated(int user) { persistNightMode(user); if (mNightMode.get() != MODE_NIGHT_CUSTOM) return; synchronized (mLock) { resetNightModeOverrideLocked(); if (shouldApplyAutomaticChangesImmediately()) { unregisterDeviceInactiveListenerLocked(); updateLocked(0, 0); Loading @@ -1597,6 +1607,7 @@ final class UiModeManagerService extends SystemService { registerDeviceInactiveListenerLocked(); } } } void dumpImpl(PrintWriter pw) { synchronized (mLock) { Loading Loading @@ -1865,6 +1876,8 @@ final class UiModeManagerService extends SystemService { unregisterTimeChangeEvent(); } updateForceInvertStates(); // Override night mode in power save mode if not in car mode if (mPowerSave && !mCarModeEnabled && !mCar) { uiMode &= ~Configuration.UI_MODE_NIGHT_NO; Loading Loading @@ -2192,26 +2205,21 @@ final class UiModeManagerService extends SystemService { } private void updateComputedNightModeLocked(boolean activate) { boolean newComputedValue = activate; boolean appliedOverrides = false; if (mNightMode.get() != MODE_NIGHT_YES && mNightMode.get() != UiModeManager.MODE_NIGHT_NO) { if (mOverrideNightModeOn && !newComputedValue) { newComputedValue = true; } else if (mOverrideNightModeOff && newComputedValue) { newComputedValue = false; } appliedOverrides = true; } // Computes final night mode values based on Attention Mode. mComputedNightMode = switch (mAttentionModeThemeOverlay) { case (UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT) -> true; case (UiModeManager.MODE_ATTENTION_THEME_OVERLAY_DAY) -> false; default -> newComputedValue; // case OFF }; updateForceInvertStates(); mComputedNightMode = activate; if (appliedOverrides) { if (mAttentionModeThemeOverlay != MODE_ATTENTION_THEME_OVERLAY_OFF) { mComputedNightMode = mAttentionModeThemeOverlay == MODE_ATTENTION_THEME_OVERLAY_NIGHT; return; } if (mNightMode.get() == MODE_NIGHT_YES || mNightMode.get() == UiModeManager.MODE_NIGHT_NO) { return; } if (mOverrideNightModeOn && !mComputedNightMode) { mComputedNightMode = true; return; } if (mOverrideNightModeOff && mComputedNightMode) { mComputedNightMode = false; return; } Loading Loading @@ -2455,7 +2463,7 @@ final class UiModeManagerService extends SystemService { } } @VisibleForTesting @VisibleForTesting(otherwise = VisibleForTesting.NONE) public static class Injector { public int getCallingUid() { return Binder.getCallingUid(); Loading services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +56 −0 Original line number Diff line number Diff line Loading @@ -913,6 +913,62 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { .setExact(anyInt(), anyLong(), anyString(), any(), any()); } @Test public void customTime_clearsOverrides_whenOverrideOnIsSet() throws RemoteException { when(mPowerManager.isInteractive()).thenReturn(false); mService.setNightMode(MODE_NIGHT_CUSTOM); LocalTime scheduleStart = LocalTime.now().plusHours(2); LocalTime scheduleEnd = LocalTime.now().plusHours(3); mService.setCustomNightModeStart(scheduleStart.toNanoOfDay() / 1000); mService.setCustomNightModeEnd(scheduleEnd.toNanoOfDay() / 1000); assertThat(isNightModeActivated()).isFalse(); mService.setNightModeActivated(true); //Verify override is set and night mode is ON due to override Boolean[] overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isTrue(); // mOverrideNightModeOn assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff assertThat(isNightModeActivated()).isTrue(); // Night mode is ON due to override LocalTime newStartTime = LocalTime.now().plusHours(1); mService.setCustomNightModeStart(newStartTime.toNanoOfDay() / 1000); // Verify overrides are cleared overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn should be cleared assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff should be cleared } @Test public void customTime_clearsOverrides_whenOverrideOffIsSet() throws RemoteException { when(mPowerManager.isInteractive()).thenReturn(false); mService.setNightMode(MODE_NIGHT_CUSTOM); LocalTime scheduleStart = LocalTime.now().minusHours(2); LocalTime scheduleEnd = LocalTime.now().plusHours(3); mService.setCustomNightModeStart(scheduleStart.toNanoOfDay() / 1000); mService.setCustomNightModeEnd(scheduleEnd.toNanoOfDay() / 1000); assertThat(isNightModeActivated()).isTrue(); mService.setNightModeActivated(false); //Verify override is set and night mode is OFF due to override Boolean[] overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn assertThat(overrides[1]).isTrue(); // mOverrideNightModeOff assertThat(isNightModeActivated()).isFalse(); // Night mode is ON due to override LocalTime newEndTime = LocalTime.now().plusHours(1); mService.setCustomNightModeStart(newEndTime.toNanoOfDay() / 1000); // Verify overrides are cleared overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn should be cleared assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff should be cleared } @Test public void customTime_alarmSetInTheFutureWhenOn() throws RemoteException { LocalDateTime now = LocalDateTime.now(); Loading Loading
services/core/java/com/android/server/UiModeManagerService.java +34 −26 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.UiModeManager.ContrastUtils.CONTRAST_DEFAULT_VALUE; import static android.app.UiModeManager.DEFAULT_PRIORITY; import static android.app.UiModeManager.FORCE_INVERT_TYPE_DARK; import static android.app.UiModeManager.FORCE_INVERT_TYPE_OFF; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF; import static android.app.UiModeManager.MODE_NIGHT_AUTO; import static android.app.UiModeManager.MODE_NIGHT_CUSTOM; Loading Loading @@ -98,9 +99,10 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import androidx.annotation.VisibleForTesting; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.DisableCarModeActivity; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; Loading Loading @@ -482,6 +484,11 @@ final class UiModeManagerService extends SystemService { mCurrentUser = currentUserId; } @VisibleForTesting Boolean[] getNightModeOverrides() { return new Boolean[]{mOverrideNightModeOn, mOverrideNightModeOff}; } @Override public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { mCurrentUser = to.getUserIdentifier(); Loading Loading @@ -1590,6 +1597,9 @@ final class UiModeManagerService extends SystemService { private void onCustomTimeUpdated(int user) { persistNightMode(user); if (mNightMode.get() != MODE_NIGHT_CUSTOM) return; synchronized (mLock) { resetNightModeOverrideLocked(); if (shouldApplyAutomaticChangesImmediately()) { unregisterDeviceInactiveListenerLocked(); updateLocked(0, 0); Loading @@ -1597,6 +1607,7 @@ final class UiModeManagerService extends SystemService { registerDeviceInactiveListenerLocked(); } } } void dumpImpl(PrintWriter pw) { synchronized (mLock) { Loading Loading @@ -1865,6 +1876,8 @@ final class UiModeManagerService extends SystemService { unregisterTimeChangeEvent(); } updateForceInvertStates(); // Override night mode in power save mode if not in car mode if (mPowerSave && !mCarModeEnabled && !mCar) { uiMode &= ~Configuration.UI_MODE_NIGHT_NO; Loading Loading @@ -2192,26 +2205,21 @@ final class UiModeManagerService extends SystemService { } private void updateComputedNightModeLocked(boolean activate) { boolean newComputedValue = activate; boolean appliedOverrides = false; if (mNightMode.get() != MODE_NIGHT_YES && mNightMode.get() != UiModeManager.MODE_NIGHT_NO) { if (mOverrideNightModeOn && !newComputedValue) { newComputedValue = true; } else if (mOverrideNightModeOff && newComputedValue) { newComputedValue = false; } appliedOverrides = true; } // Computes final night mode values based on Attention Mode. mComputedNightMode = switch (mAttentionModeThemeOverlay) { case (UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT) -> true; case (UiModeManager.MODE_ATTENTION_THEME_OVERLAY_DAY) -> false; default -> newComputedValue; // case OFF }; updateForceInvertStates(); mComputedNightMode = activate; if (appliedOverrides) { if (mAttentionModeThemeOverlay != MODE_ATTENTION_THEME_OVERLAY_OFF) { mComputedNightMode = mAttentionModeThemeOverlay == MODE_ATTENTION_THEME_OVERLAY_NIGHT; return; } if (mNightMode.get() == MODE_NIGHT_YES || mNightMode.get() == UiModeManager.MODE_NIGHT_NO) { return; } if (mOverrideNightModeOn && !mComputedNightMode) { mComputedNightMode = true; return; } if (mOverrideNightModeOff && mComputedNightMode) { mComputedNightMode = false; return; } Loading Loading @@ -2455,7 +2463,7 @@ final class UiModeManagerService extends SystemService { } } @VisibleForTesting @VisibleForTesting(otherwise = VisibleForTesting.NONE) public static class Injector { public int getCallingUid() { return Binder.getCallingUid(); Loading
services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +56 −0 Original line number Diff line number Diff line Loading @@ -913,6 +913,62 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { .setExact(anyInt(), anyLong(), anyString(), any(), any()); } @Test public void customTime_clearsOverrides_whenOverrideOnIsSet() throws RemoteException { when(mPowerManager.isInteractive()).thenReturn(false); mService.setNightMode(MODE_NIGHT_CUSTOM); LocalTime scheduleStart = LocalTime.now().plusHours(2); LocalTime scheduleEnd = LocalTime.now().plusHours(3); mService.setCustomNightModeStart(scheduleStart.toNanoOfDay() / 1000); mService.setCustomNightModeEnd(scheduleEnd.toNanoOfDay() / 1000); assertThat(isNightModeActivated()).isFalse(); mService.setNightModeActivated(true); //Verify override is set and night mode is ON due to override Boolean[] overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isTrue(); // mOverrideNightModeOn assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff assertThat(isNightModeActivated()).isTrue(); // Night mode is ON due to override LocalTime newStartTime = LocalTime.now().plusHours(1); mService.setCustomNightModeStart(newStartTime.toNanoOfDay() / 1000); // Verify overrides are cleared overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn should be cleared assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff should be cleared } @Test public void customTime_clearsOverrides_whenOverrideOffIsSet() throws RemoteException { when(mPowerManager.isInteractive()).thenReturn(false); mService.setNightMode(MODE_NIGHT_CUSTOM); LocalTime scheduleStart = LocalTime.now().minusHours(2); LocalTime scheduleEnd = LocalTime.now().plusHours(3); mService.setCustomNightModeStart(scheduleStart.toNanoOfDay() / 1000); mService.setCustomNightModeEnd(scheduleEnd.toNanoOfDay() / 1000); assertThat(isNightModeActivated()).isTrue(); mService.setNightModeActivated(false); //Verify override is set and night mode is OFF due to override Boolean[] overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn assertThat(overrides[1]).isTrue(); // mOverrideNightModeOff assertThat(isNightModeActivated()).isFalse(); // Night mode is ON due to override LocalTime newEndTime = LocalTime.now().plusHours(1); mService.setCustomNightModeStart(newEndTime.toNanoOfDay() / 1000); // Verify overrides are cleared overrides = mUiManagerService.getNightModeOverrides(); assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn should be cleared assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff should be cleared } @Test public void customTime_alarmSetInTheFutureWhenOn() throws RemoteException { LocalDateTime now = LocalDateTime.now(); Loading