From d483f72ee37c7933b3cccf50ad4102fed27f8062 Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Mon, 2 Mar 2020 15:32:23 -0500 Subject: [PATCH] Dark theme not working bug When switching dark mode, the dark mode override should only apply when the dark theme is in auto or custom mode. The solution is to set the override to the same value as night mode Test: UiModeManagerTest Fixes: 150567159 Change-Id: Ib10b73e747a53669de0babc9b44d373b47bfc0fb --- core/java/android/provider/Settings.java | 12 ++- .../android/server/UiModeManagerService.java | 86 +++++++++++-------- .../server/UiModeManagerServiceTest.java | 9 ++ 3 files changed, 71 insertions(+), 36 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fa2b0148b4b5b..4216cf387380a 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7836,12 +7836,20 @@ public final class Settings { public static final String UI_NIGHT_MODE = "ui_night_mode"; /** - * The current night mode that has been overrided by the system. Owned + * The current night mode that has been overridden to turn on by the system. Owned * and controlled by UiModeManagerService. Constants are as per * UiModeManager. * @hide */ - public static final String UI_NIGHT_MODE_OVERRIDE = "ui_night_mode_override"; + public static final String UI_NIGHT_MODE_OVERRIDE_ON = "ui_night_mode_override_on"; + + /** + * The current night mode that has been overridden to turn off by the system. Owned + * and controlled by UiModeManagerService. Constants are as per + * UiModeManager. + * @hide + */ + public static final String UI_NIGHT_MODE_OVERRIDE_OFF = "ui_night_mode_override_off"; /** * Whether screensavers are enabled. diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index f619d6927fdb9..88b517c597c48 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -97,17 +97,11 @@ final class UiModeManagerService extends SystemService { private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mNightMode = UiModeManager.MODE_NIGHT_NO; - // we use the override auto mode - // for example: force night mode off in the night time - // while in auto mode - private int mNightModeOverride = mNightMode; private final LocalTime DEFAULT_CUSTOM_NIGHT_START_TIME = LocalTime.of(22, 0); private final LocalTime DEFAULT_CUSTOM_NIGHT_END_TIME = LocalTime.of(6, 0); private LocalTime mCustomAutoNightModeStartMilliseconds = DEFAULT_CUSTOM_NIGHT_START_TIME; private LocalTime mCustomAutoNightModeEndMilliseconds = DEFAULT_CUSTOM_NIGHT_END_TIME; - protected static final String OVERRIDE_NIGHT_MODE = Secure.UI_NIGHT_MODE_OVERRIDE; - private Map mCarModePackagePriority = new HashMap<>(); private boolean mCarModeEnabled = false; private boolean mCharging = false; @@ -150,6 +144,12 @@ final class UiModeManagerService extends SystemService { private AlarmManager mAlarmManager; private PowerManager mPowerManager; + // In automatic scheduling, the user is able + // to override the computed night mode until the two match + // Example: Activate dark mode in the day time until sunrise the next day + private boolean mOverrideNightModeOn; + private boolean mOverrideNightModeOff; + private PowerManager.WakeLock mWakeLock; private final LocalService mLocalService = new LocalService(); @@ -291,15 +291,18 @@ final class UiModeManagerService extends SystemService { private final ContentObserver mSetupWizardObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange, Uri uri) { - // setup wizard is done now so we can unblock - if (setupWizardCompleteForCurrentUser()) { - mSetupWizardComplete = true; - getContext().getContentResolver().unregisterContentObserver(mSetupWizardObserver); - // update night mode - Context context = getContext(); - updateNightModeFromSettings(context, context.getResources(), - UserHandle.getCallingUserId()); - updateLocked(0, 0); + synchronized (mLock) { + // setup wizard is done now so we can unblock + if (setupWizardCompleteForCurrentUser()) { + mSetupWizardComplete = true; + getContext().getContentResolver() + .unregisterContentObserver(mSetupWizardObserver); + // update night mode + Context context = getContext(); + updateNightModeFromSettingsLocked(context, context.getResources(), + UserHandle.getCallingUserId()); + updateLocked(0, 0); + } } } }; @@ -371,11 +374,10 @@ final class UiModeManagerService extends SystemService { mCar = pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); mWatch = pm.hasSystemFeature(PackageManager.FEATURE_WATCH); - updateNightModeFromSettings(context, res, UserHandle.getCallingUserId()); - // Update the initial, static configurations. SystemServerInitThreadPool.submit(() -> { synchronized (mLock) { + updateNightModeFromSettingsLocked(context, res, UserHandle.getCallingUserId()); updateConfigurationLocked(); applyConfigurationExternallyLocked(); } @@ -457,15 +459,17 @@ final class UiModeManagerService extends SystemService { * @param userId The user to update the setting for * @return True if the new value is different from the old value. False otherwise. */ - private boolean updateNightModeFromSettings(Context context, Resources res, int userId) { + private boolean updateNightModeFromSettingsLocked(Context context, Resources res, int userId) { final int defaultNightMode = res.getInteger( com.android.internal.R.integer.config_defaultNightMode); int oldNightMode = mNightMode; if (mSetupWizardComplete) { mNightMode = Secure.getIntForUser(context.getContentResolver(), Secure.UI_NIGHT_MODE, defaultNightMode, userId); - mNightModeOverride = Secure.getIntForUser(context.getContentResolver(), - OVERRIDE_NIGHT_MODE, defaultNightMode, userId); + mOverrideNightModeOn = Secure.getIntForUser(context.getContentResolver(), + Secure.UI_NIGHT_MODE_OVERRIDE_ON, defaultNightMode, userId) != 0; + mOverrideNightModeOff = Secure.getIntForUser(context.getContentResolver(), + Secure.UI_NIGHT_MODE_OVERRIDE_OFF, defaultNightMode, userId) != 0; mCustomAutoNightModeStartMilliseconds = LocalTime.ofNanoOfDay( Secure.getLongForUser(context.getContentResolver(), Secure.DARK_THEME_CUSTOM_START_TIME, @@ -476,9 +480,10 @@ final class UiModeManagerService extends SystemService { DEFAULT_CUSTOM_NIGHT_END_TIME.toNanoOfDay() / 1000L, userId) * 1000); } else { mNightMode = defaultNightMode; - mNightModeOverride = defaultNightMode; mCustomAutoNightModeEndMilliseconds = DEFAULT_CUSTOM_NIGHT_END_TIME; mCustomAutoNightModeStartMilliseconds = DEFAULT_CUSTOM_NIGHT_START_TIME; + mOverrideNightModeOn = false; + mOverrideNightModeOff = false; } return oldNightMode != mNightMode; @@ -647,7 +652,7 @@ final class UiModeManagerService extends SystemService { } mNightMode = mode; - mNightModeOverride = mode; + resetNightModeOverrideLocked(); // Only persist setting if not in car mode if (!mCarModeEnabled) { persistNightMode(user); @@ -708,8 +713,8 @@ final class UiModeManagerService extends SystemService { try { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { unregisterScreenOffEventLocked(); - mNightModeOverride = active - ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO; + mOverrideNightModeOff = !active; + mOverrideNightModeOn = active; } else if (mNightMode == UiModeManager.MODE_NIGHT_NO && active) { mNightMode = UiModeManager.MODE_NIGHT_YES; @@ -800,9 +805,11 @@ final class UiModeManagerService extends SystemService { pw.print(" mDockState="); pw.print(mDockState); pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); - pw.print(" mNightModeOverride="); pw.print(mNightModeOverride); pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); + pw.print(" mOverrideOn/Off="); pw.print(mOverrideNightModeOn); + pw.print("/"); pw.print(mOverrideNightModeOff); + pw.print(" mNightModeLocked="); pw.println(mNightModeLocked); pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); @@ -874,7 +881,7 @@ final class UiModeManagerService extends SystemService { // When exiting car mode, restore night mode from settings if (!isCarModeNowEnabled) { Context context = getContext(); - updateNightModeFromSettings(context, + updateNightModeFromSettingsLocked(context, context.getResources(), UserHandle.getCallingUserId()); } @@ -1000,7 +1007,9 @@ final class UiModeManagerService extends SystemService { Secure.putIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE, mNightMode, user); Secure.putIntForUser(getContext().getContentResolver(), - OVERRIDE_NIGHT_MODE, mNightModeOverride, user); + Secure.UI_NIGHT_MODE_OVERRIDE_ON, mOverrideNightModeOn ? 1 : 0, user); + Secure.putIntForUser(getContext().getContentResolver(), + Secure.UI_NIGHT_MODE_OVERRIDE_OFF, mOverrideNightModeOff ? 1 : 0, user); Secure.putLongForUser(getContext().getContentResolver(), Secure.DARK_THEME_CUSTOM_START_TIME, mCustomAutoNightModeStartMilliseconds.toNanoOfDay() / 1000, user); @@ -1130,6 +1139,7 @@ final class UiModeManagerService extends SystemService { void updateLocked(int enableFlags, int disableFlags) { String action = null; String oldAction = null; + boolean originalComputedNightMode = mComputedNightMode; if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) { adjustStatusBarCarModeLocked(); oldAction = UiModeManager.ACTION_EXIT_CAR_MODE; @@ -1210,6 +1220,11 @@ final class UiModeManagerService extends SystemService { sendConfigurationAndStartDreamOrDockAppLocked(category); } + // reset overrides if mComputedNightMode changes + if (originalComputedNightMode != mComputedNightMode) { + resetNightModeOverrideLocked(); + } + // keep screen on when charging and in car mode boolean keepScreenOn = mCharging && ((mCarModeEnabled && mCarModeKeepsScreenOn && @@ -1360,19 +1375,22 @@ final class UiModeManagerService extends SystemService { private void updateComputedNightModeLocked(boolean activate) { mComputedNightMode = activate; - if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) { + if (mOverrideNightModeOn && !mComputedNightMode) { mComputedNightMode = true; return; } - if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) { + if (mOverrideNightModeOff && mComputedNightMode) { mComputedNightMode = false; return; } + } - mNightModeOverride = mNightMode; - final int user = UserHandle.getCallingUserId(); - Secure.putIntForUser(getContext().getContentResolver(), - OVERRIDE_NIGHT_MODE, mNightModeOverride, user); + private void resetNightModeOverrideLocked() { + if (mOverrideNightModeOff || mOverrideNightModeOn) { + mOverrideNightModeOff = false; + mOverrideNightModeOn = false; + persistNightMode(UserHandle.getCallingUserId()); + } } private void registerVrStateListener() { @@ -1515,7 +1533,7 @@ final class UiModeManagerService extends SystemService { final int currentId = intent.getIntExtra( Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM); // only update if the value is actually changed - if (updateNightModeFromSettings(context, context.getResources(), currentId)) { + if (updateNightModeFromSettingsLocked(context, context.getResources(), currentId)) { updateLocked(0, 0); } } diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index 6a707eb361603..93ca34ad1a45e 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -166,6 +166,15 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { verify(mContext, atLeastOnce()).unregisterReceiver(any(BroadcastReceiver.class)); } + @Test + public void setNightModeActivated_fromNoToYesAndBAck() throws RemoteException { + mService.setNightMode(MODE_NIGHT_NO); + mService.setNightModeActivated(true); + assertTrue(isNightModeActivated()); + mService.setNightModeActivated(false); + assertFalse(isNightModeActivated()); + } + @Test public void autoNightModeSwitch_batterySaverOn() throws RemoteException { mService.setNightMode(MODE_NIGHT_NO);