diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 6dd67447c3213..2430c09d93f46 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -19,6 +19,7 @@ package android.hardware.display; import static android.view.Display.DEFAULT_DISPLAY; import android.Manifest; +import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; @@ -921,6 +922,43 @@ public final class DisplayManager { mGlobal.setTemporaryBrightness(displayId, brightness); } + + /** + * Sets the brightness of the specified display. + *

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

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

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

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

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

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