diff options
37 files changed, 1076 insertions, 404 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index dc15b51a442c..a52ee54e655c 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -8723,6 +8723,7 @@ public class DevicePolicyManager { @StringDef({ Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS, + Settings.System.SCREEN_BRIGHTNESS_FLOAT, Settings.System.SCREEN_OFF_TIMEOUT }) @Retention(RetentionPolicy.SOURCE) diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index d67de09dd2a4..25b84c5c01b0 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -766,11 +766,11 @@ public final class DisplayManager { * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission. * </p> * - * @param brightness The brightness value from 0 to 255. + * @param brightness The brightness value from 0.0f to 1.0f. * * @hide Requires signature permission. */ - public void setTemporaryBrightness(int brightness) { + public void setTemporaryBrightness(float brightness) { mGlobal.setTemporaryBrightness(brightness); } diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index fd539e8f1c91..9d92c894f3f6 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -616,7 +616,7 @@ public final class DisplayManagerGlobal { * * @hide Requires signature permission. */ - public void setTemporaryBrightness(int brightness) { + public void setTemporaryBrightness(float brightness) { try { mDm.setTemporaryBrightness(brightness); } catch (RemoteException ex) { diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 79a339fa27aa..ea2b9e79d99c 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -268,8 +268,9 @@ public abstract class DisplayManagerInternal { // nearby, turning it off temporarily until the object is moved away. public boolean useProximitySensor; - // An override of the screen brightness. Set to -1 is used if there's no override. - public int screenBrightnessOverride; + // An override of the screen brightness. + // Set to PowerManager.BRIGHTNESS_INVALID if there's no override. + public float screenBrightnessOverride; // An override of the screen auto-brightness adjustment factor in the range -1 (dimmer) to // 1 (brighter). Set to Float.NaN if there's no override. @@ -300,18 +301,18 @@ public abstract class DisplayManagerInternal { public boolean blockScreenOn; // Overrides the policy for adjusting screen brightness and state while dozing. - public int dozeScreenBrightness; public int dozeScreenState; + public float dozeScreenBrightness; public DisplayPowerRequest() { policy = POLICY_BRIGHT; useProximitySensor = false; - screenBrightnessOverride = -1; + screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT; useAutoBrightness = false; screenAutoBrightnessAdjustmentOverride = Float.NaN; screenLowPowerBrightnessFactor = 0.5f; blockScreenOn = false; - dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; + dozeScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; dozeScreenState = Display.STATE_UNKNOWN; } @@ -351,7 +352,8 @@ public abstract class DisplayManagerInternal { return other != null && policy == other.policy && useProximitySensor == other.useProximitySensor - && screenBrightnessOverride == other.screenBrightnessOverride + && floatEquals(screenBrightnessOverride, + other.screenBrightnessOverride) && useAutoBrightness == other.useAutoBrightness && floatEquals(screenAutoBrightnessAdjustmentOverride, other.screenAutoBrightnessAdjustmentOverride) @@ -360,7 +362,7 @@ public abstract class DisplayManagerInternal { && blockScreenOn == other.blockScreenOn && lowPowerMode == other.lowPowerMode && boostScreenBrightness == other.boostScreenBrightness - && dozeScreenBrightness == other.dozeScreenBrightness + && floatEquals(dozeScreenBrightness, other.dozeScreenBrightness) && dozeScreenState == other.dozeScreenState; } diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index ccf221b693bc..d22188ec5d7f 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -115,7 +115,7 @@ interface IDisplayManager { boolean isMinimalPostProcessingRequested(int displayId); // Temporarily sets the display brightness. - void setTemporaryBrightness(int brightness); + void setTemporaryBrightness(float brightness); // Temporarily sets the auto brightness adjustment factor. void setTemporaryAutoBrightnessAdjustment(float adjustment); diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 3ae570081f4d..1cefbd9afa80 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -49,6 +49,7 @@ interface IPowerManager void goToSleep(long time, int reason, int flags); @UnsupportedAppUsage(maxTargetSdk = 28) void nap(long time); + float getBrightnessConstraint(int constraint); @UnsupportedAppUsage boolean isInteractive(); boolean isPowerSaveMode(); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index f3d3837bbed1..267613f0af83 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -248,8 +248,27 @@ public final class PowerManager { public static final int BRIGHTNESS_DEFAULT = -1; /** + * Brightness value for an invalid value having been stored. + * @hide + */ + public static final int BRIGHTNESS_INVALID = -1; + + //Brightness values for new float implementation: + /** + * Brightness value for fully on as float. + * @hide + */ + public static final float BRIGHTNESS_MAX = 1.0f; + + /** + * Brightness value for minimum valid brightness as float. + * @hide + */ + public static final float BRIGHTNESS_MIN = 0.0f; + + /** * Brightness value for fully off in float. - * TODO: rename this to BRIGHTNES_OFF and remove the integer-based constant. + * TODO(brightnessfloat): rename this to BRIGHTNES_OFF and remove the integer-based constant. * @hide */ public static final float BRIGHTNESS_OFF_FLOAT = -1.0f; @@ -424,6 +443,69 @@ public final class PowerManager { /** * @hide */ + @IntDef(prefix = { "BRIGHTNESS_CONSTRAINT_TYPE" }, value = { + BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM, + BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM, + BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT, + BRIGHTNESS_CONSTRAINT_TYPE_DIM, + BRIGHTNESS_CONSTRAINT_TYPE_DOZE, + BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR, + BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR, + BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT_VR + }) + @Retention(RetentionPolicy.SOURCE) + public @interface BrightnessConstraint{} + + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM = 0; + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM = 1; + + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT = 2; + + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_DIM = 3; + + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_DOZE = 4; + + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR = 5; + + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR = 6; + + /** + * Brightness constraint type: minimum allowed value. + * @hide + */ + public static final int BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT_VR = 7; + + /** + * @hide + */ @IntDef(prefix = { "WAKE_REASON_" }, value = { WAKE_REASON_UNKNOWN, WAKE_REASON_POWER_BUTTON, @@ -889,6 +971,19 @@ public final class PowerManager { } /** + * Gets a float screen brightness setting. + * @hide + */ + @UnsupportedAppUsage + public float getBrightnessConstraint(int constraint) { + try { + return mService.getBrightnessConstraint(constraint); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Creates a new wake lock with the specified level and flags. * <p> * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index b9207e5a12d5..9944fb9acea3 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3915,6 +3915,19 @@ public final class Settings { public static final String SCREEN_BRIGHTNESS_FOR_VR = "screen_brightness_for_vr"; /** + * The screen backlight brightness between 0.0f and 1.0f. + * @hide + */ + public static final String SCREEN_BRIGHTNESS_FOR_VR_FLOAT = + "screen_brightness_for_vr_float"; + + /** + * The screen backlight brightness between 0.0f and 1.0f. + * @hide + */ + public static final String SCREEN_BRIGHTNESS_FLOAT = "screen_brightness_float"; + + /** * Control whether to enable automatic brightness mode. */ public static final String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode"; @@ -4727,7 +4740,9 @@ public final class Settings { PUBLIC_SETTINGS.add(DIM_SCREEN); PUBLIC_SETTINGS.add(SCREEN_OFF_TIMEOUT); PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS); + PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_FLOAT); PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_FOR_VR); + PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_FOR_VR_FLOAT); PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_MODE); PUBLIC_SETTINGS.add(ADAPTIVE_SLEEP); PUBLIC_SETTINGS.add(MODE_RINGER_STREAMS_AFFECTED); diff --git a/core/java/com/android/internal/BrightnessSynchronizer.java b/core/java/com/android/internal/BrightnessSynchronizer.java new file mode 100644 index 000000000000..aa23251b9b85 --- /dev/null +++ b/core/java/com/android/internal/BrightnessSynchronizer.java @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2019 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.internal; + + +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Message; +import android.os.PowerManager; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.MathUtils; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * BrightnessSynchronizer helps convert between the int (old) system and float + * (new) system for storing the brightness. It has methods to convert between the two and also + * observes for when one of the settings is changed and syncs this with the other. + */ +public class BrightnessSynchronizer{ + + private static final int MSG_UPDATE_FLOAT = 1; + private static final int MSG_UPDATE_INT = 2; + + private static final String TAG = "BrightnessSynchronizer"; + private static final Uri BRIGHTNESS_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); + private static final Uri BRIGHTNESS_FLOAT_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT); + + // The tolerance within which we consider brightness values approximately equal to eachother. + // This value is approximately 1/3 of the smallest possible brightness value. + public static final float EPSILON = 0.001f; + + private final Context mContext; + + private final Queue<Object> mWriteHistory = new LinkedList<>(); + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE_FLOAT: + updateBrightnessFloatFromInt(msg.arg1); + break; + case MSG_UPDATE_INT: + updateBrightnessIntFromFloat(Float.intBitsToFloat(msg.arg1)); + break; + default: + super.handleMessage(msg); + } + + } + }; + + + public BrightnessSynchronizer(Context context) { + final BrightnessSyncObserver mBrightnessSyncObserver; + mContext = context; + mBrightnessSyncObserver = new BrightnessSyncObserver(mHandler); + mBrightnessSyncObserver.startObserving(); + } + + /** + * Converts between the int brightness system and the float brightness system. + */ + public static float brightnessIntToFloat(Context context, int brightnessInt) { + PowerManager pm = context.getSystemService(PowerManager.class); + float pmMinBrightness = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); + float pmMaxBrightness = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); + int minBrightnessInt = brightnessFloatToInt(pmMinBrightness, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, + PowerManager.BRIGHTNESS_ON); + int maxBrightnessInt = brightnessFloatToInt(pmMaxBrightness, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, + PowerManager.BRIGHTNESS_ON); + + return brightnessIntToFloat(brightnessInt, minBrightnessInt, maxBrightnessInt, + pmMinBrightness, pmMaxBrightness); + } + + /** + * Converts between the int brightness system and the float brightness system. + */ + public static float brightnessIntToFloat(int brightnessInt, int minInt, int maxInt, + float minFloat, float maxFloat) { + if (brightnessInt == PowerManager.BRIGHTNESS_OFF) { + return PowerManager.BRIGHTNESS_OFF_FLOAT; + } else if (brightnessInt == PowerManager.BRIGHTNESS_INVALID) { + return PowerManager.BRIGHTNESS_INVALID_FLOAT; + } else { + return MathUtils.constrainedMap(minFloat, maxFloat, (float) minInt, (float) maxInt, + brightnessInt); + } + } + + /** + * Converts between the float brightness system and the int brightness system. + */ + public static int brightnessFloatToInt(Context context, float brightnessFloat) { + PowerManager pm = context.getSystemService(PowerManager.class); + float pmMinBrightness = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); + float pmMaxBrightness = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); + int minBrightnessInt = brightnessFloatToInt(pmMinBrightness, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, + PowerManager.BRIGHTNESS_ON); + int maxBrightnessInt = brightnessFloatToInt(pmMaxBrightness, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, + PowerManager.BRIGHTNESS_ON); + + return brightnessFloatToInt(brightnessFloat, pmMinBrightness, pmMaxBrightness, + minBrightnessInt, maxBrightnessInt); + } + + /** + * Converts between the float brightness system and the int brightness system. + */ + public static int brightnessFloatToInt(float brightnessFloat, float minFloat, float maxFloat, + int minInt, int maxInt) { + if (floatEquals(brightnessFloat, PowerManager.BRIGHTNESS_OFF_FLOAT)) { + return PowerManager.BRIGHTNESS_OFF; + } else if (Float.isNaN(brightnessFloat)) { + return PowerManager.BRIGHTNESS_INVALID; + } else { + return Math.round(MathUtils.constrainedMap((float) minInt, (float) maxInt, minFloat, + maxFloat, brightnessFloat)); + } + } + + private static float getScreenBrightnessFloat(Context context) { + return Settings.System.getFloatForUser(context.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, Float.NaN, UserHandle.USER_CURRENT); + } + + private static int getScreenBrightnessInt(Context context) { + return Settings.System.getIntForUser(context.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS, 0, UserHandle.USER_CURRENT); + } + + private float mPreferredSettingValue; + + /** + * Updates the float setting based on a passed in int value. This is called whenever the int + * setting changes. mWriteHistory keeps a record of the values that been written to the settings + * from either this method or updateBrightnessIntFromFloat. This is to ensure that the value + * being set is due to an external value being set, rather than the updateBrightness* methods. + * The intention of this is to avoid race conditions when the setting is being changed + * frequently and to ensure we are not reacting to settings changes from this file. + * @param value Brightness value as int to store in the float setting. + */ + private void updateBrightnessFloatFromInt(int value) { + Object topOfQueue = mWriteHistory.peek(); + if (topOfQueue != null && topOfQueue.equals(value)) { + mWriteHistory.poll(); + } else { + if (brightnessFloatToInt(mContext, mPreferredSettingValue) == value) { + return; + } + float newBrightnessFloat = brightnessIntToFloat(mContext, value); + mWriteHistory.offer(newBrightnessFloat); + mPreferredSettingValue = newBrightnessFloat; + Settings.System.putFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, newBrightnessFloat, + UserHandle.USER_CURRENT); + } + } + + /** + * Updates the int setting based on a passed in float value. This is called whenever the float + * setting changes. mWriteHistory keeps a record of the values that been written to the settings + * from either this method or updateBrightnessFloatFromInt. This is to ensure that the value + * being set is due to an external value being set, rather than the updateBrightness* methods. + * The intention of this is to avoid race conditions when the setting is being changed + * frequently and to ensure we are not reacting to settings changes from this file. + * @param value Brightness setting as float to store in int setting. + */ + private void updateBrightnessIntFromFloat(float value) { + int newBrightnessInt = brightnessFloatToInt(mContext, value); + Object topOfQueue = mWriteHistory.peek(); + if (topOfQueue != null && topOfQueue.equals(value)) { + mWriteHistory.poll(); + } else { + mWriteHistory.offer(newBrightnessInt); + mPreferredSettingValue = value; + Settings.System.putIntForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS, newBrightnessInt, UserHandle.USER_CURRENT); + } + } + + /** + * Tests whether two brightness float values are within a small enough tolerance + * of each other. + * @param a first float to compare + * @param b second float to compare + * @return whether the two values are within a small enough tolerance value + */ + public static boolean floatEquals(float a, float b) { + if (a == b) { + return true; + } else if (Float.isNaN(a) && Float.isNaN(b)) { + return true; + } else if (Math.abs(a - b) < EPSILON) { + return true; + } else { + return false; + } + } + + private class BrightnessSyncObserver extends ContentObserver { + /** + * Creates a content observer. + * @param handler The handler to run {@link #onChange} on, or null if none. + */ + BrightnessSyncObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange) { + onChange(selfChange, null); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + if (selfChange) { + return; + } + if (BRIGHTNESS_URI.equals(uri)) { + int currentBrightness = getScreenBrightnessInt(mContext); + mHandler.obtainMessage(MSG_UPDATE_FLOAT, currentBrightness, 0).sendToTarget(); + } else if (BRIGHTNESS_FLOAT_URI.equals(uri)) { + float currentFloat = getScreenBrightnessFloat(mContext); + int toSend = Float.floatToIntBits(currentFloat); + mHandler.obtainMessage(MSG_UPDATE_INT, toSend, 0).sendToTarget(); + } + } + + public void startObserving() { + final ContentResolver cr = mContext.getContentResolver(); + cr.unregisterContentObserver(this); + cr.registerContentObserver(BRIGHTNESS_URI, false, this, UserHandle.USER_ALL); + cr.registerContentObserver(BRIGHTNESS_FLOAT_URI, false, this, UserHandle.USER_ALL); + } + + public void stopObserving() { + final ContentResolver cr = mContext.getContentResolver(); + cr.unregisterContentObserver(this); + } + } +} diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto index f8143de8121f..b723b5307bc1 100644 --- a/core/proto/android/providers/settings/system.proto +++ b/core/proto/android/providers/settings/system.proto @@ -161,6 +161,8 @@ message SystemSettingsProto { optional SettingProto brightness_for_vr = 3 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto brightness_mode = 4 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto auto_brightness_adj = 5 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto brightness_float = 6 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto brightness_for_vr_float = 7 [ (android.privacy).dest = DEST_AUTOMATIC ]; } optional Screen screen = 22; diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 7f574ba2036b..939ccd0f708f 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1258,32 +1258,63 @@ --> <integer name="config_doubleTapOnHomeBehavior">0</integer> - <!-- Minimum screen brightness setting allowed by the power manager. - The user is forbidden from setting the brightness below this level. --> + <!-- Note: This setting is deprecated, please use + config_screenBrightnessSettingMinimumFloat instead --> <integer name="config_screenBrightnessSettingMinimum">10</integer> - <!-- Maximum screen brightness allowed by the power manager. - The user is forbidden from setting the brightness above this level. --> + <!-- Note: This setting is deprecated, please use + config_screenBrightnessSettingMaximumFloat instead --> <integer name="config_screenBrightnessSettingMaximum">255</integer> - <!-- Default screen brightness setting. - Must be in the range specified by minimum and maximum. --> + <!-- Note: This setting is deprecated, please use + config_screenBrightnessSettingDefaultFloat instead --> <integer name="config_screenBrightnessSettingDefault">102</integer> - <!-- Default screen brightness for VR setting. --> + <!-- Minimum screen brightness setting allowed by power manager. + The user is forbidden from setting the brightness below this level. + Equivalent to 10/255. --> + <item name="config_screenBrightnessSettingMinimumFloat" format="float" type="dimen">0.035433073</item> + + <!-- Maximum screen brightness allowed by the power manager. + The user is forbidden from setting the brightness above this level. + This value is a fraction between 3.5% and 100%. --> + <item name="config_screenBrightnessSettingMaximumFloat" format="float" type="dimen">1.0</item> + + <!-- Default screen brightness setting. + Must be in the range specified by minimum and maximum. + This value is a fraction between 3.5% and 100%. + Equivalent to 102/255 (default for this device) --> + <item name="config_screenBrightnessSettingDefaultFloat" format="float" type="dimen">0.397637795276</item> + + <!-- Note: This setting is deprecated, please use + config_screenBrightnessSettingForVrDefaultFloat instead --> <integer name="config_screenBrightnessForVrSettingDefault">86</integer> - <!-- Minimum screen brightness setting allowed for VR. Device panels start increasing pulse - width as brightness decreases below this theshold. --> + <!-- Note: This setting is deprecated, please use + config_screenBrightnessSettingForVrMinimumFloat instead --> <integer name="config_screenBrightnessForVrSettingMinimum">79</integer> - <!-- Maximum screen brightness setting allowed for VR. --> + <!-- Note: This setting is deprecated, please use + config_screenBrightnessSettingForVrMaximumFloat instead --> <integer name="config_screenBrightnessForVrSettingMaximum">255</integer> + <!-- Default screen brightness for VR setting as a float. + Equivalent to 86/255--> + <item name="config_screenBrightnessSettingForVrDefaultFloat" format="float" type="dimen">0.33464</item> + + <!-- Minimum screen brightness setting allowed for VR. Device panels start increasing pulse + width as brightness decreases below this threshold as float. + Equivalent to 79/255 --> + <item name="config_screenBrightnessSettingForVrMinimumFloat" format="float" type="dimen">0.307087</item> + + <!-- Maximum screen brightness setting allowed for VR as float. --> + <item name="config_screenBrightnessSettingForVrMaximumFloat" format="float" type="dimen">1.0</item> + <!-- Screen brightness used to dim the screen while dozing in a very low power state. May be less than the minimum allowed brightness setting that can be set by the user. --> <integer name="config_screenBrightnessDoze">1</integer> + <item name="config_screenBrightnessDozeFloat" format="float" type="dimen">0.0</item> <!-- Delay that allows some content to arrive at the display before switching from DOZE to ON. --> @@ -1339,6 +1370,7 @@ timeout expires. May be less than the minimum allowed brightness setting that can be set by the user. --> <integer name="config_screenBrightnessDim">10</integer> + <item name="config_screenBrightnessDimFloat" format="float" type="dimen">0.05</item> <!-- Minimum allowable screen brightness to use in a very dark room. This value sets the floor for the darkest possible auto-brightness diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0babe48e832e..f8aa3dc4218f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1980,6 +1980,14 @@ <java-symbol type="integer" name="config_screenBrightnessForVrSettingDefault" /> <java-symbol type="integer" name="config_screenBrightnessForVrSettingMaximum" /> <java-symbol type="integer" name="config_screenBrightnessForVrSettingMinimum" /> + <java-symbol type="dimen" name="config_screenBrightnessSettingForVrMinimumFloat" /> + <java-symbol type="dimen" name="config_screenBrightnessSettingForVrMaximumFloat" /> + <java-symbol type="dimen" name="config_screenBrightnessSettingForVrDefaultFloat" /> + <java-symbol type="dimen" name="config_screenBrightnessSettingMinimumFloat" /> + <java-symbol type="dimen" name="config_screenBrightnessSettingMaximumFloat" /> + <java-symbol type="dimen" name="config_screenBrightnessSettingDefaultFloat" /> + <java-symbol type="dimen" name="config_screenBrightnessDozeFloat" /> + <java-symbol type="dimen" name="config_screenBrightnessDimFloat" /> <java-symbol type="integer" name="config_screenBrightnessDark" /> <java-symbol type="integer" name="config_screenBrightnessDim" /> <java-symbol type="integer" name="config_screenBrightnessDoze" /> diff --git a/core/tests/coretests/src/android/os/BrightnessLimit.java b/core/tests/coretests/src/android/os/BrightnessLimit.java index 5a3724f7aa24..be7935545543 100644 --- a/core/tests/coretests/src/android/os/BrightnessLimit.java +++ b/core/tests/coretests/src/android/os/BrightnessLimit.java @@ -42,7 +42,7 @@ public class BrightnessLimit extends Activity implements OnClickListener { public void onClick(View v) { DisplayManager dm = getSystemService(DisplayManager.class); - dm.setTemporaryBrightness(0); + dm.setTemporaryBrightness(0.0f); Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java index 55723f9d8ed4..57d95942bcb9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java @@ -20,7 +20,8 @@ import android.util.MathUtils; public class BrightnessUtils { - public static final int GAMMA_SPACE_MAX = 1023; + public static final int GAMMA_SPACE_MIN = 0; + public static final int GAMMA_SPACE_MAX = 65535; // Hybrid Log Gamma constant values private static final float R = 0.5f; @@ -51,7 +52,7 @@ public class BrightnessUtils { * @return The corresponding setting value. */ public static final int convertGammaToLinear(int val, int min, int max) { - final float normalizedVal = MathUtils.norm(0, GAMMA_SPACE_MAX, val); + final float normalizedVal = MathUtils.norm(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, val); final float ret; if (normalizedVal <= R) { ret = MathUtils.sq(normalizedVal / R); @@ -65,6 +66,29 @@ public class BrightnessUtils { } /** + * Version of {@link #convertGammaToLinear} that takes and returns float values. + * TODO: brightnessfloat Merge with above method later. + * + * @param val The slider value. + * @param min The minimum acceptable value for the setting. + * @param max The maximum acceptable value for the setting. + * @return The corresponding setting value. + */ + public static final float convertGammaToLinearFloat(int val, float min, float max) { + final float normalizedVal = MathUtils.norm(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, val); + final float ret; + if (normalizedVal <= R) { + ret = MathUtils.sq(normalizedVal / R); + } else { + ret = MathUtils.exp((normalizedVal - C) / A) + B; + } + + // HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1] + // in order to derive the correct setting value. + return MathUtils.lerp(min, max, ret / 12); + } + + /** * A function for converting from the linear space that the setting works in to the * gamma space that the slider works in. * @@ -96,6 +120,27 @@ public class BrightnessUtils { ret = A * MathUtils.log(normalizedVal - B) + C; } - return Math.round(MathUtils.lerp(0, GAMMA_SPACE_MAX, ret)); + return Math.round(MathUtils.lerp(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, ret)); + } + + /** + * Version of {@link #convertLinearToGamma} that takes float values. + * TODO: brightnessfloat merge with above method(?) + * @param val The brightness setting value. + * @param min The minimum acceptable value for the setting. + * @param max The maximum acceptable value for the setting. + * @return The corresponding slider value + */ + public static final int convertLinearToGammaFloat(float val, float min, float max) { + // For some reason, HLG normalizes to the range [0, 12] rather than [0, 1] + final float normalizedVal = MathUtils.norm(min, max, val) * 12; + final float ret; + if (normalizedVal <= 1f) { + ret = MathUtils.sqrt(normalizedVal) * R; + } else { + ret = A * MathUtils.log(normalizedVal - B) + C; + } + + return Math.round(MathUtils.lerp(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, ret)); } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 78b9f16ef355..66d8306932e0 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -2727,6 +2727,12 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, SystemSettingsProto.Screen.AUTO_BRIGHTNESS_ADJ); + dumpSetting(s, p, + Settings.System.SCREEN_BRIGHTNESS_FLOAT, + SystemSettingsProto.Screen.BRIGHTNESS_FLOAT); + dumpSetting(s, p, + Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, + SystemSettingsProto.Screen.BRIGHTNESS_FOR_VR_FLOAT); p.end(screenToken); dumpSetting(s, p, diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index dee1d7eced66..bf817b1ccafd 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -99,7 +99,9 @@ public class SettingsBackupTest { Settings.System.WHEN_TO_MAKE_WIFI_CALLS, // bug? Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, // used for debugging only Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities - Settings.System.PEAK_REFRESH_RATE // depends on hardware capabilities + Settings.System.PEAK_REFRESH_RATE, // depends on hardware capabilities + Settings.System.SCREEN_BRIGHTNESS_FLOAT, + Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT ); private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS = diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java index 4e887262659e..7e1c35dde683 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java @@ -199,7 +199,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi mDozeService.setDozeScreenBrightness(clampToUserSetting(mDefaultDozeBrightness)); mDozeHost.setAodDimmingScrim(0f); } - + //TODO: brightnessfloat change usages to float. private int clampToUserSetting(int brightness) { int userSetting = Settings.System.getIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, Integer.MAX_VALUE, diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index b1f1f3844cac..821144a7f12d 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -17,8 +17,8 @@ package com.android.systemui.settings; import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX; -import static com.android.settingslib.display.BrightnessUtils.convertGammaToLinear; -import static com.android.settingslib.display.BrightnessUtils.convertLinearToGamma; +import static com.android.settingslib.display.BrightnessUtils.convertGammaToLinearFloat; +import static com.android.settingslib.display.BrightnessUtils.convertLinearToGammaFloat; import android.animation.ValueAnimator; import android.content.ContentResolver; @@ -39,7 +39,9 @@ import android.provider.Settings; import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; import android.util.Log; +import android.util.MathUtils; +import com.android.internal.BrightnessSynchronizer; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.RestrictedLockUtilsInternal; @@ -58,12 +60,21 @@ public class BrightnessController implements ToggleSlider.Listener { private static final int MSG_DETACH_LISTENER = 4; private static final int MSG_VR_MODE_CHANGED = 5; - private final int mMinimumBacklight; - private final int mMaximumBacklight; - private final int mDefaultBacklight; - private final int mMinimumBacklightForVr; - private final int mMaximumBacklightForVr; - private final int mDefaultBacklightForVr; + private static final Uri BRIGHTNESS_MODE_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); + private static final Uri BRIGHTNESS_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); + private static final Uri BRIGHTNESS_FLOAT_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT); + private static final Uri BRIGHTNESS_FOR_VR_FLOAT_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT); + + private final float mMinimumBacklight; + private final float mMaximumBacklight; + private final float mDefaultBacklight; + private final float mMinimumBacklightForVr; + private final float mMaximumBacklightForVr; + private final float mDefaultBacklightForVr; private final Context mContext; private final ToggleSlider mControl; @@ -90,16 +101,9 @@ public class BrightnessController implements ToggleSlider.Listener { public void onBrightnessLevelChanged(); } - /** ContentObserver to watch brightness **/ + /** ContentObserver to watch brightness */ private class BrightnessObserver extends ContentObserver { - private final Uri BRIGHTNESS_MODE_URI = - Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); - private final Uri BRIGHTNESS_URI = - Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); - private final Uri BRIGHTNESS_FOR_VR_URI = - Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR); - public BrightnessObserver(Handler handler) { super(handler); } @@ -116,9 +120,9 @@ public class BrightnessController implements ToggleSlider.Listener { if (BRIGHTNESS_MODE_URI.equals(uri)) { mBackgroundHandler.post(mUpdateModeRunnable); mBackgroundHandler.post(mUpdateSliderRunnable); - } else if (BRIGHTNESS_URI.equals(uri)) { + } else if (BRIGHTNESS_FLOAT_URI.equals(uri)) { mBackgroundHandler.post(mUpdateSliderRunnable); - } else if (BRIGHTNESS_FOR_VR_URI.equals(uri)) { + } else if (BRIGHTNESS_FOR_VR_FLOAT_URI.equals(uri)) { mBackgroundHandler.post(mUpdateSliderRunnable); } else { mBackgroundHandler.post(mUpdateModeRunnable); @@ -139,7 +143,10 @@ public class BrightnessController implements ToggleSlider.Listener { BRIGHTNESS_URI, false, this, UserHandle.USER_ALL); cr.registerContentObserver( - BRIGHTNESS_FOR_VR_URI, + BRIGHTNESS_FLOAT_URI, + false, this, UserHandle.USER_ALL); + cr.registerContentObserver( + BRIGHTNESS_FOR_VR_FLOAT_URI, false, this, UserHandle.USER_ALL); } @@ -229,18 +236,21 @@ public class BrightnessController implements ToggleSlider.Listener { private final Runnable mUpdateSliderRunnable = new Runnable() { @Override public void run() { - final int val; + final float valFloat; final boolean inVrMode = mIsVrModeEnabled; if (inVrMode) { - val = Settings.System.getIntForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FOR_VR, mDefaultBacklightForVr, + valFloat = Settings.System.getFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, mDefaultBacklightForVr, UserHandle.USER_CURRENT); } else { - val = Settings.System.getIntForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, mDefaultBacklight, + valFloat = Settings.System.getFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, mDefaultBacklight, UserHandle.USER_CURRENT); } - mHandler.obtainMessage(MSG_UPDATE_SLIDER, val, inVrMode ? 1 : 0).sendToTarget(); + // Value is passed as intbits, since this is what the message takes. + final int valueAsIntBits = Float.floatToIntBits(valFloat); + mHandler.obtainMessage(MSG_UPDATE_SLIDER, valueAsIntBits, + inVrMode ? 1 : 0).sendToTarget(); } }; @@ -259,7 +269,7 @@ public class BrightnessController implements ToggleSlider.Listener { try { switch (msg.what) { case MSG_UPDATE_SLIDER: - updateSlider(msg.arg1, msg.arg2 != 0); + updateSlider(Float.intBitsToFloat(msg.arg1), msg.arg2 != 0); break; case MSG_SET_CHECKED: mControl.setChecked(msg.arg1 != 0); @@ -298,12 +308,19 @@ public class BrightnessController implements ToggleSlider.Listener { mBrightnessObserver = new BrightnessObserver(mHandler); PowerManager pm = context.getSystemService(PowerManager.class); - mMinimumBacklight = pm.getMinimumScreenBrightnessSetting(); - mMaximumBacklight = pm.getMaximumScreenBrightnessSetting(); - mDefaultBacklight = pm.getDefaultScreenBrightnessSetting(); - mMinimumBacklightForVr = pm.getMinimumScreenBrightnessForVrSetting(); - mMaximumBacklightForVr = pm.getMaximumScreenBrightnessForVrSetting(); - mDefaultBacklightForVr = pm.getDefaultScreenBrightnessForVrSetting(); + mMinimumBacklight = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); + mMaximumBacklight = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); + mDefaultBacklight = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT); + mMinimumBacklightForVr = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR); + mMaximumBacklightForVr = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR); + mDefaultBacklightForVr = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT_VR); + mAutomaticAvailable = context.getResources().getBoolean( com.android.internal.R.bool.config_automatic_brightness_available); @@ -344,37 +361,39 @@ public class BrightnessController implements ToggleSlider.Listener { mSliderAnimator.cancel(); } - final int min; - final int max; + final float minBacklight; + final float maxBacklight; final int metric; - final String setting; + final String settingToChange; if (mIsVrModeEnabled) { metric = MetricsEvent.ACTION_BRIGHTNESS_FOR_VR; - min = mMinimumBacklightForVr; - max = mMaximumBacklightForVr; - setting = Settings.System.SCREEN_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; - min = mMinimumBacklight; - max = mMaximumBacklight; - setting = Settings.System.SCREEN_BRIGHTNESS; + minBacklight = mMinimumBacklight; + maxBacklight = mMaximumBacklight; + settingToChange = Settings.System.SCREEN_BRIGHTNESS_FLOAT; } - - final int val = convertGammaToLinear(value, min, max); - + final float valFloat = MathUtils.min(convertGammaToLinearFloat(value, + minBacklight, maxBacklight), + 1.0f); if (stopTracking) { - MetricsLogger.action(mContext, metric, val); - } + // TODO(brightnessfloat): change to use float value instead. + MetricsLogger.action(mContext, metric, + BrightnessSynchronizer.brightnessFloatToInt(mContext, valFloat)); - setBrightness(val); + } + setBrightness(valFloat); if (!tracking) { AsyncTask.execute(new Runnable() { public void run() { - Settings.System.putIntForUser(mContext.getContentResolver(), - setting, val, UserHandle.USER_CURRENT); + Settings.System.putFloatForUser(mContext.getContentResolver(), + settingToChange, valFloat, UserHandle.USER_CURRENT); } }); } @@ -402,7 +421,7 @@ public class BrightnessController implements ToggleSlider.Listener { mUserTracker.getCurrentUserId()); } - private void setBrightness(int brightness) { + private void setBrightness(float brightness) { mDisplayManager.setTemporaryBrightness(brightness); } @@ -413,9 +432,9 @@ public class BrightnessController implements ToggleSlider.Listener { } } - private void updateSlider(int val, boolean inVrMode) { - final int min; - final int max; + private void updateSlider(float brightnessValue, boolean inVrMode) { + final float min; + final float max; if (inVrMode) { min = mMinimumBacklightForVr; max = mMaximumBacklightForVr; @@ -423,7 +442,10 @@ public class BrightnessController implements ToggleSlider.Listener { min = mMinimumBacklight; max = mMaximumBacklight; } - if (val == convertGammaToLinear(mControl.getValue(), min, max)) { + // convertGammaToLinearFloat returns 0-1 + if (BrightnessSynchronizer.brightnessFloatToInt(mContext, brightnessValue) + == BrightnessSynchronizer.brightnessFloatToInt(mContext, + convertGammaToLinearFloat(mControl.getValue(), min, max))) { // If we have more resolution on the slider than we do in the actual setting, then // multiple slider positions will map to the same setting value. Thus, if we see a // setting value here that maps to the current slider position, we don't bother to @@ -431,7 +453,8 @@ public class BrightnessController implements ToggleSlider.Listener { // change to the user even though it isn't one. return; } - final int sliderVal = convertLinearToGamma(val, min, max); + // Returns GAMMA_SPACE_MIN - GAMMA_SPACE_MAX + final int sliderVal = convertLinearToGammaFloat(brightnessValue, min, max); animateSliderTo(sliderVal); } diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index c99774a41f10..6178e6c1e094 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -21,6 +21,7 @@ import android.app.ActivityManager.StackInfo; import android.app.ActivityTaskManager; import android.app.IActivityTaskManager; import android.app.TaskStackListener; +import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.hardware.Sensor; @@ -41,6 +42,7 @@ import android.util.MathUtils; import android.util.Slog; import android.util.TimeUtils; +import com.android.internal.BrightnessSynchronizer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.server.EventLogTags; @@ -89,6 +91,8 @@ class AutomaticBrightnessController { // The minimum and maximum screen brightnesses. private final int mScreenBrightnessRangeMinimum; private final int mScreenBrightnessRangeMaximum; + private final float mScreenBrightnessRangeMinimumFloat; + private final float mScreenBrightnessRangeMaximumFloat; // How much to scale doze brightness by (should be (0, 1.0]). private final float mDozeScaleFactor; @@ -174,7 +178,7 @@ class AutomaticBrightnessController { // that we can quickly revert to the previous auto-brightness level // while the light sensor warms up. // Use -1 if there is no current auto-brightness value available. - private int mScreenAutoBrightness = -1; + private int mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID; // The current display policy. This is useful, for example, for knowing when we're dozing, // where the light sensor may not be available. @@ -204,39 +208,44 @@ class AutomaticBrightnessController { private TaskStackListenerImpl mTaskStackListener; private IActivityTaskManager mActivityTaskManager; private PackageManager mPackageManager; + private Context mContext; private final Injector mInjector; AutomaticBrightnessController(Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, BrightnessMappingStrategy mapper, - int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, - int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, - long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, - HysteresisLevels ambientBrightnessThresholds, - HysteresisLevels screenBrightnessThresholds, - PackageManager packageManager) { + int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, + float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, + long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, + boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds, + HysteresisLevels screenBrightnessThresholds, Context context) { this(new Injector(), callbacks, looper, sensorManager, lightSensor, mapper, lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig, darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig, - ambientBrightnessThresholds, screenBrightnessThresholds, packageManager); + ambientBrightnessThresholds, screenBrightnessThresholds, context); } @VisibleForTesting AutomaticBrightnessController(Injector injector, Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, BrightnessMappingStrategy mapper, - int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, - int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, - long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, - HysteresisLevels ambientBrightnessThresholds, - HysteresisLevels screenBrightnessThresholds, - PackageManager packageManager) { + int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, + float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, + long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, + boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds, + HysteresisLevels screenBrightnessThresholds, Context context) { mInjector = injector; + mContext = context; mCallbacks = callbacks; mSensorManager = sensorManager; mBrightnessMapper = mapper; - mScreenBrightnessRangeMinimum = brightnessMin; - mScreenBrightnessRangeMaximum = brightnessMax; + mScreenBrightnessRangeMinimum = + BrightnessSynchronizer.brightnessFloatToInt(mContext, brightnessMin); + mScreenBrightnessRangeMaximum = + com.android.internal.BrightnessSynchronizer.brightnessFloatToInt( + mContext, brightnessMax); + mScreenBrightnessRangeMinimumFloat = brightnessMin; + mScreenBrightnessRangeMaximumFloat = brightnessMax; mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime; mDozeScaleFactor = dozeScaleFactor; mNormalLightSensorRate = lightSensorRate; @@ -261,7 +270,7 @@ class AutomaticBrightnessController { } mActivityTaskManager = ActivityTaskManager.getService(); - mPackageManager = packageManager; + mPackageManager = mContext.getPackageManager(); mTaskStackListener = new TaskStackListenerImpl(); mForegroundAppPackageName = null; mPendingForegroundAppPackageName = null; @@ -291,7 +300,7 @@ class AutomaticBrightnessController { return -1; } if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) { - return (int) (mScreenAutoBrightness * mDozeScaleFactor); + return Math.round(mScreenAutoBrightness * mDozeScaleFactor); } return mScreenAutoBrightness; } @@ -473,7 +482,7 @@ class AutomaticBrightnessController { } else if (mLightSensorEnabled) { mLightSensorEnabled = false; mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; - mScreenAutoBrightness = -1; + mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID; mRecentLightSamples = 0; mAmbientLightRingBuffer.clear(); mCurrentLightSensorRate = -1; @@ -722,10 +731,8 @@ class AutomaticBrightnessController { float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName, mForegroundAppCategory); - - int newScreenAutoBrightness = Math.round(clampScreenBrightness( - value * PowerManager.BRIGHTNESS_ON)); - + int newScreenAutoBrightness = BrightnessSynchronizer.brightnessFloatToInt( + mContext, clampScreenBrightnessFloat(value)); // If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold, // in which case we ignore the new screen brightness if it doesn't differ enough from the // previous one. @@ -759,11 +766,19 @@ class AutomaticBrightnessController { } } + // Clamps values with float range [1.0-255.0] + // TODO(brightnessfloat): convert everything that uses this to float system private float clampScreenBrightness(float value) { return MathUtils.constrain(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); } + // Clamps values with float range [0.0-1.0] + private float clampScreenBrightnessFloat(float value) { + return MathUtils.constrain(value, + mScreenBrightnessRangeMinimumFloat, mScreenBrightnessRangeMaximumFloat); + } + private void prepareBrightnessAdjustmentSample() { if (!mBrightnessAdjustmentSamplePending) { mBrightnessAdjustmentSamplePending = true; diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index 6ff276703443..a099606852d0 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -28,6 +28,7 @@ import android.util.Pair; import android.util.Slog; import android.util.Spline; +import com.android.internal.BrightnessSynchronizer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.server.display.utils.Plog; @@ -342,9 +343,9 @@ public abstract class BrightnessMappingStrategy { } protected static float normalizeAbsoluteBrightness(int brightness) { - brightness = MathUtils.constrain(brightness, - PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); - return (float) brightness / PowerManager.BRIGHTNESS_ON; + return BrightnessSynchronizer.brightnessIntToFloat(brightness, + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); } private Pair<float[], float[]> insertControlPoint( diff --git a/services/core/java/com/android/server/display/DisplayBlanker.java b/services/core/java/com/android/server/display/DisplayBlanker.java index 816dc1302bdc..d294898da8c4 100644 --- a/services/core/java/com/android/server/display/DisplayBlanker.java +++ b/services/core/java/com/android/server/display/DisplayBlanker.java @@ -20,5 +20,5 @@ package com.android.server.display; * Interface used to update the actual display state. */ public interface DisplayBlanker { - void requestDisplayState(int state, int brightness); + void requestDisplayState(int state, float brightness); } diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index e69a3b8ba4c1..63a8d7c92441 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -129,11 +129,11 @@ abstract class DisplayDevice { * Sets the display state, if supported. * * @param state The new display state. - * @param brightness The new display brightness. + * @param brightnessState The new display brightnessState. * @return A runnable containing work to be deferred until after we have * exited the critical section, or null if none. */ - public Runnable requestDisplayStateLocked(int state, int brightness) { + public Runnable requestDisplayStateLocked(int state, float brightnessState) { return null; } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 71ade6293216..91405890b076 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -232,7 +232,7 @@ public final class DisplayManagerService extends SystemService { // The overall display brightness. // For now, this only applies to the built-in display but we may split it up eventually. - private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT; + private float mGlobalDisplayBrightness; // Set to true when there are pending display changes that have yet to be applied // to the surface flinger state. @@ -340,7 +340,8 @@ public final class DisplayManagerService extends SystemService { mMinimumBrightnessSpline = Spline.createSpline(lux, nits); PowerManager pm = mContext.getSystemService(PowerManager.class); - mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); + mGlobalDisplayBrightness = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT); mCurrentUserId = UserHandle.USER_SYSTEM; ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); mWideColorSpace = colorSpaces[1]; @@ -539,16 +540,16 @@ public final class DisplayManagerService extends SystemService { } } - private void requestGlobalDisplayStateInternal(int state, int brightness) { + private void requestGlobalDisplayStateInternal(int state, float brightnessState) { if (state == Display.STATE_UNKNOWN) { state = Display.STATE_ON; } if (state == Display.STATE_OFF) { - brightness = PowerManager.BRIGHTNESS_OFF; - } else if (brightness < 0) { - brightness = PowerManager.BRIGHTNESS_DEFAULT; - } else if (brightness > PowerManager.BRIGHTNESS_ON) { - brightness = PowerManager.BRIGHTNESS_ON; + brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT; + } else if (brightnessState < PowerManager.BRIGHTNESS_MIN || Float.isNaN(brightnessState)) { + brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT; + } else if (brightnessState > PowerManager.BRIGHTNESS_MAX) { + brightnessState = PowerManager.BRIGHTNESS_MAX; } synchronized (mTempDisplayStateWorkQueue) { @@ -558,15 +559,15 @@ public final class DisplayManagerService extends SystemService { // may happen as a side-effect of displays changing state. synchronized (mSyncRoot) { if (mGlobalDisplayState == state - && mGlobalDisplayBrightness == brightness) { + && mGlobalDisplayBrightness == brightnessState) { return; // no change } Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState(" + Display.stateToString(state) - + ", brightness=" + brightness + ")"); + + ", brightness=" + brightnessState + ")"); mGlobalDisplayState = state; - mGlobalDisplayBrightness = brightness; + mGlobalDisplayBrightness = brightnessState; applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); } @@ -1023,7 +1024,8 @@ public final class DisplayManagerService extends SystemService { // by the display power controller (if known). DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { - return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); + return device.requestDisplayStateLocked( + mGlobalDisplayState, mGlobalDisplayBrightness); } return null; } @@ -2300,7 +2302,7 @@ public final class DisplayManagerService extends SystemService { } @Override // Binder call - public void setTemporaryBrightness(int brightness) { + public void setTemporaryBrightness(float brightness) { mContext.enforceCallingOrSelfPermission( Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, "Permission required to set the display's brightness"); @@ -2419,7 +2421,7 @@ public final class DisplayManagerService extends SystemService { synchronized (mSyncRoot) { DisplayBlanker blanker = new DisplayBlanker() { @Override - public void requestDisplayState(int state, int brightness) { + public void requestDisplayState(int state, float brightness) { // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java index e87ad410f9a2..0c6c797b917a 100644 --- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java +++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java @@ -108,8 +108,8 @@ class DisplayManagerShellCommand extends ShellCommand { "Permission required to set the display's brightness"); final long token = Binder.clearCallingIdentity(); try { - Settings.System.putIntForUser(context.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, (int) (brightness * 255), + Settings.System.putFloatForUser(context.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightness, UserHandle.USER_CURRENT); } finally { Binder.restoreCallingIdentity(token); diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 96532f4a21ac..8bbeabf779d2 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -946,9 +946,9 @@ public class DisplayModeDirector { * {@link R.array#config_ambientThresholdsOfPeakRefreshRate}. */ private class BrightnessObserver extends ContentObserver { + // TODO: brightnessfloat: change this to the float setting private final Uri mDisplayBrightnessSetting = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); - private final static int LIGHT_SENSOR_RATE_MS = 250; private int[] mDisplayBrightnessThresholds; private int[] mAmbientBrightnessThresholds; @@ -1174,7 +1174,7 @@ public class DisplayModeDirector { return false; } - + // TODO: brightnessfloat: make it use float not int private void onBrightnessChangedLocked() { int brightness = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, -1); diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index f1655f0ed6e3..197842ed1c2d 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -51,6 +51,7 @@ import android.util.Slog; import android.util.TimeUtils; import android.view.Display; +import com.android.internal.BrightnessSynchronizer; import com.android.internal.app.IBatteryStats; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -102,7 +103,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final boolean USE_COLOR_FADE_ON_ANIMATION = false; // The minimum reduction in brightness when dimmed. - private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10; + private static final float SCREEN_DIM_MINIMUM_REDUCTION_FLOAT = 0.04f; + private static final float SCREEN_ANIMATION_RATE_MINIMUM = 0.0f; private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250; private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400; @@ -169,28 +171,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private Sensor mProximitySensor; // The doze screen brightness. - private final int mScreenBrightnessDozeConfig; + private final float mScreenBrightnessDozeConfig; // The dim screen brightness. - private final int mScreenBrightnessDimConfig; + private final float mScreenBrightnessDimConfig; // The minimum allowed brightness. - private final int mScreenBrightnessRangeMinimum; + private final float mScreenBrightnessRangeMinimum; // The maximum allowed brightness. - private final int mScreenBrightnessRangeMaximum; + private final float mScreenBrightnessRangeMaximum; - // The default screen brightness. - private final int mScreenBrightnessDefault; + private final float mScreenBrightnessDefault; // The minimum allowed brightness while in VR. - private final int mScreenBrightnessForVrRangeMinimum; + private final float mScreenBrightnessForVrRangeMinimum; // The maximum allowed brightness while in VR. - private final int mScreenBrightnessForVrRangeMaximum; + private final float mScreenBrightnessForVrRangeMaximum; // The default screen brightness for VR. - private final int mScreenBrightnessForVrDefault; + private final float mScreenBrightnessForVrDefault; // True if auto-brightness should be used. private boolean mUseSoftwareAutoBrightnessConfig; @@ -317,8 +318,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private BrightnessReason mBrightnessReasonTemp = new BrightnessReason(); // Brightness animation ramp rates in brightness units per second - private final int mBrightnessRampRateFast; - private final int mBrightnessRampRateSlow; + private final float mBrightnessRampRateSlow = 0.2352941f; + private final float mBrightnessRampRateFast = 0.7058823f; + // Whether or not to skip the initial brightness ramps into STATE_ON. private final boolean mSkipScreenOnBrightnessRamp; @@ -333,7 +335,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private int mSkipRampState = RAMP_STATE_SKIP_NONE; // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL. - private int mInitialAutoBrightness; + private float mInitialAutoBrightness; // The controller for the automatic brightness level. private AutomaticBrightnessController mAutomaticBrightnessController; @@ -348,24 +350,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // The last brightness that was set by the user and not temporary. Set to -1 when a brightness // has yet to be recorded. - private int mLastUserSetScreenBrightness; + private float mLastUserSetScreenBrightness; // The screen brightenss setting has changed but not taken effect yet. If this is different // from the current screen brightness setting then this is coming from something other than us // and should be considered a user interaction. - private int mPendingScreenBrightnessSetting; + private float mPendingScreenBrightnessSetting; // The last observed screen brightness setting, either set by us or by the settings app on // behalf of the user. - private int mCurrentScreenBrightnessSetting; + private float mCurrentScreenBrightnessSetting; // The temporary screen brightness. Typically set when a user is interacting with the - // brightness slider but hasn't settled on a choice yet. Set to -1 when there's no temporary - // brightness set. - private int mTemporaryScreenBrightness; + // brightness slider but hasn't settled on a choice yet. Set to + // PowerManager.BRIGHNTESS_INVALID_FLOAT when there's no temporary brightness set. + private float mTemporaryScreenBrightness; // The current screen brightness while in VR mode. - private int mScreenBrightnessForVr; + private float mScreenBrightnessForVr; // The last auto brightness adjustment that was set by the user and not temporary. Set to // Float.NaN when an auto-brightness adjustment hasn't been recorded yet. @@ -384,6 +386,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private ObjectAnimator mColorFadeOffAnimator; private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; + private BrightnessSynchronizer mBrightnessSynchronizer; + /** * Creates the display power controller. */ @@ -394,37 +398,39 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessTracker = new BrightnessTracker(context, null); mSettingsObserver = new SettingsObserver(mHandler); mCallbacks = callbacks; - + mBrightnessSynchronizer = new BrightnessSynchronizer(context); mBatteryStats = BatteryStatsService.getService(); mSensorManager = sensorManager; mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class); mBlanker = blanker; mContext = context; + PowerManager pm = context.getSystemService(PowerManager.class); final Resources resources = context.getResources(); - final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessSettingMinimum)); + final float screenBrightnessSettingMinimumFloat = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM)); - mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessDoze)); - - mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessDim)); + // DOZE AND DIM SETTINGS + mScreenBrightnessDozeConfig = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)); + mScreenBrightnessDimConfig = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DIM)); + // NORMAL SCREEN SETTINGS mScreenBrightnessRangeMinimum = - Math.min(screenBrightnessSettingMinimum, mScreenBrightnessDimConfig); - - mScreenBrightnessRangeMaximum = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessSettingMaximum)); - mScreenBrightnessDefault = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessSettingDefault)); - - mScreenBrightnessForVrRangeMinimum = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessForVrSettingMinimum)); - mScreenBrightnessForVrRangeMaximum = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessForVrSettingMaximum)); - mScreenBrightnessForVrDefault = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessForVrSettingDefault)); + Math.min(screenBrightnessSettingMinimumFloat, mScreenBrightnessDimConfig); + mScreenBrightnessRangeMaximum = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM)); + mScreenBrightnessDefault = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT)); + + // VR SETTINGS + mScreenBrightnessForVrDefault = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT_VR)); + mScreenBrightnessForVrRangeMaximum = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR)); + mScreenBrightnessForVrRangeMinimum = clampAbsoluteBrightness( + pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR)); mUseSoftwareAutoBrightnessConfig = resources.getBoolean( com.android.internal.R.bool.config_automatic_brightness_available); @@ -432,10 +438,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean( com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing); - mBrightnessRampRateFast = resources.getInteger( - com.android.internal.R.integer.config_brightness_ramp_rate_fast); - mBrightnessRampRateSlow = resources.getInteger( - com.android.internal.R.integer.config_brightness_ramp_rate_slow); mSkipScreenOnBrightnessRamp = resources.getBoolean( com.android.internal.R.bool.config_skipScreenOnBrightnessRamp); @@ -496,7 +498,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds, - screenBrightnessThresholds, context.getPackageManager()); + screenBrightnessThresholds, context); } else { mUseSoftwareAutoBrightnessConfig = false; } @@ -519,14 +521,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call TYPICAL_PROXIMITY_THRESHOLD); } } - mCurrentScreenBrightnessSetting = getScreenBrightnessSetting(); mScreenBrightnessForVr = getScreenBrightnessForVrSetting(); mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); - mTemporaryScreenBrightness = -1; - mPendingScreenBrightnessSetting = -1; - mTemporaryAutoBrightnessAdjustment = Float.NaN; - mPendingAutoBrightnessAdjustment = Float.NaN; + mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; DisplayWhiteBalanceSettings displayWhiteBalanceSettings = null; DisplayWhiteBalanceController displayWhiteBalanceController = null; @@ -681,28 +682,28 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( - mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); + mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT); mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); // Initialize screen state for battery stats. try { mBatteryStats.noteScreenState(mPowerState.getScreenState()); - mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness()); + mBatteryStats.noteScreenBrightness(BrightnessSynchronizer.brightnessFloatToInt(mContext, + mPowerState.getScreenBrightness())); } catch (RemoteException ex) { // same process } - // Initialize all of the brightness tracking state - final float brightness = convertToNits(mPowerState.getScreenBrightness()); + final float brightness = convertToNits(BrightnessSynchronizer.brightnessFloatToInt(mContext, + mPowerState.getScreenBrightness())); if (brightness >= 0.0f) { mBrightnessTracker.start(brightness); } - mContext.getContentResolver().registerContentObserver( - Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT), false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver( - Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR), + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT), false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ), @@ -776,8 +777,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Compute the basic display state using the policy. // We might override this below based on other factors. + // Initialise brightness as invalid. int state; - int brightness = PowerManager.BRIGHTNESS_DEFAULT; + float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT; boolean performScreenOffTransition = false; switch (mPowerRequest.policy) { case DisplayPowerRequest.POLICY_OFF: @@ -791,7 +793,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call state = Display.STATE_DOZE; } if (!mAllowAutoBrightnessWhileDozingConfig) { - brightness = mPowerRequest.dozeScreenBrightness; + brightnessState = mPowerRequest.dozeScreenBrightness; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE); } break; @@ -843,20 +845,20 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call animateScreenStateChange(state, performScreenOffTransition); state = mPowerState.getScreenState(); - // Use zero brightness when screen is off. if (state == Display.STATE_OFF) { - brightness = PowerManager.BRIGHTNESS_OFF; + brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF); } // Always use the VR brightness when in the VR state. if (state == Display.STATE_VR) { - brightness = mScreenBrightnessForVr; + brightnessState = mScreenBrightnessForVr; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR); } - if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) { - brightness = mPowerRequest.screenBrightnessOverride; + if ((Float.isNaN(brightnessState)) + && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) { + brightnessState = mPowerRequest.screenBrightnessOverride; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE); mAppliedScreenBrightnessOverride = true; } else { @@ -867,15 +869,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state); final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) - && brightness < 0 + && Float.isNaN(brightnessState) && mAutomaticBrightnessController != null; final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); // Use the temporary screen brightness if there isn't an override, either from // WindowManager or based on the display state. - if (mTemporaryScreenBrightness > 0) { - brightness = mTemporaryScreenBrightness; + if (isValidBrightnessValue(mTemporaryScreenBrightness)) { + brightnessState = mTemporaryScreenBrightness; mAppliedTemporaryBrightness = true; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY); } else { @@ -898,14 +900,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO; mAppliedTemporaryAutoBrightnessAdjustment = false; } - // Apply brightness boost. // We do this here after deciding whether auto-brightness is enabled so that we don't // disable the light sensor during this temporary state. That way when boost ends we will // be able to resume normal auto-brightness behavior without any delay. if (mPowerRequest.boostScreenBrightness - && brightness != PowerManager.BRIGHTNESS_OFF) { - brightness = PowerManager.BRIGHTNESS_ON; + && brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT) { + brightnessState = PowerManager.BRIGHTNESS_MAX; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST); mAppliedBrightnessBoost = true; } else { @@ -914,16 +915,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // If the brightness is already set then it's been overridden by something other than the // user, or is a temporary adjustment. - boolean userInitiatedChange = brightness < 0 + boolean userInitiatedChange = (Float.isNaN(brightnessState)) && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged); - boolean hadUserBrightnessPoint = false; // Configure auto-brightness. if (mAutomaticBrightnessController != null) { hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints(); mAutomaticBrightnessController.configure(autoBrightnessEnabled, mBrightnessConfiguration, - mLastUserSetScreenBrightness / (float) PowerManager.BRIGHTNESS_ON, + mLastUserSetScreenBrightness, userSetBrightnessChanged, autoBrightnessAdjustment, autoBrightnessAdjustmentChanged, mPowerRequest.policy); } @@ -934,17 +934,18 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Apply auto-brightness. boolean slowChange = false; - if (brightness < 0) { + if (Float.isNaN(brightnessState)) { float newAutoBrightnessAdjustment = autoBrightnessAdjustment; if (autoBrightnessEnabled) { - brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness(); + brightnessState = BrightnessSynchronizer.brightnessIntToFloat( + mContext, mAutomaticBrightnessController.getAutomaticScreenBrightness()); newAutoBrightnessAdjustment = mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); } - - if (brightness >= 0) { + if (isValidBrightnessValue(brightnessState) + || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) { // Use current auto-brightness value and slowly adjust to changes. - brightness = clampScreenBrightness(brightness); + brightnessState = clampScreenBrightness(brightnessState); if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { slowChange = true; // slowly adapt to auto-brightness } @@ -952,7 +953,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(brightness); + putScreenBrightnessSetting(brightnessState); mAppliedAutoBrightness = true; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); } else { @@ -970,24 +971,25 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAppliedAutoBrightness = false; brightnessAdjustmentFlags = 0; } - // Use default brightness when dozing unless overridden. - if (brightness < 0 && Display.isDozeState(state)) { - brightness = mScreenBrightnessDozeConfig; + if ((Float.isNaN(brightnessState)) + && Display.isDozeState(state)) { + brightnessState = mScreenBrightnessDozeConfig; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT); } // Apply manual brightness. - if (brightness < 0) { - brightness = clampScreenBrightness(mCurrentScreenBrightnessSetting); + if (Float.isNaN(brightnessState)) { + brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting); mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL); } // Apply dimming by at least some minimum amount when user activity // timeout is about to expire. if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) { - if (brightness > mScreenBrightnessRangeMinimum) { - brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION, + if (brightnessState > mScreenBrightnessRangeMinimum) { + brightnessState = Math.max(Math.min(brightnessState + - SCREEN_DIM_MINIMUM_REDUCTION_FLOAT, mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum); mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED); } @@ -999,15 +1001,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call slowChange = false; mAppliedDimming = false; } - // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor // as long as it is above the minimum threshold. if (mPowerRequest.lowPowerMode) { - if (brightness > mScreenBrightnessRangeMinimum) { + if (brightnessState > mScreenBrightnessRangeMinimum) { final float brightnessFactor = Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1); - final int lowPowerBrightness = (int) (brightness * brightnessFactor); - brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum); + final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor); + brightnessState = Math.max(lowPowerBrightnessFloat, + mScreenBrightnessRangeMinimum); mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER); } if (!mAppliedLowPower) { @@ -1025,11 +1027,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mSkipScreenOnBrightnessRamp) { if (state == Display.STATE_ON) { if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) { - mInitialAutoBrightness = brightness; + mInitialAutoBrightness = brightnessState; mSkipRampState = RAMP_STATE_SKIP_INITIAL; } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL && mUseSoftwareAutoBrightnessConfig - && brightness != mInitialAutoBrightness) { + && !BrightnessSynchronizer.floatEquals(brightnessState, + mInitialAutoBrightness)) { mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT; } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) { mSkipRampState = RAMP_STATE_SKIP_NONE; @@ -1056,9 +1059,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment; if (initialRampSkip || hasBrightnessBuckets || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) { - animateScreenBrightness(brightness, 0); + animateScreenBrightness(brightnessState, SCREEN_ANIMATION_RATE_MINIMUM); } else { - animateScreenBrightness(brightness, + animateScreenBrightness(brightnessState, slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast); } @@ -1069,14 +1072,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // slider event so notify as if the system changed the brightness. userInitiatedChange = false; } - notifyBrightnessChanged(brightness, userInitiatedChange, hadUserBrightnessPoint); + notifyBrightnessChanged( + BrightnessSynchronizer.brightnessFloatToInt(mContext, brightnessState), + userInitiatedChange, hadUserBrightnessPoint); } } // Log any changes to what is currently driving the brightness setting. if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) { - Slog.v(TAG, "Brightness [" + brightness + "] reason changing to: '" + Slog.v(TAG, "Brightness [" + brightnessState + "] reason changing to: '" + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags) + "', previous reason: '" + mBrightnessReason + "'."); mBrightnessReason.set(mBrightnessReasonTemp); @@ -1161,9 +1166,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call msg.sendToTarget(); } - public void setTemporaryBrightness(int brightness) { + public void setTemporaryBrightness(float brightness) { Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS, - brightness, 0 /*unused*/); + Float.floatToIntBits(brightness), 0 /*unused*/); msg.sendToTarget(); } @@ -1282,24 +1287,38 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mReportedScreenStateToPolicy = state; } - private int clampScreenBrightnessForVr(int value) { + private float clampScreenBrightnessForVr(float value) { return MathUtils.constrain( - value, mScreenBrightnessForVrRangeMinimum, mScreenBrightnessForVrRangeMaximum); + value, mScreenBrightnessForVrRangeMinimum, + mScreenBrightnessForVrRangeMaximum); } - private int clampScreenBrightness(int value) { + private float clampScreenBrightness(float value) { + if (Float.isNaN(value)) { + return mScreenBrightnessRangeMinimum; + } return MathUtils.constrain( value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); } - private void animateScreenBrightness(int target, int rate) { + // Checks whether the brightness is within the valid brightness range, not including the off or + // invalid states. + private boolean isValidBrightnessValue(float brightnessState) { + return brightnessState >= mScreenBrightnessRangeMinimum + && brightnessState <= mScreenBrightnessRangeMaximum; + } + + private void animateScreenBrightness(float target, float rate) { if (DEBUG) { Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate); } if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { - Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", target); + Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target); try { - mBatteryStats.noteScreenBrightness(target); + // TODO(brightnessfloat): change BatteryStats to use float + mBatteryStats.noteScreenBrightness( + BrightnessSynchronizer.brightnessFloatToInt( + mContext, target)); } catch (RemoteException ex) { // same process } @@ -1578,6 +1597,7 @@ 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; @@ -1598,24 +1618,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj); } - private int getScreenBrightnessSetting() { - final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessDefault, + private float getScreenBrightnessSetting() { + final float brightness = Settings.System.getFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, mScreenBrightnessDefault, UserHandle.USER_CURRENT); return clampAbsoluteBrightness(brightness); } - private int getScreenBrightnessForVrSetting() { - final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS_FOR_VR, mScreenBrightnessForVrDefault, + private float getScreenBrightnessForVrSetting() { + final float brightnessFloat = Settings.System.getFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, mScreenBrightnessForVrDefault, UserHandle.USER_CURRENT); - return clampScreenBrightnessForVr(brightness); + return clampScreenBrightnessForVr(brightnessFloat); } - private void putScreenBrightnessSetting(int brightness) { - mCurrentScreenBrightnessSetting = brightness; - Settings.System.putIntForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT); + private void putScreenBrightnessSetting(float brightnessValue) { + mCurrentScreenBrightnessSetting = brightnessValue; + Settings.System.putFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessValue, UserHandle.USER_CURRENT); } private void putAutoBrightnessAdjustmentSetting(float adjustment) { @@ -1638,18 +1658,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private boolean updateUserSetScreenBrightness() { - if (mPendingScreenBrightnessSetting < 0) { + if ((Float.isNaN(mPendingScreenBrightnessSetting) + || mPendingScreenBrightnessSetting < 0.0f)) { return false; } if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) { - mPendingScreenBrightnessSetting = -1; - mTemporaryScreenBrightness = -1; + mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; return false; } mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting; mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting; - mPendingScreenBrightnessSetting = -1; - mTemporaryScreenBrightness = -1; + mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; return true; } @@ -1728,8 +1749,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println("Display Power Controller Configuration:"); pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); - pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); - pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); pw.println(" mScreenBrightnessDefault=" + mScreenBrightnessDefault); pw.println(" mScreenBrightnessForVrRangeMinimum=" + mScreenBrightnessForVrRangeMinimum); pw.println(" mScreenBrightnessForVrRangeMaximum=" + mScreenBrightnessForVrRangeMaximum); @@ -1737,8 +1756,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig); pw.println(" mAllowAutoBrightnessWhileDozingConfig=" + mAllowAutoBrightnessWhileDozingConfig); - pw.println(" mBrightnessRampRateFast=" + mBrightnessRampRateFast); - pw.println(" mBrightnessRampRateSlow=" + mBrightnessRampRateSlow); pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp); pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig); pw.println(" mColorFadeEnabled=" + mColorFadeEnabled); @@ -1767,15 +1784,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mPendingProximityDebounceTime=" + TimeUtils.formatUptime(mPendingProximityDebounceTime)); pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity); - pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness); - pw.println(" mCurrentScreenBrightnessSetting=" + mCurrentScreenBrightnessSetting); - pw.println(" mPendingScreenBrightnessSetting=" + mPendingScreenBrightnessSetting); - pw.println(" mTemporaryScreenBrightness=" + mTemporaryScreenBrightness); + pw.println(" mLastUserSetScreenBrightnessFloat=" + mLastUserSetScreenBrightness); + pw.println(" mPendingScreenBrightnessSettingFloat=" + + mPendingScreenBrightnessSetting); + pw.println(" mTemporaryScreenBrightnessFloat=" + mTemporaryScreenBrightness); pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); pw.println(" mBrightnessReason=" + mBrightnessReason); pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment); pw.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment); - pw.println(" mScreenBrightnessForVr=" + mScreenBrightnessForVr); + pw.println(" mScreenBrightnessForVrFloat=" + mScreenBrightnessForVr); pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness); pw.println(" mAppliedDimming=" + mAppliedDimming); pw.println(" mAppliedLowPower=" + mAppliedLowPower); @@ -1783,7 +1800,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness); pw.println(" mDozing=" + mDozing); pw.println(" mSkipRampState=" + skipRampStateToString(mSkipRampState)); - pw.println(" mInitialAutoBrightness=" + mInitialAutoBrightness); pw.println(" mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime); pw.println(" mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime); pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker); @@ -1869,6 +1885,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); } + private static float clampAbsoluteBrightness(float value) { + return MathUtils.constrain(value, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX); + } + private static float clampAutoBrightnessAdjustment(float value) { return MathUtils.constrain(value, -1.0f, 1.0f); } @@ -1908,7 +1929,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call case MSG_SET_TEMPORARY_BRIGHTNESS: // TODO: Should we have a a timeout for the temporary brightness? - mTemporaryScreenBrightness = msg.arg1; + mTemporaryScreenBrightness = Float.intBitsToFloat(msg.arg1); updatePowerState(); break; diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java index 763f56ff918f..24e1b4edc8a6 100644 --- a/services/core/java/com/android/server/display/DisplayPowerState.java +++ b/services/core/java/com/android/server/display/DisplayPowerState.java @@ -22,11 +22,12 @@ import android.os.Looper; import android.os.PowerManager; import android.os.Trace; import android.util.FloatProperty; -import android.util.IntProperty; import android.util.Slog; import android.view.Choreographer; import android.view.Display; +import com.android.internal.BrightnessSynchronizer; + import java.io.PrintWriter; /** @@ -59,7 +60,7 @@ final class DisplayPowerState { private final PhotonicModulator mPhotonicModulator; private int mScreenState; - private int mScreenBrightness; + private float mScreenBrightness; private boolean mScreenReady; private boolean mScreenUpdatePending; @@ -85,7 +86,7 @@ final class DisplayPowerState { // will reset the brightness to a new level immediately before the changes // actually have a chance to be applied. mScreenState = Display.STATE_ON; - mScreenBrightness = PowerManager.BRIGHTNESS_ON; + mScreenBrightness = PowerManager.BRIGHTNESS_MAX; scheduleScreenUpdate(); mColorFadePrepared = false; @@ -106,18 +107,19 @@ final class DisplayPowerState { } }; - public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS = - new IntProperty<DisplayPowerState>("screenBrightness") { - @Override - public void setValue(DisplayPowerState object, int value) { - object.setScreenBrightness(value); - } - @Override - public Integer get(DisplayPowerState object) { - return object.getScreenBrightness(); - } - }; + public static final FloatProperty<DisplayPowerState> SCREEN_BRIGHTNESS_FLOAT = + new FloatProperty<DisplayPowerState>("screenBrightnessFloat") { + @Override + public void setValue(DisplayPowerState object, float value) { + object.setScreenBrightness(value); + } + + @Override + public Float get(DisplayPowerState object) { + return object.getScreenBrightness(); + } + }; /** * Sets whether the screen is on, off, or dozing. @@ -146,7 +148,7 @@ final class DisplayPowerState { * * @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest). */ - public void setScreenBrightness(int brightness) { + public void setScreenBrightness(float brightness) { if (mScreenBrightness != brightness) { if (DEBUG) { Slog.d(TAG, "setScreenBrightness: brightness=" + brightness); @@ -163,7 +165,7 @@ final class DisplayPowerState { /** * Gets the screen brightness. */ - public int getScreenBrightness() { + public float getScreenBrightness() { return mScreenBrightness; } @@ -308,9 +310,9 @@ final class DisplayPowerState { public void run() { mScreenUpdatePending = false; - int brightness = mScreenState != Display.STATE_OFF - && mColorFadeLevel > 0f ? mScreenBrightness : 0; - if (mPhotonicModulator.setState(mScreenState, brightness)) { + float brightnessState = mScreenState != Display.STATE_OFF + && mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT; + if (mPhotonicModulator.setState(mScreenState, brightnessState)) { if (DEBUG) { Slog.d(TAG, "Screen ready"); } @@ -345,14 +347,14 @@ final class DisplayPowerState { */ private final class PhotonicModulator extends Thread { private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off - private static final int INITIAL_BACKLIGHT = -1; // unknown + private static final float INITIAL_BACKLIGHT_FLOAT = PowerManager.BRIGHTNESS_INVALID_FLOAT; private final Object mLock = new Object(); private int mPendingState = INITIAL_SCREEN_STATE; - private int mPendingBacklight = INITIAL_BACKLIGHT; + private float mPendingBacklight = INITIAL_BACKLIGHT_FLOAT; private int mActualState = INITIAL_SCREEN_STATE; - private int mActualBacklight = INITIAL_BACKLIGHT; + private float mActualBacklight = INITIAL_BACKLIGHT_FLOAT; private boolean mStateChangeInProgress; private boolean mBacklightChangeInProgress; @@ -360,19 +362,19 @@ final class DisplayPowerState { super("PhotonicModulator"); } - public boolean setState(int state, int backlight) { + public boolean setState(int state, float brightnessState) { synchronized (mLock) { boolean stateChanged = state != mPendingState; - boolean backlightChanged = backlight != mPendingBacklight; + boolean backlightChanged = !BrightnessSynchronizer.floatEquals( + brightnessState, mPendingBacklight); if (stateChanged || backlightChanged) { if (DEBUG) { Slog.d(TAG, "Requesting new screen state: state=" - + Display.stateToString(state) + ", backlight=" + backlight); + + Display.stateToString(state) + ", backlight=" + brightnessState); } mPendingState = state; - mPendingBacklight = backlight; - + mPendingBacklight = brightnessState; boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress; mStateChangeInProgress = stateChanged || mStateChangeInProgress; mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress; @@ -404,13 +406,14 @@ final class DisplayPowerState { // Get pending change. final int state; final boolean stateChanged; - final int backlight; + final float brightnessState; final boolean backlightChanged; synchronized (mLock) { state = mPendingState; stateChanged = (state != mActualState); - backlight = mPendingBacklight; - backlightChanged = (backlight != mActualBacklight); + brightnessState = mPendingBacklight; + backlightChanged = !BrightnessSynchronizer.floatEquals( + brightnessState, mActualBacklight); if (!stateChanged) { // State changed applied, notify outer class. postScreenUpdateThreadSafe(); @@ -426,15 +429,15 @@ final class DisplayPowerState { continue; } mActualState = state; - mActualBacklight = backlight; + mActualBacklight = brightnessState; } // Apply pending change. if (DEBUG) { Slog.d(TAG, "Updating screen state: state=" - + Display.stateToString(state) + ", backlight=" + backlight); + + Display.stateToString(state) + ", backlight=" + brightnessState); } - mBlanker.requestDisplayState(state, backlight); + mBlanker.requestDisplayState(state, brightnessState); } } } diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index fc9542a33a78..2b225e5f3ec6 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -38,6 +38,7 @@ import android.view.DisplayEventReceiver; import android.view.Surface; import android.view.SurfaceControl; +import com.android.internal.BrightnessSynchronizer; import com.android.internal.os.BackgroundThread; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; @@ -179,7 +180,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { private DisplayDeviceInfo mInfo; private boolean mHavePendingChanges; private int mState = Display.STATE_UNKNOWN; - private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT; + private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT; private int mDefaultModeId; private int mActiveModeId; private boolean mActiveModeInvalid; @@ -574,12 +575,14 @@ final class LocalDisplayAdapter extends DisplayAdapter { } @Override - public Runnable requestDisplayStateLocked(final int state, final int brightness) { + public Runnable requestDisplayStateLocked(final int state, final float brightnessState) { // Assume that the brightness is off if the display is being turned off. - assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF; - + assert state != Display.STATE_OFF || BrightnessSynchronizer.floatEquals( + brightnessState, PowerManager.BRIGHTNESS_OFF_FLOAT); final boolean stateChanged = (mState != state); - final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null; + final boolean brightnessChanged = (!BrightnessSynchronizer.floatEquals( + mBrightnessState, brightnessState)) + && mBacklight != null; if (stateChanged || brightnessChanged) { final long physicalDisplayId = mPhysicalDisplayId; final IBinder token = getDisplayTokenLocked(); @@ -591,7 +594,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { } if (brightnessChanged) { - mBrightness = brightness; + mBrightnessState = brightnessState; } // Defer actually setting the display state until after we have exited @@ -630,10 +633,9 @@ final class LocalDisplayAdapter extends DisplayAdapter { vrModeChange = true; } - // Apply brightness changes given that we are in a non-suspended state. if (brightnessChanged || vrModeChange) { - setDisplayBrightness(brightness); + setDisplayBrightness(brightnessState); } // Enter the final desired state, possibly suspended. @@ -694,7 +696,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } - private void setDisplayBrightness(int brightness) { + private void setDisplayBrightness(float brightness) { if (DEBUG) { Slog.d(TAG, "setDisplayBrightness(" + "id=" + physicalDisplayId @@ -704,26 +706,33 @@ final class LocalDisplayAdapter extends DisplayAdapter { Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness(" + "id=" + physicalDisplayId + ", brightness=" + brightness + ")"); try { - if (mHalBrightnessSupport) { - mBacklight.setBrightnessFloat( - displayBrightnessToHalBrightness(brightness)); - } else { - mBacklight.setBrightness(brightness); + // TODO: make it float + if (isHalBrightnessRangeSpecified()) { + brightness = displayBrightnessToHalBrightness( + BrightnessSynchronizer.brightnessFloatToInt(getContext(), + brightness)); } + mBacklight.setBrightness(brightness); Trace.traceCounter(Trace.TRACE_TAG_POWER, - "ScreenBrightness", brightness); + "ScreenBrightness", + BrightnessSynchronizer.brightnessFloatToInt( + getContext(), brightness)); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } + private boolean isHalBrightnessRangeSpecified() { + return !(mSystemBrightnessToNits == null || mNitsToHalBrightness == null); + } + /** * Converts brightness range from the framework's brightness space to the * Hal brightness space if the HAL brightness space has been provided via * a display device configuration file. */ private float displayBrightnessToHalBrightness(int brightness) { - if (mSystemBrightnessToNits == null || mNitsToHalBrightness == null) { + if (!isHalBrightnessRangeSpecified()) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } @@ -887,7 +896,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { pw.println("mActiveColorMode=" + mActiveColorMode); pw.println("mDefaultModeId=" + mDefaultModeId); pw.println("mState=" + Display.stateToString(mState)); - pw.println("mBrightness=" + mBrightness); + pw.println("mBrightnessState=" + mBrightnessState); pw.println("mBacklight=" + mBacklight); pw.println("mAllmSupported=" + mAllmSupported); pw.println("mAllmRequested=" + mAllmRequested); diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java index d71269f9eaeb..7916d816dc9b 100644 --- a/services/core/java/com/android/server/display/RampAnimator.java +++ b/services/core/java/com/android/server/display/RampAnimator.java @@ -17,21 +17,23 @@ package com.android.server.display; import android.animation.ValueAnimator; -import android.util.IntProperty; +import android.util.FloatProperty; import android.view.Choreographer; +import com.android.internal.BrightnessSynchronizer; + /** * A custom animator that progressively updates a property value at * a given variable rate until it reaches a particular target value. */ final class RampAnimator<T> { private final T mObject; - private final IntProperty<T> mProperty; + private final FloatProperty<T> mProperty; private final Choreographer mChoreographer; - private int mCurrentValue; - private int mTargetValue; - private int mRate; + private float mCurrentValue; + private float mTargetValue; + private float mRate; private boolean mAnimating; private float mAnimatedValue; // higher precision copy of mCurrentValue @@ -41,7 +43,7 @@ final class RampAnimator<T> { private Listener mListener; - public RampAnimator(T object, IntProperty<T> property) { + public RampAnimator(T object, FloatProperty<T> property) { mObject = object; mProperty = property; mChoreographer = Choreographer.getInstance(); @@ -57,7 +59,8 @@ final class RampAnimator<T> { * @param rate The convergence rate in units per second, or 0 to set the value immediately. * @return True if the target differs from the previous target. */ - public boolean animateTo(int target, int rate) { + public boolean animateTo(float target, float rate) { + // Immediately jump to the target the first time. if (mFirstTime || rate <= 0) { if (mFirstTime || target != mCurrentValue) { @@ -152,14 +155,12 @@ final class RampAnimator<T> { mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); } } - final int oldCurrentValue = mCurrentValue; - mCurrentValue = Math.round(mAnimatedValue); - - if (oldCurrentValue != mCurrentValue) { + final float oldCurrentValue = mCurrentValue; + mCurrentValue = mAnimatedValue; + if (!BrightnessSynchronizer.floatEquals(oldCurrentValue, mCurrentValue)) { mProperty.setValue(mObject, mCurrentValue); } - - if (mTargetValue != mCurrentValue) { + if (!BrightnessSynchronizer.floatEquals(mTargetValue, mCurrentValue)) { postAnimationCallback(); } else { mAnimating = false; diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 1ca8dd3af4e2..f4f2eadfaa8e 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -265,7 +265,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter { } @Override - public Runnable requestDisplayStateLocked(int state, int brightness) { + public Runnable requestDisplayStateLocked(int state, float brightnessState) { if (state != mDisplayState) { mDisplayState = state; if (state == Display.STATE_OFF) { diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java index 5683e6901a31..a42dec8b575f 100644 --- a/services/core/java/com/android/server/lights/LightsService.java +++ b/services/core/java/com/android/server/lights/LightsService.java @@ -40,6 +40,7 @@ import android.view.SurfaceControl; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; +import com.android.internal.BrightnessSynchronizer; import com.android.server.SystemService; import java.util.ArrayList; @@ -249,28 +250,21 @@ public class LightsService extends SystemService { } @Override - public void setBrightnessFloat(float brightness) { - if (!Float.isNaN(brightness)) { - setBrightness(brightness, 0, BRIGHTNESS_MODE_USER); - } - } - - @Override - public void setBrightness(int brightness) { + public void setBrightness(float brightness) { setBrightness(brightness, BRIGHTNESS_MODE_USER); } @Override - public void setBrightness(int brightness, int brightnessMode) { - setBrightness(Float.NaN, brightness, brightnessMode); - } - - private void setBrightness(float brightnessFloat, int brightness, int brightnessMode) { + public void setBrightness(float brightness, int brightnessMode) { + if (Float.isNaN(brightness)) { + Slog.w(TAG, "Brightness is not valid: " + brightness); + return; + } synchronized (this) { // LOW_PERSISTENCE cannot be manually set if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) { Slog.w(TAG, "setBrightness with LOW_PERSISTENCE unexpected #" + mHwLight.id - + ": brightness=0x" + Integer.toHexString(brightness)); + + ": brightness=" + brightness); return; } // Ideally, we'd like to set the brightness mode through the SF/HWC as well, but @@ -278,6 +272,7 @@ public class LightsService extends SystemService { // anything but USER or the device shouldBeInLowPersistenceMode(). if (brightnessMode == BRIGHTNESS_MODE_USER && !shouldBeInLowPersistenceMode() && mSurfaceControlMaximumBrightness == 255) { + // New system // TODO: the last check should be mSurfaceControlMaximumBrightness != 0; the // reason we enforce 255 right now is to stay consistent with the old path. In // the future, the framework should be refactored so that brightness is a float @@ -286,17 +281,12 @@ public class LightsService extends SystemService { if (DEBUG) { Slog.d(TAG, "Using new setBrightness path!"); } - - if (!Float.isNaN(brightnessFloat)) { - SurfaceControl.setDisplayBrightness(mDisplayToken, brightnessFloat); - } else if (brightness == 0) { - SurfaceControl.setDisplayBrightness(mDisplayToken, -1.0f); - } else { - SurfaceControl.setDisplayBrightness(mDisplayToken, - (float) (brightness - 1) / (mSurfaceControlMaximumBrightness - 1)); - } + SurfaceControl.setDisplayBrightness(mDisplayToken, brightness); } else { - int color = brightness & 0x000000ff; + // Old system + int brightnessInt = BrightnessSynchronizer.brightnessFloatToInt( + getContext(), brightness); + int color = brightnessInt & 0x000000ff; color = 0xff000000 | (color << 16) | (color << 8) | color; setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); } diff --git a/services/core/java/com/android/server/lights/LogicalLight.java b/services/core/java/com/android/server/lights/LogicalLight.java index 33dfbb4eea48..7491cecaefe9 100644 --- a/services/core/java/com/android/server/lights/LogicalLight.java +++ b/services/core/java/com/android/server/lights/LogicalLight.java @@ -57,18 +57,12 @@ public abstract class LogicalLight { /** * Set the brightness of a display. */ - public abstract void setBrightness(int brightness); + public abstract void setBrightness(float brightness); /** * Set the brightness and mode of a display. */ - public abstract void setBrightness(int brightness, int brightnessMode); - - /** - * Set the brightness of a display using the brightness range defines in a - * display-device-configuration file. - */ - public abstract void setBrightnessFloat(float brightness); + public abstract void setBrightness(float brightness, int brightnessMode); /** * Set the color of a light. diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java index 91bd7aea067e..67b1008333e1 100644 --- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -783,6 +783,7 @@ public class UserRestrictionsUtils { break; case android.provider.Settings.System.SCREEN_BRIGHTNESS: + case android.provider.Settings.System.SCREEN_BRIGHTNESS_FLOAT: case android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE: if (callingUid == Process.SYSTEM_UID) { return false; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index ede04f3bbb14..61267878a409 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2729,21 +2729,23 @@ public class PhoneWindowManager implements WindowManagerPolicy { Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT_OR_SELF); } - - int min = mPowerManager.getMinimumScreenBrightnessSetting(); - int max = mPowerManager.getMaximumScreenBrightnessSetting(); - int step = (max - min + BRIGHTNESS_STEPS - 1) / BRIGHTNESS_STEPS * direction; - int brightness = Settings.System.getIntForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, - mPowerManager.getDefaultScreenBrightnessSetting(), + float minFloat = mPowerManager.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); + float maxFloat = 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, + mPowerManager.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT), UserHandle.USER_CURRENT_OR_SELF); - brightness += step; + brightnessFloat += stepFloat; // Make sure we don't go beyond the limits. - brightness = Math.min(max, brightness); - brightness = Math.max(min, brightness); + brightnessFloat = Math.min(maxFloat, brightnessFloat); + brightnessFloat = Math.max(minFloat, brightnessFloat); - Settings.System.putIntForUser(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, brightness, + Settings.System.putFloatForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessFloat, UserHandle.USER_CURRENT_OR_SELF); startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG), UserHandle.CURRENT_OR_SELF); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 4d13658c85b7..002ab9ccc57c 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -83,6 +83,7 @@ import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.view.Display; +import com.android.internal.BrightnessSynchronizer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; @@ -192,6 +193,9 @@ public final class PowerManagerService extends SystemService // This should perhaps be a setting. private static final int SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 5 * 1000; + // Float.NaN cannot be stored in config.xml so -2 is used instead + private static final float INVALID_BRIGHTNESS_IN_CONFIG = -2f; + // How long a partial wake lock must be held until we consider it a long wake lock. static final long MIN_LONG_WAKE_CHECK_INTERVAL = 60*1000; @@ -485,13 +489,17 @@ public final class PowerManagerService extends SystemService private boolean mProximityPositive; // Screen brightness setting limits. - private int mScreenBrightnessSettingMinimum; - private int mScreenBrightnessSettingMaximum; - private int mScreenBrightnessSettingDefault; - - // The screen brightness setting, from 0 to 255. - // Use -1 if no value has been set. - private int mScreenBrightnessSetting; + private float mScreenBrightnessSettingMinimum; + private float mScreenBrightnessSettingMaximum; + private float mScreenBrightnessSettingDefault; + public final float mScreenBrightnessMinimum; + public final float mScreenBrightnessMaximum; + public final float mScreenBrightnessDefault; + public final float mScreenBrightnessDoze; + public final float mScreenBrightnessDim; + public final float mScreenBrightnessMinimumVr; + public final float mScreenBrightnessMaximumVr; + public final float mScreenBrightnessDefaultVr; // The screen brightness mode. // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants. @@ -502,6 +510,9 @@ public final class PowerManagerService extends SystemService // Use -1 to disable. private int mScreenBrightnessOverrideFromWindowManager = -1; + private float mScreenBrightnessOverrideFromWindowManagerFloat = + PowerManager.BRIGHTNESS_INVALID_FLOAT; + // The window manager has determined the user to be inactive via other means. // Set this to false to disable. private boolean mUserInactiveOverrideFromWindowManager; @@ -521,6 +532,8 @@ public final class PowerManagerService extends SystemService // The screen brightness to use while dozing. private int mDozeScreenBrightnessOverrideFromDreamManager = PowerManager.BRIGHTNESS_DEFAULT; + private float mDozeScreenBrightnessOverrideFromDreamManagerFloat = + PowerManager.BRIGHTNESS_INVALID_FLOAT; // Keep display state when dozing. private boolean mDrawWakeLockOverrideFromSidekick; @@ -827,6 +840,91 @@ public final class PowerManagerService extends SystemService mInattentiveSleepWarningOverlayController = mInjector.createInattentiveSleepWarningController(); + // Save brightness values: + // Get float values from config. + // Store float if valid + // Otherwise, get int values and convert to float and then store. + final float min = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingMinimumFloat); + final float max = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingMaximumFloat); + final float def = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingDefaultFloat); + final float doze = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessDozeFloat); + final float dim = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessDimFloat); + + if (min == INVALID_BRIGHTNESS_IN_CONFIG || max == INVALID_BRIGHTNESS_IN_CONFIG + || def == INVALID_BRIGHTNESS_IN_CONFIG) { + mScreenBrightnessMinimum = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessSettingMinimum), + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); + mScreenBrightnessMaximum = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessSettingMaximum), + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); + mScreenBrightnessDefault = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessSettingDefault), + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); + } else { + mScreenBrightnessMinimum = min; + mScreenBrightnessMaximum = max; + mScreenBrightnessDefault = def; + } + if (doze == INVALID_BRIGHTNESS_IN_CONFIG) { + mScreenBrightnessDoze = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessDoze), PowerManager.BRIGHTNESS_OFF + 1, + PowerManager.BRIGHTNESS_ON, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX); + } else { + mScreenBrightnessDoze = doze; + } + if (dim == INVALID_BRIGHTNESS_IN_CONFIG) { + mScreenBrightnessDim = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessDim), PowerManager.BRIGHTNESS_OFF + 1, + PowerManager.BRIGHTNESS_ON, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX); + } else { + mScreenBrightnessDim = dim; + } + + final float vrMin = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingForVrMinimumFloat); + final float vrMax = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingForVrMaximumFloat); + final float vrDef = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingForVrDefaultFloat); + if (vrMin == INVALID_BRIGHTNESS_IN_CONFIG || vrMax == INVALID_BRIGHTNESS_IN_CONFIG + || vrDef == INVALID_BRIGHTNESS_IN_CONFIG) { + mScreenBrightnessMinimumVr = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessForVrSettingMinimum), + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); + mScreenBrightnessMaximumVr = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessForVrSettingMaximum), + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); + mScreenBrightnessDefaultVr = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessForVrSettingDefault), + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); + } else { + mScreenBrightnessMinimumVr = vrMin; + mScreenBrightnessMaximumVr = vrMax; + mScreenBrightnessDefaultVr = vrDef; + } + synchronized (mLock) { mWakeLockSuspendBlocker = mInjector.createSuspendBlocker(this, "PowerManagerService.WakeLocks"); @@ -895,9 +993,12 @@ public final class PowerManagerService extends SystemService mAttentionDetector.systemReady(mContext); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); - mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting(); - mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting(); + mScreenBrightnessSettingMinimum = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); + mScreenBrightnessSettingMaximum = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); + mScreenBrightnessSettingDefault = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT); SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); @@ -2672,7 +2773,7 @@ public final class PowerManagerService extends SystemService // Determine appropriate screen brightness and auto-brightness adjustments. final boolean autoBrightness; - final int screenBrightnessOverride; + final float screenBrightnessOverride; if (!mBootCompleted) { // Keep the brightness steady during boot. This requires the // bootloader brightness and the default brightness to be identical. @@ -2680,11 +2781,11 @@ public final class PowerManagerService extends SystemService screenBrightnessOverride = mScreenBrightnessSettingDefault; } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) { autoBrightness = false; - screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager; + screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManagerFloat; } else { autoBrightness = (mScreenBrightnessModeSetting == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); - screenBrightnessOverride = -1; + screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT; } // Update display power request. @@ -2707,10 +2808,11 @@ public final class PowerManagerService extends SystemService } } mDisplayPowerRequest.dozeScreenBrightness = - mDozeScreenBrightnessOverrideFromDreamManager; + mDozeScreenBrightnessOverrideFromDreamManagerFloat; } else { mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN; - mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; + mDisplayPowerRequest.dozeScreenBrightness = + PowerManager.BRIGHTNESS_INVALID_FLOAT; } mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, @@ -3426,10 +3528,13 @@ public final class PowerManagerService extends SystemService } } + // TODO(brightnessfloat): change to float private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) { synchronized (mLock) { if (mScreenBrightnessOverrideFromWindowManager != brightness) { mScreenBrightnessOverrideFromWindowManager = brightness; + mScreenBrightnessOverrideFromWindowManagerFloat = + BrightnessSynchronizer.brightnessIntToFloat(mContext, brightness); mDirty |= DIRTY_SETTINGS; updatePowerStateLocked(); } @@ -3462,6 +3567,9 @@ public final class PowerManagerService extends SystemService || mDozeScreenBrightnessOverrideFromDreamManager != screenBrightness) { mDozeScreenStateOverrideFromDreamManager = screenState; mDozeScreenBrightnessOverrideFromDreamManager = screenBrightness; + mDozeScreenBrightnessOverrideFromDreamManagerFloat = + BrightnessSynchronizer.brightnessIntToFloat(mContext, + mDozeScreenBrightnessOverrideFromDreamManager); mDirty |= DIRTY_SETTINGS; updatePowerStateLocked(); } @@ -3715,10 +3823,9 @@ public final class PowerManagerService extends SystemService + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced=" + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")"); pw.println(" mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting); - pw.println(" mScreenBrightnessSetting=" + mScreenBrightnessSetting); pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting); - pw.println(" mScreenBrightnessOverrideFromWindowManager=" - + mScreenBrightnessOverrideFromWindowManager); + pw.println(" mScreenBrightnessOverrideFromWindowManagerFloat=" + + mScreenBrightnessOverrideFromWindowManagerFloat); pw.println(" mUserActivityTimeoutOverrideFromWindowManager=" + mUserActivityTimeoutOverrideFromWindowManager); pw.println(" mUserInactiveOverrideFromWindowManager=" @@ -3728,9 +3835,9 @@ public final class PowerManagerService extends SystemService pw.println(" mDrawWakeLockOverrideFromSidekick=" + mDrawWakeLockOverrideFromSidekick); pw.println(" mDozeScreenBrightnessOverrideFromDreamManager=" + mDozeScreenBrightnessOverrideFromDreamManager); - pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum); - pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum); - pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault); + pw.println(" mScreenBrightnessSettingMinimumFloat=" + mScreenBrightnessSettingMinimum); + pw.println(" mScreenBrightnessSettingMaximumFloat=" + mScreenBrightnessSettingMaximum); + pw.println(" mScreenBrightnessSettingDefaultFloat=" + mScreenBrightnessSettingDefault); pw.println(" mDoubleTapWakeEnabled=" + mDoubleTapWakeEnabled); pw.println(" mIsVrModeEnabled=" + mIsVrModeEnabled); pw.println(" mForegroundProfile=" + mForegroundProfile); @@ -4056,7 +4163,7 @@ public final class PowerManagerService extends SystemService proto.write( PowerServiceSettingsAndConfigurationDumpProto .SCREEN_BRIGHTNESS_OVERRIDE_FROM_WINDOW_MANAGER, - mScreenBrightnessOverrideFromWindowManager); + mScreenBrightnessOverrideFromWindowManagerFloat); proto.write( PowerServiceSettingsAndConfigurationDumpProto .USER_ACTIVITY_TIMEOUT_OVERRIDE_FROM_WINDOW_MANAGER_MS, @@ -4738,6 +4845,29 @@ public final class PowerManagerService extends SystemService } } + public float getBrightnessConstraint(int constraint) { + switch (constraint) { + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM: + return mScreenBrightnessMinimum; + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM: + return mScreenBrightnessMaximum; + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT: + return mScreenBrightnessDefault; + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DIM: + return mScreenBrightnessDim; + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE: + return mScreenBrightnessDoze; + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR: + return mScreenBrightnessMinimumVr; + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR: + return mScreenBrightnessMaximumVr; + case PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT_VR: + return mScreenBrightnessDefaultVr; + default: + return PowerManager.BRIGHTNESS_INVALID_FLOAT; + } + } + @Override // Binder call public boolean isInteractive() { final long ident = Binder.clearCallingIdentity(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index cb687c9144c6..f700d7164d2a 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -490,6 +490,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { SYSTEM_SETTINGS_WHITELIST = new ArraySet<>(); SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS); + SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS_FLOAT); SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS_MODE); SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_OFF_TIMEOUT); diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java index ca00116d7ead..234c987bd3d6 100644 --- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.content.pm.PackageManager; import android.hardware.Sensor; import android.hardware.SensorEventListener; import android.hardware.SensorManager; @@ -46,9 +45,8 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidJUnit4.class) public class AutomaticBrightnessControllerTest { - - private static final int BRIGHTNESS_MIN = 1; - private static final int BRIGHTNESS_MAX = 255; + private static final float BRIGHTNESS_MIN_FLOAT = 0.0f; + private static final float BRIGHTNESS_MAX_FLOAT = 1.0f; private static final int LIGHT_SENSOR_RATE = 20; private static final int INITIAL_LIGHT_SENSOR_RATE = 20; private static final int BRIGHTENING_LIGHT_DEBOUNCE_CONFIG = 0; @@ -61,7 +59,6 @@ public class AutomaticBrightnessControllerTest { @Mock BrightnessMappingStrategy mBrightnessMappingStrategy; @Mock HysteresisLevels mAmbientBrightnessThresholds; @Mock HysteresisLevels mScreenBrightnessThresholds; - @Mock PackageManager mPackageManager; @Mock Handler mNoopHandler; private static final int LIGHT_SENSOR_WARMUP_TIME = 0; @@ -81,11 +78,11 @@ public class AutomaticBrightnessControllerTest { } }, () -> { }, mContext.getMainLooper(), mSensorManager, lightSensor, - mBrightnessMappingStrategy, LIGHT_SENSOR_WARMUP_TIME, BRIGHTNESS_MIN, - BRIGHTNESS_MAX, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE, INITIAL_LIGHT_SENSOR_RATE, - BRIGHTENING_LIGHT_DEBOUNCE_CONFIG, DARKENING_LIGHT_DEBOUNCE_CONFIG, - RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG, mAmbientBrightnessThresholds, - mScreenBrightnessThresholds, mPackageManager); + mBrightnessMappingStrategy, LIGHT_SENSOR_WARMUP_TIME, BRIGHTNESS_MIN_FLOAT, + BRIGHTNESS_MAX_FLOAT, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE, + INITIAL_LIGHT_SENSOR_RATE, BRIGHTENING_LIGHT_DEBOUNCE_CONFIG, + DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG, + mAmbientBrightnessThresholds, mScreenBrightnessThresholds, mContext); controller.setLoggingEnabled(true); // Configure the brightness controller and grab an instance of the sensor listener, @@ -110,7 +107,7 @@ public class AutomaticBrightnessControllerTest { // Set up system to return 5 as a brightness value float lux1 = 100.0f; - float normalizedBrightness1 = 0.02f; + float normalizedBrightness1 = 0.0158f; //float equivalent of 5 out of 255 when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1)) .thenReturn(lux1); when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1)) @@ -156,7 +153,7 @@ public class AutomaticBrightnessControllerTest { // Set up system to return 250 as a brightness value float lux1 = 100.0f; - float normalizedBrightness1 = 0.98f; + float normalizedBrightness1 = 0.981f; //float equivalent of 250 out of 255 when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1)) .thenReturn(lux1); when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1)) |