From 9320191858d62d6a50842bf248d0f9c9752ea941 Mon Sep 17 00:00:00 2001 From: Fiona Campbell Date: Mon, 15 Feb 2021 12:22:17 +0000 Subject: [PATCH] Store Brightness Per Display This changes stores a brightness value per display. Add brightness value item to persistent data store. Add BrightnessSettingController to save and retrieve brightnesses. It is indexed by primary display device of the concerned logical display. Add method in DisplayManager to expose this. Bug: 176985835 Bug: 147415200 Bug: 175286226 Test: manual, check "adb shell dumpsys display | grep -A10 Persistent" shows brightness values for each display attached. Change-Id: Ib8557f8a0f45a5bfb0810967f678015d3f121bb9 --- .../hardware/display/DisplayManager.java | 38 ++++ .../display/DisplayManagerGlobal.java | 31 ++++ .../hardware/display/IDisplayManager.aidl | 6 + .../display/BrightnessSynchronizer.java | 27 +-- .../brightness/BrightnessController.java | 15 +- .../server/display/BrightnessSetting.java | 173 ++++++++++++++++++ .../server/display/DisplayManagerService.java | 54 +++++- .../display/DisplayManagerShellCommand.java | 19 +- .../display/DisplayPowerController.java | 53 ++++-- .../server/display/PersistentDataStore.java | 59 +++++- .../server/policy/PhoneWindowManager.java | 22 +-- .../tests/servicestests/AndroidManifest.xml | 1 + 12 files changed, 421 insertions(+), 77 deletions(-) create mode 100644 services/core/java/com/android/server/display/BrightnessSetting.java diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 6dd67447c3213..2430c09d93f46 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -19,6 +19,7 @@ package android.hardware.display; import static android.view.Display.DEFAULT_DISPLAY; import android.Manifest; +import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; @@ -921,6 +922,43 @@ public final class DisplayManager { mGlobal.setTemporaryBrightness(displayId, brightness); } + + /** + * Sets the brightness of the specified display. + *

+ * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} + * permission. + *

+ * + * @param displayId the logical display id + * @param brightness The brightness value from 0.0f to 1.0f. + * + * @hide + */ + @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS) + public void setBrightness(int displayId, @FloatRange(from = 0f, to = 1f) float brightness) { + mGlobal.setBrightness(displayId, brightness); + } + + + /** + * Gets the brightness of the specified display. + *

+ * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} + * permission. + *

+ * + * @param displayId The display of which brightness value to get from. + * + * @hide + */ + @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS) + @FloatRange(from = 0f, to = 1f) + public float getBrightness(int displayId) { + return mGlobal.getBrightness(displayId); + } + + /** * Temporarily sets the auto brightness adjustment factor. *

diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index fd0431c5bc3fb..06efc4fc263e3 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -690,6 +690,37 @@ public final class DisplayManagerGlobal { } } + + /** + * Sets the brightness of the display. + * + * @param brightness The brightness value from 0.0f to 1.0f. + * + * @hide + */ + public void setBrightness(int displayId, float brightness) { + try { + mDm.setBrightness(displayId, brightness); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + + /** + * Gets the brightness of the display. + * + * @param displayId The display from which to get the brightness + * + * @hide + */ + public float getBrightness(int displayId) { + try { + return mDm.getBrightness(displayId); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + /** * Temporarily sets the auto brightness adjustment factor. *

diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index dee91445c2241..3538ff17a5a27 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -119,6 +119,12 @@ interface IDisplayManager { // Temporarily sets the display brightness. void setTemporaryBrightness(int displayId, float brightness); + // Saves the display brightness. + void setBrightness(int displayId, float brightness); + + // Retrieves the display brightness. + float getBrightness(int displayId); + // Temporarily sets the auto brightness adjustment factor. void setTemporaryAutoBrightnessAdjustment(float adjustment); diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java index fae58622d91e0..6776c27fc16e6 100644 --- a/core/java/com/android/internal/display/BrightnessSynchronizer.java +++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java @@ -20,6 +20,7 @@ package com.android.internal.display; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; +import android.hardware.display.DisplayManager; import android.net.Uri; import android.os.Handler; import android.os.Looper; @@ -28,6 +29,7 @@ import android.os.PowerManager; import android.os.UserHandle; import android.provider.Settings; import android.util.MathUtils; +import android.view.Display; import java.util.LinkedList; import java.util.Queue; @@ -52,6 +54,7 @@ public class BrightnessSynchronizer { // This value is approximately 1/3 of the smallest possible brightness value. public static final float EPSILON = 0.001f; + private DisplayManager mDisplayManager; private final Context mContext; private final Queue mWriteHistory = new LinkedList<>(); @@ -87,11 +90,15 @@ public class BrightnessSynchronizer { * value, if float is invalid. If both are invalid, use default float value from config. */ public void startSynchronizing() { + if (mDisplayManager == null) { + mDisplayManager = mContext.getSystemService(DisplayManager.class); + } + final BrightnessSyncObserver brightnessSyncObserver; brightnessSyncObserver = new BrightnessSyncObserver(mHandler); brightnessSyncObserver.startObserving(); - final float currentFloatBrightness = getScreenBrightnessFloat(mContext); + final float currentFloatBrightness = getScreenBrightnessFloat(); final int currentIntBrightness = getScreenBrightnessInt(mContext); if (!Float.isNaN(currentFloatBrightness)) { @@ -101,9 +108,7 @@ public class BrightnessSynchronizer { } else { final float defaultBrightness = mContext.getResources().getFloat( com.android.internal.R.dimen.config_screenBrightnessSettingDefaultFloat); - Settings.System.putFloatForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, defaultBrightness, - UserHandle.USER_CURRENT); + mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, defaultBrightness); } } @@ -135,7 +140,7 @@ public class BrightnessSynchronizer { /** * Translates specified value from the float brightness system to the int brightness system, * given the min/max of each range. Accounts for special values such as OFF and invalid values. - * Value returned as a float privimite (to preserve precision), but is a value within the + * Value returned as a float primitive (to preserve precision), but is a value within the * int-system range. */ public static float brightnessFloatToIntRange(float brightnessFloat) { @@ -152,10 +157,8 @@ public class BrightnessSynchronizer { } } - private static float getScreenBrightnessFloat(Context context) { - return Settings.System.getFloatForUser(context.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, PowerManager.BRIGHTNESS_INVALID_FLOAT, - UserHandle.USER_CURRENT); + private float getScreenBrightnessFloat() { + return mDisplayManager.getBrightness(Display.DEFAULT_DISPLAY); } private static int getScreenBrightnessInt(Context context) { @@ -184,9 +187,7 @@ public class BrightnessSynchronizer { float newBrightnessFloat = brightnessIntToFloat(value); mWriteHistory.offer(newBrightnessFloat); mPreferredSettingValue = newBrightnessFloat; - Settings.System.putFloatForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, newBrightnessFloat, - UserHandle.USER_CURRENT); + mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, newBrightnessFloat); } } @@ -255,7 +256,7 @@ public class BrightnessSynchronizer { mHandler.removeMessages(MSG_UPDATE_FLOAT); mHandler.obtainMessage(MSG_UPDATE_FLOAT, currentBrightness, 0).sendToTarget(); } else if (BRIGHTNESS_FLOAT_URI.equals(uri)) { - float currentFloat = getScreenBrightnessFloat(mContext); + float currentFloat = getScreenBrightnessFloat(); int toSend = Float.floatToIntBits(currentFloat); mHandler.removeMessages(MSG_UPDATE_INT); mHandler.obtainMessage(MSG_UPDATE_INT, toSend, 0).sendToTarget(); diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java index fea521f15b849..bdb392608455f 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java @@ -241,15 +241,7 @@ public class BrightnessController implements ToggleSlider.Listener { public void run() { final float valFloat; final boolean inVrMode = mIsVrModeEnabled; - if (inVrMode) { - valFloat = Settings.System.getFloatForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, mDefaultBacklightForVr, - UserHandle.USER_CURRENT); - } else { - valFloat = Settings.System.getFloatForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, mDefaultBacklight, - UserHandle.USER_CURRENT); - } + valFloat = mDisplayManager.getBrightness(mDisplayId); // Value is passed as intbits, since this is what the message takes. final int valueAsIntBits = Float.floatToIntBits(valFloat); mHandler.obtainMessage(MSG_UPDATE_SLIDER, valueAsIntBits, @@ -364,14 +356,12 @@ public class BrightnessController implements ToggleSlider.Listener { metric = MetricsEvent.ACTION_BRIGHTNESS_FOR_VR; minBacklight = mMinimumBacklightForVr; maxBacklight = mMaximumBacklightForVr; - settingToChange = Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT; } else { metric = mAutomatic ? MetricsEvent.ACTION_BRIGHTNESS_AUTO : MetricsEvent.ACTION_BRIGHTNESS; minBacklight = PowerManager.BRIGHTNESS_MIN; maxBacklight = PowerManager.BRIGHTNESS_MAX; - settingToChange = Settings.System.SCREEN_BRIGHTNESS_FLOAT; } final float valFloat = MathUtils.min(convertGammaToLinearFloat(value, minBacklight, maxBacklight), @@ -386,8 +376,7 @@ public class BrightnessController implements ToggleSlider.Listener { if (!tracking) { AsyncTask.execute(new Runnable() { public void run() { - Settings.System.putFloatForUser(mContext.getContentResolver(), - settingToChange, valFloat, UserHandle.USER_CURRENT); + mDisplayManager.setBrightness(mDisplayId, valFloat); } }); } diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java new file mode 100644 index 0000000000000..8ce7b66e6c7e6 --- /dev/null +++ b/services/core/java/com/android/server/display/BrightnessSetting.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import android.annotation.NonNull; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.PowerManager; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.Slog; +import android.view.Display; + +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Saves brightness to a persistent data store, enabling each logical display to have its own + * brightness. + */ +public class BrightnessSetting { + private static final String TAG = "BrightnessSetting"; + + private static final int MSG_BRIGHTNESS_CHANGED = 1; + private static final Uri BRIGHTNESS_FLOAT_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT); + private final PersistentDataStore mPersistentDataStore; + + private final boolean mIsDefaultDisplay; + private final Context mContext; + private final LogicalDisplay mLogicalDisplay; + private final Object mLock = new Object(); + + private final Handler mHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + if (msg.what == MSG_BRIGHTNESS_CHANGED) { + float brightnessVal = Float.intBitsToFloat(msg.arg1); + notifyListeners(brightnessVal); + } + } + }; + + private final ContentObserver mBrightnessSettingsObserver = new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange, Uri uri) { + if (selfChange) { + return; + } + if (BRIGHTNESS_FLOAT_URI.equals(uri)) { + float brightness = getScreenBrightnessSettingFloat(); + setBrightness(brightness, true); + } + } + }; + + private final CopyOnWriteArrayList mListeners = + new CopyOnWriteArrayList(); + + private float mBrightness; + + BrightnessSetting(@NonNull PersistentDataStore persistentDataStore, + @NonNull LogicalDisplay logicalDisplay, + @NonNull Context context) { + mPersistentDataStore = persistentDataStore; + mLogicalDisplay = logicalDisplay; + mContext = context; + mIsDefaultDisplay = mLogicalDisplay.getDisplayIdLocked() == Display.DEFAULT_DISPLAY; + mBrightness = mPersistentDataStore.getBrightness( + mLogicalDisplay.getPrimaryDisplayDeviceLocked()); + if (mIsDefaultDisplay) { + mContext.getContentResolver().registerContentObserver(BRIGHTNESS_FLOAT_URI, + false, mBrightnessSettingsObserver); + } + } + + /** + * Returns the brightness from the brightness setting + * + * @return brightness for the current display + */ + public float getBrightness() { + return mBrightness; + } + + /** + * Registers listener for brightness setting change events. + */ + public void registerListener(BrightnessSettingListener l) { + if (!mListeners.contains(l)) { + mListeners.add(l); + } + } + + /** + * Unregisters listener for brightness setting change events. + * + * @param l listener + */ + public void unregisterListener(BrightnessSettingListener l) { + mListeners.remove(l); + } + + void setBrightness(float brightness) { + setBrightness(brightness, false); + } + + private void setBrightness(float brightness, boolean isFromSystemSetting) { + if (brightness == mBrightness) { + return; + } + if (Float.isNaN(brightness)) { + Slog.w(TAG, "Attempting to set invalid brightness"); + return; + } + synchronized (mLock) { + + mBrightness = brightness; + + // If it didn't come from us + if (mIsDefaultDisplay && !isFromSystemSetting) { + Settings.System.putFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightness, + UserHandle.USER_CURRENT); + } + mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(), + brightness); + int toSend = Float.floatToIntBits(mBrightness); + Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED, toSend, 0); + mHandler.sendMessage(msg); + } + } + + private float getScreenBrightnessSettingFloat() { + return Settings.System.getFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, PowerManager.BRIGHTNESS_INVALID_FLOAT, + UserHandle.USER_CURRENT); + } + + private void notifyListeners(float brightness) { + for (BrightnessSettingListener l : mListeners) { + l.onBrightnessChanged(brightness); + } + } + + /** + * Listener for changes to system brightness. + */ + public interface BrightnessSettingListener { + + /** + * Notify that the brightness has changed. + */ + void onBrightnessChanged(float brightness); + } +} diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index c0109065fea4d..e38d91ca9d338 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1955,9 +1955,12 @@ public final class DisplayManagerService extends SystemService { if (mBrightnessTracker == null) { mBrightnessTracker = new BrightnessTracker(mContext, null); } + + final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore, + display, mContext); final DisplayPowerController displayPowerController = new DisplayPowerController( mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, - mDisplayBlanker, display, mBrightnessTracker); + mDisplayBlanker, display, mBrightnessTracker, brightnessSetting); mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController); } @@ -2661,6 +2664,48 @@ public final class DisplayManagerService extends SystemService { } } + @Override // Binder call + public void setBrightness(int displayId, float brightness) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, + "Permission required to set the display's brightness"); + if (!isValidBrightness(brightness)) { + Slog.w(TAG, "Attempted to set invalid brightness" + brightness); + return; + } + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mSyncRoot) { + DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); + if (dpc != null) { + dpc.putScreenBrightnessSetting(brightness); + } + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override // Binder call + public float getBrightness(int displayId) { + float brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mContext.enforceCallingOrSelfPermission( + Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, + "Permission required to set the display's brightness"); + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mSyncRoot) { + DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); + if (dpc != null) { + brightness = dpc.getScreenBrightnessSetting(); + } + } + } finally { + Binder.restoreCallingIdentity(token); + } + return brightness; + } + @Override // Binder call public void setTemporaryAutoBrightnessAdjustment(float adjustment) { mContext.enforceCallingOrSelfPermission( @@ -2809,6 +2854,13 @@ public final class DisplayManagerService extends SystemService { Slog.w(TAG, msg); return false; } + + } + + private static boolean isValidBrightness(float brightness) { + return !Float.isNaN(brightness) + && (brightness >= PowerManager.BRIGHTNESS_MIN) + && (brightness <= PowerManager.BRIGHTNESS_MAX); } private final class LocalService extends DisplayManagerInternal { diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java index d1d04966bdecb..48edb73ac81df 100644 --- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java +++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java @@ -16,13 +16,11 @@ package com.android.server.display; -import android.Manifest; import android.content.Context; import android.content.Intent; -import android.os.Binder; +import android.hardware.display.DisplayManager; import android.os.ShellCommand; -import android.os.UserHandle; -import android.provider.Settings; +import android.view.Display; import java.io.PrintWriter; @@ -111,17 +109,8 @@ class DisplayManagerShellCommand extends ShellCommand { } final Context context = mService.getContext(); - context.enforceCallingOrSelfPermission( - Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, - "Permission required to set the display's brightness"); - final long token = Binder.clearCallingIdentity(); - try { - Settings.System.putFloatForUser(context.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightness, - UserHandle.USER_CURRENT); - } finally { - Binder.restoreCallingIdentity(token); - } + final DisplayManager dm = context.getSystemService(DisplayManager.class); + dm.setBrightness(Display.DEFAULT_DISPLAY, brightness); return 0; } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 7110d3e6a7c16..56ad01b3c41b3 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -122,6 +122,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7; private static final int MSG_IGNORE_PROXIMITY = 8; private static final int MSG_STOP = 9; + private static final int MSG_UPDATE_BRIGHTNESS = 10; private static final int PROXIMITY_UNKNOWN = -1; private static final int PROXIMITY_NEGATIVE = 0; @@ -355,13 +356,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private final HighBrightnessModeController mHbmController; + private final BrightnessSetting mBrightnessSetting; + // A record of state for skipping brightness ramps. private int mSkipRampState = RAMP_STATE_SKIP_NONE; // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL. private float mInitialAutoBrightness; - // The controller for the automatic brightness level. private AutomaticBrightnessController mAutomaticBrightnessController; @@ -410,6 +412,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private ObjectAnimator mColorFadeOnAnimator; private ObjectAnimator mColorFadeOffAnimator; private RampAnimator mScreenBrightnessRampAnimator; + private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener; // True if this DisplayPowerController has been stopped and should no longer be running. private boolean mStopped; @@ -420,7 +423,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call public DisplayPowerController(Context context, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, - BrightnessTracker brightnessTracker) { + BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting) { mLogicalDisplay = logicalDisplay; mDisplayId = mLogicalDisplay.getDisplayIdLocked(); mHandler = new DisplayControllerHandler(handler.getLooper()); @@ -439,7 +442,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mContext = context; mBrightnessTracker = brightnessTracker; - + mBrightnessSetting = brightnessSetting; PowerManager pm = context.getSystemService(PowerManager.class); final Resources resources = context.getResources(); @@ -785,6 +788,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAutomaticBrightnessController.stop(); } + if (mBrightnessSetting != null) { + mBrightnessSetting.unregisterListener(mBrightnessSettingListener); + } + mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); } } @@ -831,10 +838,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (brightness >= PowerManager.BRIGHTNESS_MIN) { mBrightnessTracker.start(brightness); } + mBrightnessSettingListener = brightnessValue -> { + Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue); + mHandler.sendMessage(msg); + }; - mContext.getContentResolver().registerContentObserver( - Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT), - false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); + mBrightnessSetting.registerListener(mBrightnessSettingListener); mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT), false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); @@ -1150,7 +1159,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // before applying the low power or dim transformations so that the slider // accurately represents the full possible range, even if they range changes what // it means in absolute terms. - putScreenBrightnessSetting(brightnessState); + putScreenBrightnessSetting(brightnessState, /* updateCurrent */ true); } // Apply dimming by at least some minimum amount when user activity @@ -1804,7 +1813,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void handleSettingsChange(boolean userSwitch) { mPendingScreenBrightnessSetting = getScreenBrightnessSetting(); - if (userSwitch) { // Don't treat user switches as user initiated change. mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting; @@ -1825,10 +1833,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj); } - private float getScreenBrightnessSetting() { - final float brightness = Settings.System.getFloatForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, mScreenBrightnessDefault, - UserHandle.USER_CURRENT); + float getScreenBrightnessSetting() { + float brightness = mBrightnessSetting.getBrightness(); + if (Float.isNaN(brightness)) { + brightness = mScreenBrightnessDefault; + } return clampAbsoluteBrightness(brightness); } @@ -1839,13 +1848,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call return clampScreenBrightnessForVr(brightnessFloat); } - private void putScreenBrightnessSetting(float brightnessValue) { - if (mDisplayId == Display.DEFAULT_DISPLAY) { + void putScreenBrightnessSetting(float brightnessValue) { + putScreenBrightnessSetting(brightnessValue, false); + } + + private void putScreenBrightnessSetting(float brightnessValue, boolean updateCurrent) { + if (updateCurrent) { mCurrentScreenBrightnessSetting = brightnessValue; - Settings.System.putFloatForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessValue, - UserHandle.USER_CURRENT); } + mBrightnessSetting.setBrightness(brightnessValue); } private void putAutoBrightnessAdjustmentSetting(float adjustment) { @@ -2175,7 +2186,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } break; case MSG_CONFIGURE_BRIGHTNESS: - mBrightnessConfiguration = (BrightnessConfiguration)msg.obj; + mBrightnessConfiguration = (BrightnessConfiguration) msg.obj; updatePowerState(); break; @@ -2197,6 +2208,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call case MSG_STOP: cleanupHandlerThreadAfterStop(); break; + + case MSG_UPDATE_BRIGHTNESS: + if (mStopped) { + return; + } + handleSettingsChange(false /*userSwitch*/); } } } diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index a62642b1f8423..c90ddf48a0918 100644 --- a/services/core/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java @@ -62,6 +62,7 @@ import java.util.Objects; * <display-states> * <display unique-id="XXXXXXX"> * <color-mode>0</color-mode> + * <brightness-value>0</brightness-value> * </display> * </display-states> * <stable-device-values> @@ -82,7 +83,7 @@ import java.util.Objects; * TODO: refactor this to extract common code shared with the input manager's data store */ final class PersistentDataStore { - static final String TAG = "DisplayManager"; + static final String TAG = "DisplayManager.PersistentDataStore"; private static final String TAG_DISPLAY_MANAGER_STATE = "display-manager-state"; @@ -95,6 +96,7 @@ final class PersistentDataStore { private static final String TAG_DISPLAY_STATES = "display-states"; private static final String TAG_DISPLAY = "display"; private static final String TAG_COLOR_MODE = "color-mode"; + private static final String TAG_BRIGHTNESS_VALUE = "brightness-value"; private static final String ATTR_UNIQUE_ID = "unique-id"; private static final String TAG_STABLE_DEVICE_VALUES = "stable-device-values"; @@ -255,6 +257,30 @@ final class PersistentDataStore { return false; } + public float getBrightness(DisplayDevice device) { + if (device == null || !device.hasStableUniqueId()) { + return Float.NaN; + } + final DisplayState state = getDisplayState(device.getUniqueId(), false); + if (state == null) { + return Float.NaN; + } + return state.getBrightness(); + } + + public boolean setBrightness(DisplayDevice displayDevice, float brightness) { + final String displayDeviceUniqueId = displayDevice.getUniqueId(); + if (!displayDevice.hasStableUniqueId() || displayDeviceUniqueId == null) { + return false; + } + final DisplayState state = getDisplayState(displayDeviceUniqueId, true); + if (state.setBrightness(brightness)) { + setDirty(); + return true; + } + return false; + } + public Point getStableDisplaySize() { loadIfNeeded(); return mStableDeviceValues.getDisplaySize(); @@ -473,6 +499,7 @@ final class PersistentDataStore { private static final class DisplayState { private int mColorMode; + private float mBrightness; public boolean setColorMode(int colorMode) { if (colorMode == mColorMode) { @@ -486,14 +513,33 @@ final class PersistentDataStore { return mColorMode; } + public boolean setBrightness(float brightness) { + if (brightness == mBrightness) { + return false; + } + mBrightness = brightness; + return true; + } + + public float getBrightness() { + return mBrightness; + } + + public void loadFromXml(TypedXmlPullParser parser) throws IOException, XmlPullParserException { final int outerDepth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, outerDepth)) { - if (parser.getName().equals(TAG_COLOR_MODE)) { - String value = parser.nextText(); - mColorMode = Integer.parseInt(value); + switch (parser.getName()) { + case TAG_COLOR_MODE: + String value = parser.nextText(); + mColorMode = Integer.parseInt(value); + break; + case TAG_BRIGHTNESS_VALUE: + String brightness = parser.nextText(); + mBrightness = Float.parseFloat(brightness); + break; } } } @@ -502,10 +548,15 @@ final class PersistentDataStore { serializer.startTag(null, TAG_COLOR_MODE); serializer.text(Integer.toString(mColorMode)); serializer.endTag(null, TAG_COLOR_MODE); + serializer.startTag(null, TAG_BRIGHTNESS_VALUE); + serializer.text(Float.toString(mBrightness)); + serializer.endTag(null, TAG_BRIGHTNESS_VALUE); + } public void dump(final PrintWriter pw, final String prefix) { pw.println(prefix + "ColorMode=" + mColorMode); + pw.println(prefix + "BrightnessValue=" + mBrightness); } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index d0aa28b441a0d..d5fc9ffd09849 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2624,23 +2624,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT_OR_SELF); } - float minFloat = mPowerManager.getBrightnessConstraint( + float min = mPowerManager.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); - float maxFloat = mPowerManager.getBrightnessConstraint( + float max = mPowerManager.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); - float stepFloat = (maxFloat - minFloat) / BRIGHTNESS_STEPS * direction; - float brightnessFloat = Settings.System.getFloatForUser( - mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_FLOAT, - mContext.getDisplay().getBrightnessDefault(), - UserHandle.USER_CURRENT_OR_SELF); - brightnessFloat += stepFloat; + float step = (max - min) / BRIGHTNESS_STEPS * direction; + int screenDisplayId = displayId < 0 ? DEFAULT_DISPLAY : displayId; + float brightness = mDisplayManager.getBrightness(screenDisplayId); + brightness += step; // Make sure we don't go beyond the limits. - brightnessFloat = Math.min(maxFloat, brightnessFloat); - brightnessFloat = Math.max(minFloat, brightnessFloat); + brightness = Math.min(max, brightness); + brightness = Math.max(min, brightness); - Settings.System.putFloatForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessFloat, - UserHandle.USER_CURRENT_OR_SELF); + mDisplayManager.setBrightness(screenDisplayId, brightness); startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG), UserHandle.CURRENT_OR_SELF); } diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index b9aa554aa0acc..4ef454c072458 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -70,6 +70,7 @@ +