diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java index 74486113dcf9b..4a9b562be697c 100644 --- a/services/core/java/com/android/server/display/BrightnessSetting.java +++ b/services/core/java/com/android/server/display/BrightnessSetting.java @@ -96,7 +96,11 @@ public class BrightnessSetting { mListeners.remove(l); } - void setBrightness(float brightness) { + /** + * Sets the brigtness and broadcasts the change to the listeners. + * @param brightness The value to which the brightness is to be set. + */ + public void setBrightness(float brightness) { if (Float.isNaN(brightness)) { Slog.w(TAG, "Attempting to set invalid brightness"); return; diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 96342f3ea4aad..ba9fe38c7cb44 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -68,6 +68,7 @@ import com.android.server.am.BatteryStatsService; import com.android.server.display.RampAnimator.DualRampAnimator; import com.android.server.display.brightness.BrightnessEvent; import com.android.server.display.brightness.BrightnessReason; +import com.android.server.display.brightness.BrightnessUtils; import com.android.server.display.brightness.DisplayBrightnessController; import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal; import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener; @@ -197,8 +198,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // mScreenBrightnessDimConfig. private final float mScreenBrightnessMinimumDimAmount; - private final float mScreenBrightnessDefault; - // True if auto-brightness should be used. private boolean mUseSoftwareAutoBrightnessConfig; @@ -332,8 +331,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private final BrightnessThrottler mBrightnessThrottler; - private final BrightnessSetting mBrightnessSetting; - private final Runnable mOnBrightnessChangeRunnable; private final BrightnessEvent mLastBrightnessEvent; @@ -384,19 +381,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal @Nullable private BrightnessConfiguration mBrightnessConfiguration; - // The last brightness that was set by the user and not temporary. Set to - // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded. - private float mLastUserSetScreenBrightness = Float.NaN; - - // The screen brightness 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 float mPendingScreenBrightnessSetting; - - // The last observed screen brightness setting, either set by us or by the settings app on - // behalf of the user. - private float mCurrentScreenBrightnessSetting; - // 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. private float mAutoBrightnessAdjustment; @@ -417,7 +401,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private ObjectAnimator mColorFadeOnAnimator; private ObjectAnimator mColorFadeOffAnimator; private DualRampAnimator mScreenBrightnessRampAnimator; - private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener; // True if this DisplayPowerController2 has been stopped and should no longer be running. private boolean mStopped; @@ -471,8 +454,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mBlanker = blanker; mContext = context; mBrightnessTracker = brightnessTracker; - // TODO: b/186428377 update brightness setting when display changes - mBrightnessSetting = brightnessSetting; mOnBrightnessChangeRunnable = onBrightnessChangeRunnable; PowerManager pm = context.getSystemService(PowerManager.class); @@ -480,18 +461,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal final Resources resources = context.getResources(); // DOZE AND DIM SETTINGS - mScreenBrightnessDozeConfig = clampAbsoluteBrightness( + mScreenBrightnessDozeConfig = BrightnessUtils.clampAbsoluteBrightness( pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)); - mScreenBrightnessDimConfig = clampAbsoluteBrightness( + mScreenBrightnessDimConfig = BrightnessUtils.clampAbsoluteBrightness( pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DIM)); mScreenBrightnessMinimumDimAmount = resources.getFloat( R.dimen.config_screenBrightnessMinimumDimAmountFloat); - - // NORMAL SCREEN SETTINGS - mScreenBrightnessDefault = clampAbsoluteBrightness( - mLogicalDisplay.getDisplayInfoLocked().brightnessDefault); - loadBrightnessRampRates(); mSkipScreenOnBrightnessRamp = resources.getBoolean( R.bool.config_skipScreenOnBrightnessRamp); @@ -499,7 +475,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mHbmController = createHbmControllerLocked(); mBrightnessThrottler = createBrightnessThrottlerLocked(); - + mDisplayBrightnessController = + new DisplayBrightnessController(context, null, + mDisplayId, mLogicalDisplay.getDisplayInfoLocked().brightnessDefault, + brightnessSetting, () -> postBrightnessChangeRunnable()); // Seed the cached brightness saveBrightnessInfo(getScreenBrightnessSetting()); @@ -554,12 +533,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mBrightnessBucketsInDozeConfig = resources.getBoolean( R.bool.config_displayBrightnessBucketsInDoze); - - mDisplayBrightnessController = - new DisplayBrightnessController(context, null, mDisplayId); - mCurrentScreenBrightnessSetting = getScreenBrightnessSetting(); mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); - mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; @@ -773,9 +747,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mAutomaticBrightnessController.stop(); } - if (mBrightnessSetting != null) { - mBrightnessSetting.unregisterListener(mBrightnessSettingListener); - } + mDisplayBrightnessController.stop(); mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); } @@ -854,12 +826,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal if (mBrightnessTracker != null && brightness >= PowerManager.BRIGHTNESS_MIN) { mBrightnessTracker.start(brightness); } - mBrightnessSettingListener = brightnessValue -> { + + BrightnessSetting.BrightnessSettingListener brightnessSettingListener = brightnessValue -> { Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue); mHandler.sendMessage(msg); }; + mDisplayBrightnessController + .registerBrightnessSettingChangeListener(brightnessSettingListener); - mBrightnessSetting.registerListener(mBrightnessSettingListener); mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ), false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); @@ -1209,7 +1183,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED; - final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); + final boolean userSetBrightnessChanged = mDisplayBrightnessController + .updateUserSetScreenBrightness(); final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment(); @@ -1235,7 +1210,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints(); mAutomaticBrightnessController.configure(autoBrightnessState, mBrightnessConfiguration, - mLastUserSetScreenBrightness, + mDisplayBrightnessController.getLastUserSetScreenBrightness(), userSetBrightnessChanged, autoBrightnessAdjustment, autoBrightnessAdjustmentChanged, mPowerRequest.policy, mShouldResetShortTermModel); @@ -1247,7 +1222,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } boolean updateScreenBrightnessSetting = false; - + float currentBrightnessSetting = mDisplayBrightnessController.getCurrentBrightness(); // Apply auto-brightness. boolean slowChange = false; if (Float.isNaN(brightnessState)) { @@ -1258,14 +1233,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal newAutoBrightnessAdjustment = mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); } - if (isValidBrightnessValue(brightnessState) + if (BrightnessUtils.isValidBrightnessValue(brightnessState) || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) { // Use current auto-brightness value and slowly adjust to changes. brightnessState = clampScreenBrightness(brightnessState); if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { slowChange = true; // slowly adapt to auto-brightness } - updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; + updateScreenBrightnessSetting = currentBrightnessSetting != brightnessState; mAppliedAutoBrightness = true; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); if (mScreenOffBrightnessSensorController != null) { @@ -1303,9 +1278,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal if (Float.isNaN(brightnessState) && autoBrightnessEnabled && mScreenOffBrightnessSensorController != null) { brightnessState = mScreenOffBrightnessSensorController.getAutomaticScreenBrightness(); - if (isValidBrightnessValue(brightnessState)) { + if (BrightnessUtils.isValidBrightnessValue(brightnessState)) { brightnessState = clampScreenBrightness(brightnessState); - updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; + updateScreenBrightnessSetting = mDisplayBrightnessController.getCurrentBrightness() + != brightnessState; mBrightnessReasonTemp.setReason( BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR); } @@ -1313,8 +1289,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // Apply manual brightness. if (Float.isNaN(brightnessState)) { - brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting); - if (brightnessState != mCurrentScreenBrightnessSetting) { + brightnessState = clampScreenBrightness(currentBrightnessSetting); + if (brightnessState != currentBrightnessSetting) { // The manually chosen screen brightness is outside of the currently allowed // range (i.e., high-brightness-mode), make sure we tell the rest of the system // by updating the setting. @@ -1351,7 +1327,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // 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. - updateScreenBrightnessSetting(brightnessState); + mDisplayBrightnessController.updateScreenBrightnessSetting(brightnessState); } // Apply dimming by at least some minimum amount when user activity @@ -1462,7 +1438,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal final float currentBrightness = mPowerState.getScreenBrightness(); final float currentSdrBrightness = mPowerState.getSdrScreenBrightness(); - if (isValidBrightnessValue(animateValue) + if (BrightnessUtils.isValidBrightnessValue(animateValue) && (animateValue != currentBrightness || sdrAnimateValue != currentSdrBrightness)) { if (initialRampSkip || hasBrightnessBuckets @@ -1897,12 +1873,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax()); } - // Checks whether the brightness is within the valid brightness range, not including off. - private boolean isValidBrightnessValue(float brightness) { - return brightness >= PowerManager.BRIGHTNESS_MIN - && brightness <= PowerManager.BRIGHTNESS_MAX; - } - private void animateScreenBrightness(float target, float sdrTarget, float rate) { if (DEBUG) { Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget @@ -2083,11 +2053,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } private void handleSettingsChange(boolean userSwitch) { - mPendingScreenBrightnessSetting = getScreenBrightnessSetting(); + mDisplayBrightnessController + .setPendingScreenBrightness(mDisplayBrightnessController + .getScreenBrightnessSetting()); mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); if (userSwitch) { // Don't treat user switches as user initiated change. - setCurrentScreenBrightness(mPendingScreenBrightnessSetting); + mDisplayBrightnessController.setCurrentScreenBrightness(mDisplayBrightnessController + .getPendingScreenBrightness()); updateAutoBrightnessAdjustment(); if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.resetShortTermModel(); @@ -2116,34 +2089,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal @Override public float getScreenBrightnessSetting() { - float brightness = mBrightnessSetting.getBrightness(); - if (Float.isNaN(brightness)) { - brightness = mScreenBrightnessDefault; - } - return clampAbsoluteBrightness(brightness); + return mDisplayBrightnessController.getScreenBrightnessSetting(); } @Override public void setBrightness(float brightnessValue) { - // Update the setting, which will eventually call back into DPC to have us actually update - // the display with the new value. - mBrightnessSetting.setBrightness(brightnessValue); - } - - private void updateScreenBrightnessSetting(float brightnessValue) { - if (!isValidBrightnessValue(brightnessValue) - || brightnessValue == mCurrentScreenBrightnessSetting) { - return; - } - setCurrentScreenBrightness(brightnessValue); - mBrightnessSetting.setBrightness(brightnessValue); - } - - private void setCurrentScreenBrightness(float brightnessValue) { - if (brightnessValue != mCurrentScreenBrightnessSetting) { - mCurrentScreenBrightnessSetting = brightnessValue; - postBrightnessChangeRunnable(); - } + mDisplayBrightnessController.setBrightness(brightnessValue); } private void putAutoBrightnessAdjustmentSetting(float adjustment) { @@ -2169,28 +2120,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal return true; } - // We want to return true if the user has set the screen brightness. - // RBC on, off, and intensity changes will return false. - // Slider interactions whilst in RBC will return true, just as when in non-rbc. - private boolean updateUserSetScreenBrightness() { - if ((Float.isNaN(mPendingScreenBrightnessSetting) - || mPendingScreenBrightnessSetting < 0.0f)) { - return false; - } - if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) { - mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; - mDisplayBrightnessController - .setTemporaryBrightness(PowerManager.BRIGHTNESS_INVALID_FLOAT); - return false; - } - setCurrentScreenBrightness(mPendingScreenBrightnessSetting); - mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting; - mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; - mDisplayBrightnessController - .setTemporaryBrightness(PowerManager.BRIGHTNESS_INVALID_FLOAT); - return true; - } - private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated, boolean hadUserDataPoint) { final float brightnessInNits = convertToNits(brightness); @@ -2235,7 +2164,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal pw.println(); pw.println("Display Power Controller Configuration:"); - pw.println(" mScreenBrightnessRangeDefault=" + mScreenBrightnessDefault); pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig); @@ -2266,9 +2194,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal pw.println(); pw.println("Display Power Controller Thread State:"); pw.println(" mPowerRequest=" + mPowerRequest); - pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness); - pw.println(" mPendingScreenBrightnessSetting=" - + mPendingScreenBrightnessSetting); pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); pw.println(" mBrightnessReason=" + mBrightnessReason); pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment); @@ -2385,11 +2310,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } } - 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); } diff --git a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java index fd4e296ae0024..d5aeba156bd7e 100644 --- a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java +++ b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java @@ -17,6 +17,7 @@ package com.android.server.display.brightness; import android.os.PowerManager; +import android.util.MathUtils; import com.android.server.display.DisplayBrightnessState; @@ -32,6 +33,14 @@ public final class BrightnessUtils { && brightness <= PowerManager.BRIGHTNESS_MAX; } + /** + * Clamps the brightness value in the maximum and the minimum brightness range + */ + public static float clampAbsoluteBrightness(float value) { + return MathUtils.constrain(value, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX); + } + /** * A utility to construct the DisplayBrightnessState */ diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java index bdc8d9dbb043c..e003ecb5cbadd 100644 --- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java +++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java @@ -18,9 +18,12 @@ package com.android.server.display.brightness; import android.content.Context; import android.hardware.display.DisplayManagerInternal; +import android.os.PowerManager; import android.util.IndentingPrintWriter; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.display.BrightnessSetting; import com.android.server.display.DisplayBrightnessState; import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy; @@ -31,19 +34,67 @@ import java.io.PrintWriter; * display. Applies the chosen brightness. */ public final class DisplayBrightnessController { + // The ID of the display tied to this DisplayBrightnessController private final int mDisplayId; + + // The lock which is to be used to synchronize the resources being used in this class + private final Object mLock = new Object(); + + // The default screen brightness to be used when no value is available in BrightnessSetting. + private final float mScreenBrightnessDefault; + + // This is used to persist the changes happening to the brightness. + private final BrightnessSetting mBrightnessSetting; + + // A runnable to update the clients registered via DisplayManagerGlobal + // .EVENT_DISPLAY_BRIGHTNESS_CHANGED about the brightness change. Called when + // mCurrentScreenBrightness is updated. + private Runnable mOnBrightnessChangeRunnable; + + // The screen brightness that has changed but not taken effect yet. If this is different + // from the current screen brightness then this is coming from something other than us + // and should be considered a user interaction. + @GuardedBy("mLock") + private float mPendingScreenBrightness; + + // The last observed screen brightness, either set by us or by the settings app on + // behalf of the user. + @GuardedBy("mLock") + private float mCurrentScreenBrightness; + + // The last brightness that was set by the user and not temporary. Set to + // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded. + @GuardedBy("mLock") + private float mLastUserSetScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + + // The listener which is to be notified everytime there is a change in the brightness in the + // BrightnessSetting. + private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener; + // Selects an appropriate strategy based on the request provided by the clients. + @GuardedBy("mLock") private DisplayBrightnessStrategySelector mDisplayBrightnessStrategySelector; + + // Currently selected DisplayBrightnessStrategy. + @GuardedBy("mLock") private DisplayBrightnessStrategy mDisplayBrightnessStrategy; /** * The constructor of DisplayBrightnessController. */ - public DisplayBrightnessController(Context context, Injector injector, int displayId) { + public DisplayBrightnessController(Context context, Injector injector, int displayId, + float defaultScreenBrightness, BrightnessSetting brightnessSetting, + Runnable onBrightnessChangeRunnable) { if (injector == null) { injector = new Injector(); } mDisplayId = displayId; + // TODO: b/186428377 update brightness setting when display changes + mBrightnessSetting = brightnessSetting; + mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mCurrentScreenBrightness = getScreenBrightnessSetting(); + mOnBrightnessChangeRunnable = onBrightnessChangeRunnable; + mScreenBrightnessDefault = BrightnessUtils.clampAbsoluteBrightness(defaultScreenBrightness); mDisplayBrightnessStrategySelector = injector.getDisplayBrightnessStrategySelector(context, displayId); } @@ -61,25 +112,20 @@ public final class DisplayBrightnessController { public DisplayBrightnessState updateBrightness( DisplayManagerInternal.DisplayPowerRequest displayPowerRequest, int targetDisplayState) { - mDisplayBrightnessStrategy = - mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest, - targetDisplayState); - return mDisplayBrightnessStrategy.updateBrightness(displayPowerRequest); + synchronized (mLock) { + mDisplayBrightnessStrategy = mDisplayBrightnessStrategySelector.selectStrategy( + displayPowerRequest, targetDisplayState); + return mDisplayBrightnessStrategy.updateBrightness(displayPowerRequest); + } } /** * Sets the temporary brightness */ public void setTemporaryBrightness(Float temporaryBrightness) { - mDisplayBrightnessStrategySelector.getTemporaryDisplayBrightnessStrategy() - .setTemporaryScreenBrightness(temporaryBrightness); - } - - /** - * Returns the current selected DisplayBrightnessStrategy - */ - public DisplayBrightnessStrategy getCurrentDisplayBrightnessStrategy() { - return mDisplayBrightnessStrategy; + synchronized (mLock) { + setTemporaryBrightnessLocked(temporaryBrightness); + } } /** @@ -87,7 +133,140 @@ public final class DisplayBrightnessController { * brightness when dozing */ public boolean isAllowAutoBrightnessWhileDozingConfig() { - return mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozingConfig(); + synchronized (mLock) { + return mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozingConfig(); + } + } + + /** + * Sets the current screen brightness to the supplied value, and notifies all the listeners + * requesting for change events on brightness change. + */ + public void setCurrentScreenBrightness(float brightnessValue) { + synchronized (mLock) { + if (brightnessValue != mCurrentScreenBrightness) { + mCurrentScreenBrightness = brightnessValue; + mOnBrightnessChangeRunnable.run(); + } + } + } + + /** + * Returns the last observed screen brightness. + */ + public float getCurrentBrightness() { + synchronized (mLock) { + return mCurrentScreenBrightness; + } + } + + /** + * Returns the screen brightness which has changed but has not taken any effect so far. + */ + public float getPendingScreenBrightness() { + synchronized (mLock) { + return mPendingScreenBrightness; + } + } + + /** + * Sets the pending screen brightness setting, representing a value which is requested, but not + * yet processed. + * @param brightnessValue The value to which the pending screen brightness is to be set. + */ + public void setPendingScreenBrightness(float brightnessValue) { + synchronized (mLock) { + mPendingScreenBrightness = brightnessValue; + } + } + + /** + * We want to return true if the user has set the screen brightness. + * RBC on, off, and intensity changes will return false. + * Slider interactions whilst in RBC will return true, just as when in non-rbc. + */ + public boolean updateUserSetScreenBrightness() { + synchronized (mLock) { + if (!BrightnessUtils.isValidBrightnessValue(mPendingScreenBrightness)) { + return false; + } + if (mCurrentScreenBrightness == mPendingScreenBrightness) { + mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT); + return false; + } + setCurrentScreenBrightness(mPendingScreenBrightness); + mLastUserSetScreenBrightness = mPendingScreenBrightness; + mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT); + return true; + } + } + + /** + * Registers the BrightnessSettingListener with the BrightnessSetting, which will be notified + * everytime there is a change in the brightness. + */ + public void registerBrightnessSettingChangeListener( + BrightnessSetting.BrightnessSettingListener brightnessSettingListener) { + mBrightnessSettingListener = brightnessSettingListener; + mBrightnessSetting.registerListener(mBrightnessSettingListener); + } + + /** + * Returns the last user set brightness which is not temporary. + */ + public float getLastUserSetScreenBrightness() { + synchronized (mLock) { + return mLastUserSetScreenBrightness; + } + } + + /** + * Returns the current screen brightnessSetting which is responsible for saving the brightness + * in the persistent store + */ + public float getScreenBrightnessSetting() { + float brightness = mBrightnessSetting.getBrightness(); + synchronized (mLock) { + if (Float.isNaN(brightness)) { + brightness = mScreenBrightnessDefault; + } + return BrightnessUtils.clampAbsoluteBrightness(brightness); + } + } + + /** + * Notifies the brightnessSetting to persist the supplied brightness value. + */ + public void setBrightness(float brightnessValue) { + // Update the setting, which will eventually call back into DPC to have us actually + // update the display with the new value. + mBrightnessSetting.setBrightness(brightnessValue); + } + + /** + * Sets the current screen brightness, and notifies the BrightnessSetting about the change. + */ + public void updateScreenBrightnessSetting(float brightnessValue) { + synchronized (mLock) { + if (!BrightnessUtils.isValidBrightnessValue(brightnessValue) + || brightnessValue == mCurrentScreenBrightness) { + return; + } + setCurrentScreenBrightness(brightnessValue); + setBrightness(brightnessValue); + } + } + + /** + * Stops the associated listeners when the display is stopped. Invoked when the {@link + * #mDisplayId} is being removed. + */ + public void stop() { + if (mBrightnessSetting != null) { + mBrightnessSetting.unregisterListener(mBrightnessSettingListener); + } } /** @@ -99,12 +278,19 @@ public final class DisplayBrightnessController { writer.println(); writer.println("DisplayBrightnessController:"); writer.println(" mDisplayId=: " + mDisplayId); - if (mDisplayBrightnessStrategy != null) { - writer.println(" Last selected DisplayBrightnessStrategy= " - + mDisplayBrightnessStrategy.getName()); + writer.println(" mScreenBrightnessDefault=" + mScreenBrightnessDefault); + synchronized (mLock) { + writer.println(" mPendingScreenBrightness=" + mPendingScreenBrightness); + writer.println(" mCurrentScreenBrightness=" + mCurrentScreenBrightness); + writer.println(" mLastUserSetScreenBrightness=" + + mLastUserSetScreenBrightness); + if (mDisplayBrightnessStrategy != null) { + writer.println(" Last selected DisplayBrightnessStrategy= " + + mDisplayBrightnessStrategy.getName()); + } + IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " "); + mDisplayBrightnessStrategySelector.dump(ipw); } - IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " "); - mDisplayBrightnessStrategySelector.dump(ipw); } @VisibleForTesting @@ -114,4 +300,26 @@ public final class DisplayBrightnessController { return new DisplayBrightnessStrategySelector(context, /* injector= */ null, displayId); } } + + @VisibleForTesting + BrightnessSetting.BrightnessSettingListener getBrightnessSettingListenerLocked() { + return mBrightnessSettingListener; + } + + /** + * Returns the current selected DisplayBrightnessStrategy + */ + @VisibleForTesting + DisplayBrightnessStrategy getCurrentDisplayBrightnessStrategyLocked() { + synchronized (mLock) { + return mDisplayBrightnessStrategy; + } + } + + private void setTemporaryBrightnessLocked(float temporaryBrightness) { + synchronized (mLock) { + mDisplayBrightnessStrategySelector.getTemporaryDisplayBrightnessStrategy() + .setTemporaryScreenBrightness(temporaryBrightness); + } + } } diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java index cbeaf7ba2434a..c24d83f0f8780 100644 --- a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java @@ -16,18 +16,26 @@ package com.android.server.display.brightness; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.content.Context; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; +import android.os.PowerManager; import android.view.Display; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.display.BrightnessSetting; import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy; +import com.android.server.display.brightness.strategy.TemporaryBrightnessStrategy; import org.junit.Before; import org.junit.Test; @@ -39,11 +47,16 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public final class DisplayBrightnessControllerTest { private static final int DISPLAY_ID = 1; + private static final float DEFAULT_BRIGHTNESS = 0.4f; @Mock private DisplayBrightnessStrategySelector mDisplayBrightnessStrategySelector; @Mock private Context mContext; + @Mock + private BrightnessSetting mBrightnessSetting; + @Mock + private Runnable mOnBrightnessChangeRunnable; private DisplayBrightnessController mDisplayBrightnessController; @@ -58,11 +71,11 @@ public final class DisplayBrightnessControllerTest { } }; mDisplayBrightnessController = new DisplayBrightnessController(mContext, injector, - DISPLAY_ID); + DISPLAY_ID, DEFAULT_BRIGHTNESS, mBrightnessSetting, mOnBrightnessChangeRunnable); } @Test - public void updateBrightnessWorksAsExpected() { + public void updateBrightness() { DisplayPowerRequest displayPowerRequest = mock(DisplayPowerRequest.class); DisplayBrightnessStrategy displayBrightnessStrategy = mock(DisplayBrightnessStrategy.class); int targetDisplayState = Display.STATE_DOZE; @@ -70,6 +83,8 @@ public final class DisplayBrightnessControllerTest { targetDisplayState)).thenReturn(displayBrightnessStrategy); mDisplayBrightnessController.updateBrightness(displayPowerRequest, targetDisplayState); verify(displayBrightnessStrategy).updateBrightness(displayPowerRequest); + assertEquals(mDisplayBrightnessController.getCurrentDisplayBrightnessStrategyLocked(), + displayBrightnessStrategy); } @Test @@ -77,4 +92,154 @@ public final class DisplayBrightnessControllerTest { mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig(); verify(mDisplayBrightnessStrategySelector).isAllowAutoBrightnessWhileDozingConfig(); } + + @Test + public void setTemporaryBrightness() { + float temporaryBrightness = 0.4f; + TemporaryBrightnessStrategy temporaryBrightnessStrategy = mock( + TemporaryBrightnessStrategy.class); + when(mDisplayBrightnessStrategySelector.getTemporaryDisplayBrightnessStrategy()).thenReturn( + temporaryBrightnessStrategy); + mDisplayBrightnessController.setTemporaryBrightness(temporaryBrightness); + verify(temporaryBrightnessStrategy).setTemporaryScreenBrightness(temporaryBrightness); + } + + @Test + public void setCurrentScreenBrightness() { + // Current Screen brightness is set as expected when a different value than the current + // is set + float currentScreenBrightness = 0.4f; + mDisplayBrightnessController.setCurrentScreenBrightness(currentScreenBrightness); + assertEquals(mDisplayBrightnessController.getCurrentBrightness(), + currentScreenBrightness, 0.0f); + verify(mOnBrightnessChangeRunnable).run(); + + // No change to the current screen brightness is same as the existing one + mDisplayBrightnessController.setCurrentScreenBrightness(currentScreenBrightness); + verifyNoMoreInteractions(mOnBrightnessChangeRunnable); + } + + @Test + public void setPendingScreenBrightnessSetting() { + float pendingScreenBrightness = 0.4f; + mDisplayBrightnessController.setPendingScreenBrightness(pendingScreenBrightness); + assertEquals(mDisplayBrightnessController.getPendingScreenBrightness(), + pendingScreenBrightness, 0.0f); + } + + @Test + public void updateUserSetScreenBrightness() { + // No brightness is set if the pending brightness is invalid + mDisplayBrightnessController.setPendingScreenBrightness(Float.NaN); + assertFalse(mDisplayBrightnessController.updateUserSetScreenBrightness()); + + // user set brightness is not set if the current and the pending brightness are same. + float currentBrightness = 0.4f; + TemporaryBrightnessStrategy temporaryBrightnessStrategy = mock( + TemporaryBrightnessStrategy.class); + when(mDisplayBrightnessStrategySelector.getTemporaryDisplayBrightnessStrategy()).thenReturn( + temporaryBrightnessStrategy); + mDisplayBrightnessController.setCurrentScreenBrightness(currentBrightness); + mDisplayBrightnessController.setPendingScreenBrightness(currentBrightness); + mDisplayBrightnessController.setTemporaryBrightness(currentBrightness); + assertFalse(mDisplayBrightnessController.updateUserSetScreenBrightness()); + verify(temporaryBrightnessStrategy).setTemporaryScreenBrightness( + PowerManager.BRIGHTNESS_INVALID_FLOAT); + assertEquals(mDisplayBrightnessController.getPendingScreenBrightness(), + PowerManager.BRIGHTNESS_INVALID_FLOAT, 0.0f); + + // user set brightness is set as expected + currentBrightness = 0.4f; + float pendingScreenBrightness = 0.3f; + float temporaryScreenBrightness = 0.2f; + mDisplayBrightnessController.setCurrentScreenBrightness(currentBrightness); + mDisplayBrightnessController.setPendingScreenBrightness(pendingScreenBrightness); + mDisplayBrightnessController.setTemporaryBrightness(temporaryScreenBrightness); + assertTrue(mDisplayBrightnessController.updateUserSetScreenBrightness()); + assertEquals(mDisplayBrightnessController.getCurrentBrightness(), + pendingScreenBrightness, 0.0f); + assertEquals(mDisplayBrightnessController.getLastUserSetScreenBrightness(), + pendingScreenBrightness, 0.0f); + verify(mOnBrightnessChangeRunnable, times(2)).run(); + verify(temporaryBrightnessStrategy, times(2)) + .setTemporaryScreenBrightness(PowerManager.BRIGHTNESS_INVALID_FLOAT); + assertEquals(mDisplayBrightnessController.getPendingScreenBrightness(), + PowerManager.BRIGHTNESS_INVALID_FLOAT, 0.0f); + } + + @Test + public void registerBrightnessSettingChangeListener() { + BrightnessSetting.BrightnessSettingListener brightnessSettingListener = mock( + BrightnessSetting.BrightnessSettingListener.class); + mDisplayBrightnessController.registerBrightnessSettingChangeListener( + brightnessSettingListener); + verify(mBrightnessSetting).registerListener(brightnessSettingListener); + assertEquals(mDisplayBrightnessController.getBrightnessSettingListenerLocked(), + brightnessSettingListener); + } + + @Test + public void getScreenBrightnessSetting() { + // getScreenBrightnessSetting returns the value relayed by BrightnessSetting, if the + // valid is valid and in range + float brightnessSetting = 0.2f; + when(mBrightnessSetting.getBrightness()).thenReturn(brightnessSetting); + assertEquals(mDisplayBrightnessController.getScreenBrightnessSetting(), brightnessSetting, + 0.0f); + + // getScreenBrightnessSetting value is clamped if BrightnessSetting returns value beyond max + brightnessSetting = 1.1f; + when(mBrightnessSetting.getBrightness()).thenReturn(brightnessSetting); + assertEquals(mDisplayBrightnessController.getScreenBrightnessSetting(), 1.0f, + 0.0f); + + // getScreenBrightnessSetting returns default value is BrightnessSetting returns invalid + // value. + brightnessSetting = Float.NaN; + when(mBrightnessSetting.getBrightness()).thenReturn(brightnessSetting); + assertEquals(mDisplayBrightnessController.getScreenBrightnessSetting(), DEFAULT_BRIGHTNESS, + 0.0f); + } + + @Test + public void setBrightnessSetsInBrightnessSetting() { + float brightnessValue = 0.3f; + mDisplayBrightnessController.setBrightness(brightnessValue); + verify(mBrightnessSetting).setBrightness(brightnessValue); + } + + @Test + public void updateScreenBrightnessSetting() { + // This interaction happens in the constructor itself + verify(mBrightnessSetting).getBrightness(); + + // Sets the appropriate value when valid, and not equal to the current brightness + float brightnessValue = 0.3f; + mDisplayBrightnessController.updateScreenBrightnessSetting(brightnessValue); + assertEquals(mDisplayBrightnessController.getCurrentBrightness(), brightnessValue, + 0.0f); + verify(mOnBrightnessChangeRunnable).run(); + verify(mBrightnessSetting).setBrightness(brightnessValue); + + // Does nothing if the value is invalid + mDisplayBrightnessController.updateScreenBrightnessSetting(Float.NaN); + verifyNoMoreInteractions(mOnBrightnessChangeRunnable, mBrightnessSetting); + + // Does nothing if the value is same as the current brightness + brightnessValue = 0.2f; + mDisplayBrightnessController.setCurrentScreenBrightness(brightnessValue); + verify(mOnBrightnessChangeRunnable, times(2)).run(); + mDisplayBrightnessController.updateScreenBrightnessSetting(brightnessValue); + verifyNoMoreInteractions(mOnBrightnessChangeRunnable, mBrightnessSetting); + } + + @Test + public void stop() { + BrightnessSetting.BrightnessSettingListener brightnessSettingListener = mock( + BrightnessSetting.BrightnessSettingListener.class); + mDisplayBrightnessController.registerBrightnessSettingChangeListener( + brightnessSettingListener); + mDisplayBrightnessController.stop(); + verify(mBrightnessSetting).unregisterListener(brightnessSettingListener); + } }