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
This commit is contained in:
Fiona Campbell
2021-02-15 12:22:17 +00:00
parent 80e8713490
commit 9320191858
12 changed files with 421 additions and 77 deletions

View File

@@ -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.
* <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>

View File

@@ -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.
* <p>

View File

@@ -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);

View File

@@ -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<Object> 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();

View File

@@ -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);
}
});
}

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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<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 @@ 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*/);
}
}
}

View File

@@ -62,6 +62,7 @@ import java.util.Objects;
* &lt;display-states>
* &lt;display unique-id="XXXXXXX">
* &lt;color-mode>0&lt;/color-mode>
* &lt;brightness-value>0&lt;/brightness-value>
* &lt;/display>
* &lt;/display-states>
* &lt;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);
}
}

View File

@@ -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);
}

View File

@@ -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"/>