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
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6dd6744..2430c09 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -19,6 +19,7 @@
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 @@
mGlobal.setTemporaryBrightness(displayId, brightness);
}
+
+ /**
+ * Sets the brightness of the specified display.
+ * <p>
+ * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
+ * permission.
+ * </p>
+ *
+ * @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.
+ * <p>
+ * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS}
+ * permission.
+ * </p>
+ *
+ * @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.
* <p>
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index fd0431c5..06efc4f 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -690,6 +690,37 @@
}
}
+
+ /**
+ * 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.
* <p>
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index dee9144..3538ff1 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -119,6 +119,12 @@
// 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 fae5862..6776c27 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -20,6 +20,7 @@
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.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 @@
// 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<Object> mWriteHistory = new LinkedList<>();
@@ -87,11 +90,15 @@
* 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 @@
} 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 @@
/**
* 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 @@
}
}
- 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 @@
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 @@
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 fea521f..bdb3926 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 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 @@
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 @@
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 0000000..8ce7b66
--- /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<BrightnessSettingListener> mListeners =
+ new CopyOnWriteArrayList<BrightnessSettingListener>();
+
+ 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 c010906..e38d91c 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 @@
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);
}
@@ -2662,6 +2665,48 @@
}
@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(
Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
@@ -2809,6 +2854,13 @@
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 d1d0496..48edb73 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 @@
}
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 7110d3e..56ad01b 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 @@
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 @@
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 @@
private ObjectAnimator mColorFadeOnAnimator;
private ObjectAnimator mColorFadeOffAnimator;
private RampAnimator<DisplayPowerState> 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 @@
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 @@
mContext = context;
mBrightnessTracker = brightnessTracker;
-
+ mBrightnessSetting = brightnessSetting;
PowerManager pm = context.getSystemService(PowerManager.class);
final Resources resources = context.getResources();
@@ -785,6 +788,10 @@
mAutomaticBrightnessController.stop();
}
+ if (mBrightnessSetting != null) {
+ mBrightnessSetting.unregisterListener(mBrightnessSettingListener);
+ }
+
mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
}
}
@@ -831,10 +838,12 @@
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 @@
// 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 @@
private void handleSettingsChange(boolean userSwitch) {
mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
-
if (userSwitch) {
// Don't treat user switches as user initiated change.
mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;
@@ -1825,10 +1833,11 @@
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 @@
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 @@
}
break;
case MSG_CONFIGURE_BRIGHTNESS:
- mBrightnessConfiguration = (BrightnessConfiguration)msg.obj;
+ mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
updatePowerState();
break;
@@ -2197,6 +2208,12 @@
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 a62642b..c90ddf4 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 @@
* <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 @@
* 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 @@
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 @@
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 @@
private static final class DisplayState {
private int mColorMode;
+ private float mBrightness;
public boolean setColorMode(int colorMode) {
if (colorMode == mColorMode) {
@@ -486,14 +513,33 @@
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 @@
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 d0aa28b..d5fc9ff 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 @@
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 b9aa554..4ef454c 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -70,6 +70,7 @@
<uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
<uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
<uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"/>
+ <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/>
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
<uses-permission android:name="android.permission.HARDWARE_TEST"/>