From 5f116e1db142757f6e39cc9e2eb804e9ed494bd0 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Sat, 7 Dec 2019 16:15:29 +0000 Subject: [PATCH] Apply Dark theme changes when screen off only this change waits to apply ui changes after screen off battery manager sends updates and continuously updates the ui mode this change also applies external changes to ui configurations when the mode is actually changed. this resolves some perfromance regression issues Fixes: 145694649 Fixes: 145161355 Fixes: 145776479 Test: atest UiModeManagerService Change-Id: Ib769df4302d1c09166e2dc456b8ced35daa4d0b7 --- core/java/android/provider/Settings.java | 16 +++++ .../systemui/qs/tiles/UiModeNightTile.java | 4 +- .../android/server/UiModeManagerService.java | 64 +++++++++++-------- 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ad8d553137951..165c2843301c8 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -647,6 +647,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 9fe9703e41816..d79e38332af5f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java @@ -92,7 +92,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); @@ -123,7 +123,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 b1e2c0fe9586a..a4a6f23fc8943 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -56,6 +56,7 @@ import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; import android.util.ArraySet; import android.util.Slog; + import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.DisableCarModeActivity; @@ -73,7 +74,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import static android.content.Intent.ACTION_SCREEN_OFF; final class UiModeManagerService extends SystemService { private static final String TAG = UiModeManager.class.getSimpleName(); @@ -97,6 +97,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; @@ -208,24 +212,23 @@ final class UiModeManagerService extends SystemService { public void onTwilightStateChanged(@Nullable TwilightState state) { synchronized (mLock) { if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { - 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. - } } } }; @@ -335,7 +338,7 @@ final class UiModeManagerService extends SystemService { SystemServerInitThreadPool.submit(() -> { synchronized (mLock) { updateConfigurationLocked(); - sendConfigurationLocked(); + applyConfigurationExternallyLocked(); } }, TAG + ".onStart"); @@ -404,6 +407,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(@UiModeManager.EnableCarMode int flags, @@ -525,11 +544,7 @@ 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. - } + unregisterScreenOffEvent(); } // Only persist setting if not in car mode if (!mCarModeEnabled) { @@ -541,12 +556,11 @@ final class UiModeManagerService extends SystemService { mNightMode = mode; mNightModeOverride = mode; - //on screen off will update configuration instead + // on screen off will update configuration instead if (mNightMode != UiModeManager.MODE_NIGHT_AUTO) { updateLocked(0, 0); } else { - getContext().registerReceiver( - mOnScreenOffHandler, new IntentFilter(ACTION_SCREEN_OFF)); + registerScreenOffEvent(); } } } @@ -594,10 +608,7 @@ final class UiModeManagerService extends SystemService { 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 @@ -608,7 +619,7 @@ final class UiModeManagerService extends SystemService { mNightMode = UiModeManager.MODE_NIGHT_NO; } updateConfigurationLocked(); - sendConfigurationLocked(); + applyConfigurationExternallyLocked(); return true; } finally { Binder.restoreCallingIdentity(ident); @@ -863,12 +874,12 @@ 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; // load splash screen instead of screenshot @@ -1052,7 +1063,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) { @@ -1130,7 +1141,6 @@ final class UiModeManagerService extends SystemService { final int user = UserHandle.getCallingUserId(); Secure.putIntForUser(getContext().getContentResolver(), OVERRIDE_NIGHT_MODE, mNightModeOverride, user); - } }