diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b9f5348027e6e..495b37cb5944d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -660,6 +660,22 @@ public final class Settings {
public static final String ACTION_NIGHT_DISPLAY_SETTINGS =
"android.settings.NIGHT_DISPLAY_SETTINGS";
+ /**
+ * Activity Action: Show settings to allow configuration of Dark theme.
+ *
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ *
+ * Input: Nothing.
+ *
+ * Output: Nothing.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_DARK_THEME_SETTINGS =
+ "android.settings.DARK_THEME_SETTINGS";
+
/**
* Activity Action: Show settings to allow configuration of locale.
*
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
index dc9a2ce1beef5..54fbaf3617459 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -91,7 +91,7 @@ public class UiModeNightTile extends QSTileImpl implements
boolean nightMode = (mContext.getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
- if (isAuto) {
+ if (isAuto && !powerSave) {
state.secondaryLabel = mContext.getResources().getString(nightMode
? R.string.quick_settings_dark_mode_secondary_label_until_sunrise
: R.string.quick_settings_dark_mode_secondary_label_on_at_sunset);
@@ -121,7 +121,7 @@ public class UiModeNightTile extends QSTileImpl implements
@Override
public Intent getLongClickIntent() {
- return new Intent(Settings.ACTION_DISPLAY_SETTINGS);
+ return new Intent(Settings.ACTION_DARK_THEME_SETTINGS);
}
@Override
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 7215389055218..978cc577f1eb0 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -16,8 +16,6 @@
package com.android.server;
-import static android.content.Intent.ACTION_SCREEN_OFF;
-
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -91,6 +89,10 @@ final class UiModeManagerService extends SystemService {
private boolean mCarModeEnabled = false;
private boolean mCharging = false;
private boolean mPowerSave = false;
+ // Do not change configuration now. wait until screen turns off.
+ // This prevents jank and activity restart when the user
+ // is actively using the device
+ private boolean mWaitForScreenOff = false;
private int mDefaultUiModeType;
private boolean mCarModeKeepsScreenOn;
private boolean mDeskModeKeepsScreenOn;
@@ -206,25 +208,24 @@ final class UiModeManagerService extends SystemService {
if (mCar) {
updateLocked(0, 0);
} else {
- final IntentFilter intentFilter =
- new IntentFilter(ACTION_SCREEN_OFF);
- getContext().registerReceiver(mOnScreenOffHandler, intentFilter);
+ registerScreenOffEvent();
}
}
}
}
};
+ /**
+ * DO NOT USE DIRECTLY
+ * see register registerScreenOffEvent and unregisterScreenOffEvent
+ */
private final BroadcastReceiver mOnScreenOffHandler = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
+ // must unregister first before updating
+ unregisterScreenOffEvent();
updateLocked(0, 0);
- try {
- getContext().unregisterReceiver(mOnScreenOffHandler);
- } catch (IllegalArgumentException e) {
- // we ignore this exception if the receiver is unregistered already.
- }
}
}
};
@@ -263,7 +264,7 @@ final class UiModeManagerService extends SystemService {
int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE,
mNightMode, 0);
mode = mode == UiModeManager.MODE_NIGHT_AUTO
- ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO;
+ ? UiModeManager.MODE_NIGHT_YES : mode;
SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
}
};
@@ -335,7 +336,7 @@ final class UiModeManagerService extends SystemService {
SystemServerInitThreadPool.get().submit(() -> {
synchronized (mLock) {
updateConfigurationLocked();
- sendConfigurationLocked();
+ applyConfigurationExternallyLocked();
}
}, TAG + ".onStart");
@@ -404,6 +405,22 @@ final class UiModeManagerService extends SystemService {
return oldNightMode != mNightMode;
}
+ private void registerScreenOffEvent() {
+ mWaitForScreenOff = true;
+ final IntentFilter intentFilter =
+ new IntentFilter(Intent.ACTION_SCREEN_OFF);
+ getContext().registerReceiver(mOnScreenOffHandler, intentFilter);
+ }
+
+ private void unregisterScreenOffEvent() {
+ mWaitForScreenOff = false;
+ try {
+ getContext().unregisterReceiver(mOnScreenOffHandler);
+ } catch (IllegalArgumentException e) {
+ // we ignore this exception if the receiver is unregistered already.
+ }
+ }
+
private final IUiModeManager.Stub mService = new IUiModeManager.Stub() {
@Override
public void enableCarMode(int flags) {
@@ -482,28 +499,21 @@ final class UiModeManagerService extends SystemService {
synchronized (mLock) {
if (mNightMode != mode) {
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
- try {
- getContext().unregisterReceiver(mOnScreenOffHandler);
- } catch (IllegalArgumentException e) {
- // we ignore this exception if the receiver is unregistered already.
- }
- }
- // Only persist setting if not in car mode
- if (!mCarModeEnabled) {
- Secure.putIntForUser(getContext().getContentResolver(),
- Secure.UI_NIGHT_MODE, mode, user);
- Secure.putIntForUser(getContext().getContentResolver(),
- OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
+ unregisterScreenOffEvent();
}
mNightMode = mode;
mNightModeOverride = mode;
- //on screen off will update configuration instead
+
+ // Only persist setting if not in car mode
+ if (!mCarModeEnabled) {
+ persistNightMode(user);
+ }
+ // on screen off will update configuration instead
if (mNightMode != UiModeManager.MODE_NIGHT_AUTO || mCar) {
updateLocked(0, 0);
} else {
- getContext().registerReceiver(
- mOnScreenOffHandler, new IntentFilter(ACTION_SCREEN_OFF));
+ registerScreenOffEvent();
}
}
}
@@ -548,13 +558,11 @@ final class UiModeManagerService extends SystemService {
@Override
public boolean setNightModeActivated(boolean active) {
synchronized (mLock) {
+ final int user = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
- try {
- getContext().unregisterReceiver(mOnScreenOffHandler);
- } catch (IllegalArgumentException e) {
- }
+ unregisterScreenOffEvent();
mNightModeOverride = active
? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO;
} else if (mNightMode == UiModeManager.MODE_NIGHT_NO
@@ -565,7 +573,8 @@ final class UiModeManagerService extends SystemService {
mNightMode = UiModeManager.MODE_NIGHT_NO;
}
updateConfigurationLocked();
- sendConfigurationLocked();
+ applyConfigurationExternallyLocked();
+ persistNightMode(user);
return true;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -651,6 +660,13 @@ final class UiModeManagerService extends SystemService {
}
}
+ private void persistNightMode(int user) {
+ Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.UI_NIGHT_MODE, mNightMode, user);
+ Secure.putIntForUser(getContext().getContentResolver(),
+ OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
+ }
+
private void updateConfigurationLocked() {
int uiMode = mDefaultUiModeType;
if (mUiModeLocked) {
@@ -696,15 +712,14 @@ final class UiModeManagerService extends SystemService {
}
mCurUiMode = uiMode;
- if (!mHoldingConfiguration) {
+ if (!mHoldingConfiguration || !mWaitForScreenOff) {
mConfiguration.uiMode = uiMode;
}
}
- private void sendConfigurationLocked() {
+ private void applyConfigurationExternallyLocked() {
if (mSetUiMode != mConfiguration.uiMode) {
mSetUiMode = mConfiguration.uiMode;
-
try {
ActivityTaskManager.getService().updateConfiguration(mConfiguration);
} catch (RemoteException e) {
@@ -884,7 +899,7 @@ final class UiModeManagerService extends SystemService {
}
// Send the new configuration.
- sendConfigurationLocked();
+ applyConfigurationExternallyLocked();
// If we did not start a dock app, then start dreaming if supported.
if (category != null && !dockAppStarted) {
@@ -962,7 +977,6 @@ final class UiModeManagerService extends SystemService {
final int user = UserHandle.getCallingUserId();
Secure.putIntForUser(getContext().getContentResolver(),
OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
-
}
}