Merge "Introducing AutomaticBrightnessStrategy" into udc-dev

This commit is contained in:
Rupesh Bansal
2023-03-27 16:58:52 +00:00
committed by Android (Google) Code Review
5 changed files with 804 additions and 162 deletions

View File

@@ -1634,7 +1634,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAppliedAutoBrightness = false;
brightnessAdjustmentFlags = 0;
}
// Use default brightness when dozing unless overridden.
if ((Float.isNaN(brightnessState))
&& Display.isDozeState(state)) {

View File

@@ -64,6 +64,7 @@ import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.RingBuffer;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
@@ -72,6 +73,7 @@ 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.brightness.strategy.AutomaticBrightnessStrategy;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
import com.android.server.display.layout.Layout;
@@ -209,9 +211,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// True if auto-brightness should be used.
private boolean mUseSoftwareAutoBrightnessConfig;
// True if the brightness config has changed and the short-term model needs to be reset
private boolean mShouldResetShortTermModel;
// Whether or not the color fade on screen on / off is enabled.
private final boolean mColorFadeEnabled;
@@ -296,12 +295,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// If the last recorded screen state was dozing or not.
private boolean mDozing;
// Remembers whether certain kinds of brightness adjustments
// were recently applied so that we can decide how to transition.
private boolean mAppliedAutoBrightness;
private boolean mAppliedDimming;
private boolean mAppliedLowPower;
private boolean mAppliedTemporaryAutoBrightnessAdjustment;
private boolean mAppliedThrottling;
// Reason for which the brightness was last changed. See {@link BrightnessReason} for more
@@ -359,6 +354,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// Tracks and manages the display state of the associated display.
private final DisplayStateController mDisplayStateController;
// Responsible for evaluating and tracking the automatic brightness relevant states.
// Todo: This is a temporary workaround. Ideally DPC2 should never talk to the strategies
private final AutomaticBrightnessStrategy mAutomaticBrightnessStrategy;
// A record of state for skipping brightness ramps.
private int mSkipRampState = RAMP_STATE_SKIP_NONE;
@@ -385,24 +385,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
@Nullable
private BrightnessMappingStrategy mIdleModeBrightnessMapper;
// The current brightness configuration.
@Nullable
private BrightnessConfiguration mBrightnessConfiguration;
// 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;
// The pending auto brightness adjustment that will take effect on the next power state update.
private float mPendingAutoBrightnessAdjustment;
// The temporary auto brightness adjustment. Typically set when a user is interacting with the
// adjustment slider but hasn't settled on a choice yet. Set to
// PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set.
private float mTemporaryAutoBrightnessAdjustment;
private boolean mUseAutoBrightness;
private boolean mIsRbcActive;
// Animators.
@@ -454,6 +436,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
() -> updatePowerState(), mDisplayId, mSensorManager);
mHighBrightnessModeMetadata = hbmMetadata;
mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController);
mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy(context, mDisplayId);
mTag = "DisplayPowerController2[" + mDisplayId + "]";
mBrightnessThrottlingDataId = logicalDisplay.getBrightnessThrottlingDataIdLocked();
@@ -555,9 +538,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mBrightnessBucketsInDozeConfig = resources.getBoolean(
R.bool.config_displayBrightnessBucketsInDoze);
mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mBootCompleted = bootCompleted;
}
@@ -1038,6 +1018,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayBrightnessController.setAutomaticBrightnessController(
mAutomaticBrightnessController);
mAutomaticBrightnessStrategy
.setAutomaticBrightnessController(mAutomaticBrightnessController);
mBrightnessEventRingBuffer =
new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
@@ -1168,7 +1150,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
final boolean mustNotify;
final int previousPolicy;
boolean mustInitialize = false;
int brightnessAdjustmentFlags = 0;
mBrightnessReasonTemp.set(null);
mTempBrightnessEvent.reset();
SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
@@ -1208,7 +1189,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
.updateDisplayState(mPowerRequest, mIsEnabled, mIsInTransition);
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
mScreenOffBrightnessSensorController
.setLightSensorEnabled(mAutomaticBrightnessStrategy.shouldUseAutoBrightness()
&& mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
&& !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()))
&& mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
@@ -1222,7 +1204,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// Animate the screen state change unless already animating.
// The transition may be deferred, so after this point we will use the
// actual state instead of the desired one.
final int oldState = mPowerState.getScreenState();
animateScreenStateChange(state, mDisplayStateController.shouldPerformScreenOffTransition());
state = mPowerState.getScreenState();
@@ -1231,112 +1212,59 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
float brightnessState = displayBrightnessState.getBrightness();
float rawBrightnessState = displayBrightnessState.getBrightness();
mBrightnessReasonTemp.set(displayBrightnessState.getBrightnessReason());
final boolean autoBrightnessEnabledInDoze =
mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()
&& Display.isDozeState(state);
final boolean autoBrightnessEnabled = mUseAutoBrightness
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
&& (Float.isNaN(brightnessState)
|| mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_TEMPORARY
|| mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_BOOST)
&& mAutomaticBrightnessController != null
&& mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_FOLLOWER;
final boolean autoBrightnessDisabledDueToDisplayOff = mUseAutoBrightness
&& !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
final int autoBrightnessState = autoBrightnessEnabled
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: autoBrightnessDisabledDueToDisplayOff
? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
final boolean userSetBrightnessChanged = mDisplayBrightnessController
.updateUserSetScreenBrightness();
final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
// Use the autobrightness adjustment override if set.
final float autoBrightnessAdjustment;
if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;
mAppliedTemporaryAutoBrightnessAdjustment = true;
} else {
autoBrightnessAdjustment = mAutoBrightnessAdjustment;
brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;
mAppliedTemporaryAutoBrightnessAdjustment = false;
}
// Take note if the short term model was already active before applying the current
// request changes.
final boolean wasShortTermModelActive =
mAutomaticBrightnessStrategy.isShortTermModelActive();
mAutomaticBrightnessStrategy.setAutoBrightnessState(state,
mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig(),
brightnessState, mBrightnessReasonTemp.getReason(), mPowerRequest.policy,
mDisplayBrightnessController.getLastUserSetScreenBrightness(),
userSetBrightnessChanged);
// If the brightness is already set then it's been overridden by something other than the
// user, or is a temporary adjustment.
boolean userInitiatedChange = (Float.isNaN(brightnessState))
&& (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
boolean wasShortTermModelActive = false;
// Configure auto-brightness.
if (mAutomaticBrightnessController != null) {
wasShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints();
mAutomaticBrightnessController.configure(autoBrightnessState,
mBrightnessConfiguration,
mDisplayBrightnessController.getLastUserSetScreenBrightness(),
userSetBrightnessChanged, autoBrightnessAdjustment,
autoBrightnessAdjustmentChanged, mPowerRequest.policy,
mShouldResetShortTermModel);
mShouldResetShortTermModel = false;
}
mHbmController.setAutoBrightnessEnabled(mUseAutoBrightness
&& (mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged()
|| userSetBrightnessChanged);
mHbmController.setAutoBrightnessEnabled(mAutomaticBrightnessStrategy
.shouldUseAutoBrightness()
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
if (mBrightnessTracker != null) {
mBrightnessTracker.setShouldCollectColorSample(mBrightnessConfiguration != null
&& mBrightnessConfiguration.shouldCollectColorSamples());
}
boolean updateScreenBrightnessSetting = false;
float currentBrightnessSetting = mDisplayBrightnessController.getCurrentBrightness();
// Apply auto-brightness.
boolean slowChange = false;
int brightnessAdjustmentFlags = 0;
if (Float.isNaN(brightnessState)) {
float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
if (autoBrightnessEnabled) {
rawBrightnessState = mAutomaticBrightnessController
.getRawAutomaticScreenBrightness();
brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(
mTempBrightnessEvent);
newAutoBrightnessAdjustment =
mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
}
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
if (mAutomaticBrightnessStrategy.isAutoBrightnessEnabled()) {
brightnessState = mAutomaticBrightnessStrategy.getAutomaticScreenBrightness();
if (BrightnessUtils.isValidBrightnessValue(brightnessState)
|| brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) {
rawBrightnessState = mAutomaticBrightnessController
.getRawAutomaticScreenBrightness();
brightnessState = clampScreenBrightness(brightnessState);
// slowly adapt to auto-brightness
slowChange = mAutomaticBrightnessStrategy.hasAppliedAutoBrightness()
&& !mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged();
brightnessAdjustmentFlags =
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentReasonsFlags();
updateScreenBrightnessSetting = currentBrightnessSetting != brightnessState;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
}
}
updateScreenBrightnessSetting = currentBrightnessSetting != brightnessState;
mAppliedAutoBrightness = true;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
}
} else {
mAppliedAutoBrightness = false;
}
if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {
// If the autobrightness controller has decided to change the adjustment value
// used, make sure that's reflected in settings.
putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
} else {
// Adjustment values resulted in no change
brightnessAdjustmentFlags = 0;
}
} else {
// Any non-auto-brightness values such as override or temporary should still be subject
// to clamping so that they don't go beyond the current max as specified by HBM
// Controller.
brightnessState = clampScreenBrightness(brightnessState);
mAppliedAutoBrightness = false;
brightnessAdjustmentFlags = 0;
}
// Use default brightness when dozing unless overridden.
@@ -1349,7 +1277,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// The ALS is not available yet - use the screen off sensor to determine the initial
// brightness
if (Float.isNaN(brightnessState) && autoBrightnessEnabled
if (Float.isNaN(brightnessState) && mAutomaticBrightnessStrategy.isAutoBrightnessEnabled()
&& mScreenOffBrightnessSensorController != null) {
rawBrightnessState =
mScreenOffBrightnessSensorController.getAutomaticScreenBrightness();
@@ -1466,7 +1394,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
boolean brightnessAdjusted = false;
final boolean brightnessIsTemporary =
(mBrightnessReason.getReason() == BrightnessReason.REASON_TEMPORARY)
|| mAppliedTemporaryAutoBrightnessAdjustment;
|| mAutomaticBrightnessStrategy
.isTemporaryAutoBrightnessAdjustmentApplied();
if (!mPendingScreenOff) {
if (mSkipScreenOnBrightnessRamp) {
if (state == Display.STATE_ON) {
@@ -1524,6 +1453,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
final float currentBrightness = mPowerState.getScreenBrightness();
final float currentSdrBrightness = mPowerState.getSdrScreenBrightness();
if (BrightnessUtils.isValidBrightnessValue(animateValue)
&& (animateValue != currentBrightness
|| sdrAnimateValue != currentSdrBrightness)) {
@@ -1605,7 +1535,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mTempBrightnessEvent.setWasShortTermModelActive(wasShortTermModelActive);
mTempBrightnessEvent.setDisplayBrightnessStrategyName(displayBrightnessState
.getDisplayBrightnessStrategyName());
mTempBrightnessEvent.setAutomaticBrightnessEnabled(mUseAutoBrightness);
mTempBrightnessEvent.setAutomaticBrightnessEnabled(mAutomaticBrightnessStrategy
.shouldUseAutoBrightness());
// Temporary is what we use during slider interactions. We avoid logging those so that
// we don't spam logcat when the slider is being used.
boolean tempToTempTransition =
@@ -2151,13 +2082,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayBrightnessController
.setPendingScreenBrightness(mDisplayBrightnessController
.getScreenBrightnessSetting());
mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(userSwitch);
if (userSwitch) {
// Don't treat user switches as user initiated change.
mDisplayBrightnessController
.setAndNotifyCurrentScreenBrightness(mDisplayBrightnessController
.getPendingScreenBrightness());
updateAutoBrightnessAdjustment();
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.resetShortTermModel();
}
@@ -2171,8 +2101,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
mHandler.postAtTime(() -> {
mUseAutoBrightness = screenBrightnessModeSetting
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
mAutomaticBrightnessStrategy.setUseAutoBrightness(screenBrightnessModeSetting
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
updatePowerState();
}, mClock.uptimeMillis());
}
@@ -2220,33 +2150,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
sendUpdatePowerState();
}
private void putAutoBrightnessAdjustmentSetting(float adjustment) {
if (mDisplayId == Display.DEFAULT_DISPLAY) {
mAutoBrightnessAdjustment = adjustment;
Settings.System.putFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment,
UserHandle.USER_CURRENT);
}
}
private boolean updateAutoBrightnessAdjustment() {
if (Float.isNaN(mPendingAutoBrightnessAdjustment)) {
return false;
}
if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) {
mPendingAutoBrightnessAdjustment = Float.NaN;
return false;
}
mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment;
mPendingAutoBrightnessAdjustment = Float.NaN;
mTemporaryAutoBrightnessAdjustment = Float.NaN;
return true;
}
private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
boolean wasShortTermModelActive) {
final float brightnessInNits = mDisplayBrightnessController.convertToNits(brightness);
if (mUseAutoBrightness && brightnessInNits >= 0.0f
if (mAutomaticBrightnessStrategy.shouldUseAutoBrightness() && brightnessInNits >= 0.0f
&& mAutomaticBrightnessController != null && mBrightnessTracker != null) {
// We only want to track changes on devices that can actually map the display backlight
// values into a physical brightness unit since the value provided by the API is in
@@ -2329,16 +2236,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
pw.println();
pw.println("Display Power Controller Thread State:");
pw.println(" mPowerRequest=" + mPowerRequest);
pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
pw.println(" mBrightnessReason=" + mBrightnessReason);
pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
pw.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
pw.println(" mAppliedDimming=" + mAppliedDimming);
pw.println(" mAppliedLowPower=" + mAppliedLowPower);
pw.println(" mAppliedThrottling=" + mAppliedThrottling);
pw.println(" mAppliedTemporaryAutoBrightnessAdjustment="
+ mAppliedTemporaryAutoBrightnessAdjustment);
pw.println(" mDozing=" + mDozing);
pw.println(" mSkipRampState=" + skipRampStateToString(mSkipRampState));
pw.println(" mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime);
@@ -2349,6 +2250,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
pw.println(" mReportedToPolicy="
+ reportedToPolicyToString(mReportedScreenStateToPolicy));
pw.println(" mIsRbcActive=" + mIsRbcActive);
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
mAutomaticBrightnessStrategy.dump(ipw);
if (mScreenBrightnessRampAnimator != null) {
pw.println(" mScreenBrightnessRampAnimator.isAnimating()="
@@ -2580,8 +2483,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
break;
case MSG_CONFIGURE_BRIGHTNESS:
mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
mShouldResetShortTermModel = msg.arg1 == 1;
BrightnessConfiguration brightnessConfiguration =
(BrightnessConfiguration) msg.obj;
mAutomaticBrightnessStrategy.setBrightnessConfiguration(brightnessConfiguration,
msg.arg1 == 1);
if (mBrightnessTracker != null) {
mBrightnessTracker
.setShouldCollectColorSample(brightnessConfiguration != null
&& brightnessConfiguration.shouldCollectColorSamples());
}
updatePowerState();
break;
@@ -2593,7 +2503,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
break;
case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT:
mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
mAutomaticBrightnessStrategy
.setTemporaryAutoBrightnessAdjustment(Float.intBitsToFloat(msg.arg1));
updatePowerState();
break;

View File

@@ -0,0 +1,404 @@
/*
* Copyright (C) 2023 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.brightness.strategy;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.display.BrightnessConfiguration;
import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.AutomaticBrightnessController;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.brightness.BrightnessUtils;
import java.io.PrintWriter;
/**
* Helps manage the brightness based on the ambient environment (Ambient Light/lux sensor) using
* mappings from lux to nits to brightness, configured in the
* {@link com.android.server.display.DisplayDeviceConfig} class. This class inherently assumes
* that it is being executed from the power thread, and hence doesn't synchronize
* any of its resources
*/
public class AutomaticBrightnessStrategy {
private final Context mContext;
// The DisplayId of the associated logical display
private final int mDisplayId;
// The last auto brightness adjustment that was set by the user and is not temporary. Set to
// Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
private float mAutoBrightnessAdjustment;
// The pending auto brightness adjustment that will take effect on the next power state update.
private float mPendingAutoBrightnessAdjustment;
// The temporary auto brightness adjustment. This was historically used when a user interacts
// with the adjustment slider but hasn't settled on a choice yet.
// Set to PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set.
private float mTemporaryAutoBrightnessAdjustment;
// Indicates if the temporary auto brightness adjustment has been applied while updating the
// associated display brightness
private boolean mAppliedTemporaryAutoBrightnessAdjustment;
// Indicates if the auto brightness adjustment has happened.
private boolean mAutoBrightnessAdjustmentChanged;
// Indicates the reasons for the auto-brightness adjustment
private int mAutoBrightnessAdjustmentReasonsFlags = 0;
// Indicates if the short term model should be reset before fetching the new brightness
// Todo(273543270): Short term model is an internal information of
// AutomaticBrightnessController and shouldn't be exposed outside of that class
private boolean mShouldResetShortTermModel = false;
// Remembers whether the auto-brightness has been applied in the latest brightness update.
private boolean mAppliedAutoBrightness = false;
// The controller for the automatic brightness level.
@Nullable
private AutomaticBrightnessController mAutomaticBrightnessController;
// The system setting denoting if the auto-brightness for the current user is enabled or not
private boolean mUseAutoBrightness = false;
// Indicates if the auto-brightness is currently enabled or not. It's possible that even if
// the user has enabled the auto-brightness from the settings, it is disabled because the
// display is off
private boolean mIsAutoBrightnessEnabled = false;
// If the auto-brightness model for the last manual changes done by the user.
private boolean mIsShortTermModelActive = false;
// The BrightnessConfiguration currently being used
// Todo(273543270): BrightnessConfiguration is an internal implementation detail of
// AutomaticBrightnessController, and AutomaticBrightnessStrategy shouldn't be aware of its
// existence.
@Nullable
private BrightnessConfiguration mBrightnessConfiguration;
public AutomaticBrightnessStrategy(Context context, int displayId) {
mContext = context;
mDisplayId = displayId;
mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
/**
* Sets up the automatic brightness states of this class. Also configures
* AutomaticBrightnessController accounting for any manual changes made by the user.
*/
public void setAutoBrightnessState(int targetDisplayState,
boolean allowAutoBrightnessWhileDozingConfig,
float brightnessState, int brightnessReason, int policy,
float lastUserSetScreenBrightness, boolean userSetBrightnessChanged) {
final boolean autoBrightnessEnabledInDoze =
allowAutoBrightnessWhileDozingConfig
&& Display.isDozeState(targetDisplayState);
mIsAutoBrightnessEnabled = shouldUseAutoBrightness()
&& (targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze)
&& (Float.isNaN(brightnessState)
|| brightnessReason == BrightnessReason.REASON_TEMPORARY
|| brightnessReason == BrightnessReason.REASON_BOOST)
&& mAutomaticBrightnessController != null
&& brightnessReason != BrightnessReason.REASON_FOLLOWER;
final boolean autoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness()
&& !(targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze);
final int autoBrightnessState = mIsAutoBrightnessEnabled
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: autoBrightnessDisabledDueToDisplayOff
? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
accommodateUserBrightnessChanges(userSetBrightnessChanged, lastUserSetScreenBrightness,
policy, mBrightnessConfiguration, autoBrightnessState);
}
public boolean isAutoBrightnessEnabled() {
return mIsAutoBrightnessEnabled;
}
/**
* Updates the {@link BrightnessConfiguration} that is currently being used by the associated
* display.
*/
public void setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration,
boolean shouldResetShortTermModel) {
mBrightnessConfiguration = brightnessConfiguration;
setShouldResetShortTermModel(shouldResetShortTermModel);
}
/**
* Promotes the pending auto-brightness adjustments which are yet to be applied to the current
* adjustments. Note that this is not applying the new adjustments to the AutoBrightness mapping
* strategies, but is only accommodating the changes in this class.
*/
public boolean processPendingAutoBrightnessAdjustments() {
mAutoBrightnessAdjustmentChanged = false;
if (Float.isNaN(mPendingAutoBrightnessAdjustment)) {
return false;
}
if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) {
mPendingAutoBrightnessAdjustment = Float.NaN;
return false;
}
mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment;
mPendingAutoBrightnessAdjustment = Float.NaN;
mTemporaryAutoBrightnessAdjustment = Float.NaN;
mAutoBrightnessAdjustmentChanged = true;
return true;
}
/**
* Updates the associated AutomaticBrightnessController
*/
public void setAutomaticBrightnessController(
AutomaticBrightnessController automaticBrightnessController) {
if (automaticBrightnessController == mAutomaticBrightnessController) {
return;
}
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.stop();
}
mAutomaticBrightnessController = automaticBrightnessController;
}
/**
* Returns if the auto-brightness of the associated display has been enabled or not
*/
public boolean shouldUseAutoBrightness() {
return mUseAutoBrightness;
}
/**
* Sets the auto-brightness state of the associated display. Called when the user makes a change
* in the system setting to enable/disable the auto-brightness.
*/
public void setUseAutoBrightness(boolean useAutoBrightness) {
mUseAutoBrightness = useAutoBrightness;
}
/**
* Returns if the user made brightness change events(Typically when they interact with the
* brightness slider) were accommodated in the auto-brightness mapping strategies. This doesn't
* account for the latest changes that have been made by the user.
*/
public boolean isShortTermModelActive() {
return mIsShortTermModelActive;
}
/**
* Sets the pending auto-brightness adjustments in the system settings. Executed
* when there is a change in the brightness system setting, or when there is a user switch.
*/
public void updatePendingAutoBrightnessAdjustments(boolean userSwitch) {
final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
mPendingAutoBrightnessAdjustment = Float.isNaN(adj) ? Float.NaN
: BrightnessUtils.clampAbsoluteBrightness(adj);
if (userSwitch) {
processPendingAutoBrightnessAdjustments();
}
}
/**
* Sets the temporary auto-brightness adjustments
*/
public void setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment) {
mTemporaryAutoBrightnessAdjustment = temporaryAutoBrightnessAdjustment;
}
/**
* Dumps the state of this class.
*/
public void dump(PrintWriter writer) {
writer.println("AutomaticBrightnessStrategy:");
writer.println(" mDisplayId=" + mDisplayId);
writer.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
writer.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
writer.println(
" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
writer.println(" mShouldResetShortTermModel=" + mShouldResetShortTermModel);
writer.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
writer.println(" mAutoBrightnessAdjustmentChanged=" + mAutoBrightnessAdjustmentChanged);
writer.println(" mAppliedTemporaryAutoBrightnessAdjustment="
+ mAppliedTemporaryAutoBrightnessAdjustment);
writer.println(" mUseAutoBrightness=" + mUseAutoBrightness);
writer.println(" mWasShortTermModelActive=" + mIsShortTermModelActive);
writer.println(" mAutoBrightnessAdjustmentReasonsFlags="
+ mAutoBrightnessAdjustmentReasonsFlags);
}
/**
* Indicates if any auto-brightness adjustments have happened since the last auto-brightness was
* set.
*/
public boolean getAutoBrightnessAdjustmentChanged() {
return mAutoBrightnessAdjustmentChanged;
}
/**
* Returns whether the latest temporary auto-brightness adjustments have been applied or not
*/
public boolean isTemporaryAutoBrightnessAdjustmentApplied() {
return mAppliedTemporaryAutoBrightnessAdjustment;
}
/**
* Evaluates the target automatic brightness of the associated display.
*/
public float getAutomaticScreenBrightness() {
float brightness = (mAutomaticBrightnessController != null)
? mAutomaticBrightnessController.getAutomaticScreenBrightness()
: PowerManager.BRIGHTNESS_INVALID_FLOAT;
adjustAutomaticBrightnessStateIfValid(brightness);
return brightness;
}
/**
* Gets the auto-brightness adjustment flag change reason
*/
public int getAutoBrightnessAdjustmentReasonsFlags() {
return mAutoBrightnessAdjustmentReasonsFlags;
}
/**
* Returns if the auto brightness has been applied
*/
public boolean hasAppliedAutoBrightness() {
return mAppliedAutoBrightness;
}
/**
* Used to adjust the state of this class when the automatic brightness value for the
* associated display is valid
*/
@VisibleForTesting
void adjustAutomaticBrightnessStateIfValid(float brightnessState) {
mAutoBrightnessAdjustmentReasonsFlags = isTemporaryAutoBrightnessAdjustmentApplied()
? BrightnessReason.ADJUSTMENT_AUTO_TEMP
: BrightnessReason.ADJUSTMENT_AUTO;
mAppliedAutoBrightness = BrightnessUtils.isValidBrightnessValue(brightnessState)
|| brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT;
float newAutoBrightnessAdjustment =
(mAutomaticBrightnessController != null)
? mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()
: 0.0f;
if (!Float.isNaN(newAutoBrightnessAdjustment)
&& mAutoBrightnessAdjustment != newAutoBrightnessAdjustment) {
// If the auto-brightness controller has decided to change the adjustment value
// used, make sure that's reflected in settings.
putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
} else {
mAutoBrightnessAdjustmentReasonsFlags = 0;
}
}
/**
* Sets up the system to reset the short term model. Note that this will not reset the model
* right away, but ensures that the reset happens whenever the next brightness change happens
*/
@VisibleForTesting
void setShouldResetShortTermModel(boolean shouldResetShortTermModel) {
mShouldResetShortTermModel = shouldResetShortTermModel;
}
@VisibleForTesting
boolean shouldResetShortTermModel() {
return mShouldResetShortTermModel;
}
@VisibleForTesting
float getAutoBrightnessAdjustment() {
return mAutoBrightnessAdjustment;
}
@VisibleForTesting
float getPendingAutoBrightnessAdjustment() {
return mPendingAutoBrightnessAdjustment;
}
@VisibleForTesting
float getTemporaryAutoBrightnessAdjustment() {
return mTemporaryAutoBrightnessAdjustment;
}
@VisibleForTesting
void putAutoBrightnessAdjustmentSetting(float adjustment) {
if (mDisplayId == Display.DEFAULT_DISPLAY) {
mAutoBrightnessAdjustment = adjustment;
Settings.System.putFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment,
UserHandle.USER_CURRENT);
}
}
/**
* Sets if the auto-brightness is applied on the latest brightness change.
*/
@VisibleForTesting
void setAutoBrightnessApplied(boolean autoBrightnessApplied) {
mAppliedAutoBrightness = autoBrightnessApplied;
}
/**
* Accommodates the latest manual changes made by the user. Also updates {@link
* AutomaticBrightnessController} about the changes and configures it accordingly.
*/
@VisibleForTesting
void accommodateUserBrightnessChanges(boolean userSetBrightnessChanged,
float lastUserSetScreenBrightness, int policy,
BrightnessConfiguration brightnessConfiguration, int autoBrightnessState) {
// Update the pending auto-brightness adjustments if any. This typically checks and adjusts
// the state of the class if the user moves the brightness slider and has settled to a
// different value
processPendingAutoBrightnessAdjustments();
// Update the temporary auto-brightness adjustments if any. This typically checks and
// adjusts the state of this class if the user is in the process of moving the brightness
// slider, but hasn't settled to any value yet
float autoBrightnessAdjustment = updateTemporaryAutoBrightnessAdjustments();
mIsShortTermModelActive = false;
// Configure auto-brightness.
if (mAutomaticBrightnessController != null) {
// Accommodate user changes if any in the auto-brightness model
mAutomaticBrightnessController.configure(autoBrightnessState,
brightnessConfiguration,
lastUserSetScreenBrightness,
userSetBrightnessChanged, autoBrightnessAdjustment,
mAutoBrightnessAdjustmentChanged, policy, mShouldResetShortTermModel);
mShouldResetShortTermModel = false;
// We take note if the user brightness point is still being used in the current
// auto-brightness model.
mIsShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints();
}
}
/**
* Evaluates if there are any temporary auto-brightness adjustments which is not applied yet.
* Temporary brightness adjustments happen when the user moves the brightness slider in the
* auto-brightness mode, but hasn't settled to a value yet
*/
private float updateTemporaryAutoBrightnessAdjustments() {
mAppliedTemporaryAutoBrightnessAdjustment =
!Float.isNaN(mTemporaryAutoBrightnessAdjustment);
// We do not update the mAutoBrightnessAdjustment with mTemporaryAutoBrightnessAdjustment
// since we have not settled to a value yet
return mAppliedTemporaryAutoBrightnessAdjustment
? mTemporaryAutoBrightnessAdjustment : mAutoBrightnessAdjustment;
}
/**
* Returns the auto-brightness adjustment that is set in the system setting.
*/
private float getAutoBrightnessAdjustmentSetting() {
final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
return Float.isNaN(adj) ? 0.0f : BrightnessUtils.clampAbsoluteBrightness(adj);
}
}

View File

@@ -66,7 +66,6 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.server.LocalServices;
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.color.ColorDisplayService;
import com.android.server.display.layout.Layout;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
@@ -565,8 +564,8 @@ public final class DisplayPowerController2Test {
.thenReturn(brightness);
dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
.thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
@@ -603,8 +602,8 @@ public final class DisplayPowerController2Test {
.thenReturn(brightness);
dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
.thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState

View File

@@ -0,0 +1,329 @@
/*
* Copyright (C) 2023 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.brightness.strategy;
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.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.ContextWrapper;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.DisplayManagerInternal;
import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
import android.view.Display;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
import com.android.server.display.AutomaticBrightnessController;
import com.android.server.display.brightness.BrightnessReason;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class AutomaticBrightnessStrategyTest {
private static final int DISPLAY_ID = 0;
@Rule
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
@Mock
private AutomaticBrightnessController mAutomaticBrightnessController;
private BrightnessConfiguration mBrightnessConfiguration;
private float mDefaultScreenAutoBrightnessAdjustment;
private Context mContext;
private AutomaticBrightnessStrategy mAutomaticBrightnessStrategy;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext);
when(mContext.getContentResolver()).thenReturn(resolver);
mDefaultScreenAutoBrightnessAdjustment = Settings.System.getFloat(
mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, Float.NaN);
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.5f);
mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy(mContext, DISPLAY_ID);
mBrightnessConfiguration = new BrightnessConfiguration.Builder(
new float[]{0f, 1f}, new float[]{0, PowerManager.BRIGHTNESS_ON}).build();
when(mAutomaticBrightnessController.hasUserDataPoints()).thenReturn(true);
mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
mAutomaticBrightnessController);
mAutomaticBrightnessStrategy.setBrightnessConfiguration(mBrightnessConfiguration,
true);
}
@After
public void after() {
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, mDefaultScreenAutoBrightnessAdjustment);
}
@Test
public void setAutoBrightnessWhenDisabled() {
mAutomaticBrightnessStrategy.setUseAutoBrightness(false);
int targetDisplayState = Display.STATE_ON;
boolean allowAutoBrightnessWhileDozing = false;
float brightnessState = Float.NaN;
int brightnessReason = BrightnessReason.REASON_OVERRIDE;
int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
float lastUserSetBrightness = 0.2f;
boolean userSetBrightnessChanged = true;
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(true);
mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
allowAutoBrightnessWhileDozing, brightnessState, brightnessReason, policy,
lastUserSetBrightness, userSetBrightnessChanged);
verify(mAutomaticBrightnessController)
.configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
mBrightnessConfiguration,
lastUserSetBrightness,
userSetBrightnessChanged, 0.5f,
false, policy, true);
}
@Test
public void setAutoBrightnessWhenEnabledAndDisplayIsDozing() {
mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
int targetDisplayState = Display.STATE_DOZE;
float brightnessState = Float.NaN;
boolean allowAutoBrightnessWhileDozing = true;
int brightnessReason = BrightnessReason.REASON_DOZE;
int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
float lastUserSetBrightness = 0.2f;
boolean userSetBrightnessChanged = true;
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.4f);
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(false);
mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
allowAutoBrightnessWhileDozing, brightnessState, brightnessReason, policy,
lastUserSetBrightness, userSetBrightnessChanged);
verify(mAutomaticBrightnessController)
.configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
mBrightnessConfiguration,
lastUserSetBrightness,
userSetBrightnessChanged, 0.4f,
true, policy, true);
}
@Test
public void setAutoBrightnessWhenEnabledAndDisplayIsOn() {
mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
int targetDisplayState = Display.STATE_ON;
float brightnessState = Float.NaN;
boolean allowAutoBrightnessWhileDozing = false;
int brightnessReason = BrightnessReason.REASON_OVERRIDE;
float lastUserSetBrightness = 0.2f;
boolean userSetBrightnessChanged = true;
int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
float pendingBrightnessAdjustment = 0.1f;
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingBrightnessAdjustment);
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(false);
mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
allowAutoBrightnessWhileDozing, brightnessState, brightnessReason, policy,
lastUserSetBrightness, userSetBrightnessChanged);
verify(mAutomaticBrightnessController)
.configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
mBrightnessConfiguration,
lastUserSetBrightness,
userSetBrightnessChanged, pendingBrightnessAdjustment,
true, policy, true);
}
@Test
public void accommodateUserBrightnessChangesWorksAsExpected() {
// Verify the state if automaticBrightnessController is configured.
assertFalse(mAutomaticBrightnessStrategy.isShortTermModelActive());
boolean userSetBrightnessChanged = true;
float lastUserSetScreenBrightness = 0.2f;
int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
BrightnessConfiguration brightnessConfiguration = new BrightnessConfiguration.Builder(
new float[]{0f, 1f}, new float[]{0, PowerManager.BRIGHTNESS_ON}).build();
int autoBrightnessState = AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
float temporaryAutoBrightnessAdjustments = 0.4f;
mAutomaticBrightnessStrategy.setShouldResetShortTermModel(true);
setTemporaryAutoBrightnessAdjustment(temporaryAutoBrightnessAdjustments);
mAutomaticBrightnessStrategy.accommodateUserBrightnessChanges(userSetBrightnessChanged,
lastUserSetScreenBrightness, policy, brightnessConfiguration,
autoBrightnessState);
verify(mAutomaticBrightnessController).configure(autoBrightnessState,
brightnessConfiguration,
lastUserSetScreenBrightness,
userSetBrightnessChanged, temporaryAutoBrightnessAdjustments,
/* userChangedAutoBrightnessAdjustment= */ false, policy,
/* shouldResetShortTermModel= */ true);
assertTrue(mAutomaticBrightnessStrategy.isTemporaryAutoBrightnessAdjustmentApplied());
assertFalse(mAutomaticBrightnessStrategy.shouldResetShortTermModel());
assertTrue(mAutomaticBrightnessStrategy.isShortTermModelActive());
// Verify the state when automaticBrightnessController is not configured
setTemporaryAutoBrightnessAdjustment(Float.NaN);
mAutomaticBrightnessStrategy.setAutomaticBrightnessController(null);
mAutomaticBrightnessStrategy.setShouldResetShortTermModel(true);
mAutomaticBrightnessStrategy.accommodateUserBrightnessChanges(userSetBrightnessChanged,
lastUserSetScreenBrightness, policy, brightnessConfiguration,
autoBrightnessState);
assertFalse(mAutomaticBrightnessStrategy.isTemporaryAutoBrightnessAdjustmentApplied());
assertTrue(mAutomaticBrightnessStrategy.shouldResetShortTermModel());
assertFalse(mAutomaticBrightnessStrategy.isShortTermModelActive());
}
@Test
public void adjustAutomaticBrightnessStateIfValid() throws Settings.SettingNotFoundException {
float brightnessState = 0.3f;
float autoBrightnessAdjustment = 0.2f;
when(mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()).thenReturn(
autoBrightnessAdjustment);
mAutomaticBrightnessStrategy.adjustAutomaticBrightnessStateIfValid(brightnessState);
assertTrue(mAutomaticBrightnessStrategy.hasAppliedAutoBrightness());
assertEquals(autoBrightnessAdjustment,
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
assertEquals(autoBrightnessAdjustment, Settings.System.getFloatForUser(
mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
UserHandle.USER_CURRENT), 0.0f);
assertEquals(BrightnessReason.ADJUSTMENT_AUTO,
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentReasonsFlags());
float invalidBrightness = -0.5f;
mAutomaticBrightnessStrategy
.adjustAutomaticBrightnessStateIfValid(invalidBrightness);
assertFalse(mAutomaticBrightnessStrategy.hasAppliedAutoBrightness());
assertEquals(autoBrightnessAdjustment,
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
assertEquals(0,
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentReasonsFlags());
}
@Test
public void updatePendingAutoBrightnessAdjustments() {
// Verify the state when the pendingAutoBrightnessAdjustments are not present
setPendingAutoBrightnessAdjustment(Float.NaN);
assertFalse(mAutomaticBrightnessStrategy.processPendingAutoBrightnessAdjustments());
assertFalse(mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged());
// Verify the state when the pendingAutoBrightnessAdjustments are present, but
// pendingAutoBrightnessAdjustments and autoBrightnessAdjustments are the same
float autoBrightnessAdjustment = 0.3f;
setPendingAutoBrightnessAdjustment(autoBrightnessAdjustment);
setAutoBrightnessAdjustment(autoBrightnessAdjustment);
assertFalse(mAutomaticBrightnessStrategy.processPendingAutoBrightnessAdjustments());
assertFalse(mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged());
assertEquals(Float.NaN, mAutomaticBrightnessStrategy.getPendingAutoBrightnessAdjustment(),
0.0f);
// Verify the state when the pendingAutoBrightnessAdjustments are present, and
// pendingAutoBrightnessAdjustments and autoBrightnessAdjustments are not the same
float pendingAutoBrightnessAdjustment = 0.2f;
setPendingAutoBrightnessAdjustment(pendingAutoBrightnessAdjustment);
setTemporaryAutoBrightnessAdjustment(0.1f);
assertTrue(mAutomaticBrightnessStrategy.processPendingAutoBrightnessAdjustments());
assertTrue(mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged());
assertEquals(pendingAutoBrightnessAdjustment,
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
assertEquals(Float.NaN, mAutomaticBrightnessStrategy.getPendingAutoBrightnessAdjustment(),
0.0f);
assertEquals(Float.NaN, mAutomaticBrightnessStrategy.getTemporaryAutoBrightnessAdjustment(),
0.0f);
}
@Test
public void setAutomaticBrightnessWorksAsExpected() {
float automaticScreenBrightness = 0.3f;
AutomaticBrightnessController automaticBrightnessController = mock(
AutomaticBrightnessController.class);
when(automaticBrightnessController.getAutomaticScreenBrightness()).thenReturn(
automaticScreenBrightness);
mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
automaticBrightnessController);
assertEquals(automaticScreenBrightness,
mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(), 0.0f);
}
@Test
public void shouldUseAutoBrightness() {
mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
assertTrue(mAutomaticBrightnessStrategy.shouldUseAutoBrightness());
}
@Test
public void setPendingAutoBrightnessAdjustments() throws Settings.SettingNotFoundException {
float pendingAutoBrightnessAdjustments = 0.3f;
setPendingAutoBrightnessAdjustment(pendingAutoBrightnessAdjustments);
assertEquals(pendingAutoBrightnessAdjustments,
mAutomaticBrightnessStrategy.getPendingAutoBrightnessAdjustment(), 0.0f);
assertEquals(pendingAutoBrightnessAdjustments, Settings.System.getFloatForUser(
mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
UserHandle.USER_CURRENT), 0.0f);
}
@Test
public void setTemporaryAutoBrightnessAdjustment() {
float temporaryAutoBrightnessAdjustment = 0.3f;
mAutomaticBrightnessStrategy.setTemporaryAutoBrightnessAdjustment(
temporaryAutoBrightnessAdjustment);
assertEquals(temporaryAutoBrightnessAdjustment,
mAutomaticBrightnessStrategy.getTemporaryAutoBrightnessAdjustment(), 0.0f);
}
@Test
public void setAutoBrightnessApplied() {
mAutomaticBrightnessStrategy.setAutoBrightnessApplied(true);
assertTrue(mAutomaticBrightnessStrategy.hasAppliedAutoBrightness());
}
@Test
public void testVerifyNoAutoBrightnessAdjustmentsArePopulatedForNonDefaultDisplay() {
int newDisplayId = 1;
mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy(mContext, newDisplayId);
mAutomaticBrightnessStrategy.putAutoBrightnessAdjustmentSetting(0.3f);
assertEquals(0.5f, mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(),
0.0f);
}
private void setPendingAutoBrightnessAdjustment(float pendingAutoBrightnessAdjustment) {
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingAutoBrightnessAdjustment);
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(false);
}
private void setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment) {
mAutomaticBrightnessStrategy.setTemporaryAutoBrightnessAdjustment(
temporaryAutoBrightnessAdjustment);
}
private void setAutoBrightnessAdjustment(float autoBrightnessAdjustment) {
mAutomaticBrightnessStrategy.putAutoBrightnessAdjustmentSetting(autoBrightnessAdjustment);
}
}