Pass brightness ramp rate to follower displays

This CL also fixes an issue with DPC2 where the ramp rate with auto-brightness on would always be slow.

Bug: 281801095
Test: atest DisplayPowerControllerTest
Test: atest DisplayPowerController2Test
Test: atest AutomaticBrightnessStrategyTest
Change-Id: I0bcc0fa6c30c8d413cd2389962b3635e8f4ad5f6
This commit is contained in:
Piotr Wilczyński
2023-06-12 12:44:57 +00:00
parent b7186d7c91
commit 9b8f1d5863
7 changed files with 439 additions and 147 deletions

View File

@@ -512,6 +512,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// of the lead display that this DPC should follow.
private float mBrightnessToFollow;
// Indicates whether we should ramp slowly to the brightness value to follow.
private boolean mBrightnessToFollowSlowChange;
// 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;
@@ -812,7 +815,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
boolean slowChange) {
mBrightnessRangeController.onAmbientLuxChange(ambientLux);
if (nits < 0) {
mBrightnessToFollow = leadDisplayBrightness;
@@ -825,6 +829,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessToFollow = leadDisplayBrightness;
}
}
mBrightnessToFollowSlowChange = slowChange;
sendUpdatePowerState();
}
@@ -842,7 +847,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mDisplayBrightnessFollowers.remove(follower.getDisplayId());
mHandler.postAtTime(() -> follower.setBrightnessToFollow(
PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
/* ambientLux= */ 0), mClock.uptimeMillis());
/* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
}
}
@@ -852,7 +857,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i);
mHandler.postAtTime(() -> follower.setBrightnessToFollow(
PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
/* ambientLux= */ 0), mClock.uptimeMillis());
/* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
}
mDisplayBrightnessFollowers.clear();
}
@@ -1559,6 +1564,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
final int oldState = mPowerState.getScreenState();
animateScreenStateChange(state, performScreenOffTransition);
state = mPowerState.getScreenState();
boolean slowChange = false;
if (state == Display.STATE_OFF) {
brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
@@ -1567,6 +1573,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (Float.isNaN(brightnessState) && isValidBrightnessValue(mBrightnessToFollow)) {
brightnessState = mBrightnessToFollow;
slowChange = mBrightnessToFollowSlowChange;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_FOLLOWER);
}
@@ -1661,7 +1668,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
float rawBrightnessState = brightnessState;
// Apply auto-brightness.
boolean slowChange = false;
if (Float.isNaN(brightnessState)) {
float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
if (autoBrightnessEnabled) {
@@ -1740,6 +1746,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
}
float ambientLux = mAutomaticBrightnessController == null ? 0
: mAutomaticBrightnessController.getAmbientLux();
for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState),
ambientLux, slowChange);
}
// Now that a desired brightness has been calculated, apply brightness throttling. The
// dimming and low power transformations that follow can only dim brightness further.
//
@@ -1762,14 +1776,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAppliedThrottling = false;
}
float ambientLux = mAutomaticBrightnessController == null ? 0
: mAutomaticBrightnessController.getAmbientLux();
for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState),
ambientLux);
}
if (updateScreenBrightnessSetting) {
// Tell the rest of the system about the new brightness in case we had to change it
// for things like auto-brightness or high-brightness-mode. Note that we do this
@@ -2157,8 +2163,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken,
displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData,
return mInjector.getHighBrightnessModeController(mHandler, info.width, info.height,
displayToken, displayUniqueId, PowerManager.BRIGHTNESS_MIN,
PowerManager.BRIGHTNESS_MAX, hbmData,
new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@Override
public float getHdrBrightnessFromSdr(
@@ -2949,6 +2956,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
+ mPendingScreenBrightnessSetting);
pw.println(" mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
pw.println(" mBrightnessToFollow=" + mBrightnessToFollow);
pw.println(" mBrightnessToFollowSlowChange=" + mBrightnessToFollowSlowChange);
pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
pw.println(" mBrightnessReason=" + mBrightnessReason);
pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
@@ -3528,6 +3536,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
brightnessMapper
);
}
HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
Context context) {
return new HighBrightnessModeController(handler, width, height, displayToken,
displayUniqueId, brightnessMin, brightnessMax, hbmData, hdrBrightnessCfg,
hbmChangeCallback, hbmMetadata, context);
}
}
static class CachedBrightnessInfo {

View File

@@ -435,6 +435,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
@Nullable
private BrightnessMappingStrategy mIdleModeBrightnessMapper;
// Indicates whether we should ramp slowly to the brightness value to follow.
private boolean mBrightnessToFollowSlowChange;
private boolean mIsRbcActive;
// Animators.
@@ -1272,6 +1275,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// actual state instead of the desired one.
animateScreenStateChange(state, mDisplayStateController.shouldPerformScreenOffTransition());
state = mPowerState.getScreenState();
boolean slowChange = false;
final boolean userSetBrightnessChanged = mDisplayBrightnessController
.updateUserSetScreenBrightness();
@@ -1281,6 +1285,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
float rawBrightnessState = displayBrightnessState.getBrightness();
mBrightnessReasonTemp.set(displayBrightnessState.getBrightnessReason());
if (displayBrightnessState.getBrightnessReason().getReason()
== BrightnessReason.REASON_FOLLOWER) {
slowChange = mBrightnessToFollowSlowChange;
}
// Take note if the short term model was already active before applying the current
// request changes.
final boolean wasShortTermModelActive =
@@ -1305,7 +1314,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
boolean updateScreenBrightnessSetting = false;
float currentBrightnessSetting = mDisplayBrightnessController.getCurrentBrightness();
// Apply auto-brightness.
boolean slowChange = false;
int brightnessAdjustmentFlags = 0;
if (Float.isNaN(brightnessState)) {
if (mAutomaticBrightnessStrategy.isAutoBrightnessEnabled()) {
@@ -1322,10 +1330,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
brightnessAdjustmentFlags =
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentReasonsFlags();
updateScreenBrightnessSetting = currentBrightnessSetting != brightnessState;
mAutomaticBrightnessStrategy.setAutoBrightnessApplied(true);
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
}
} else {
mAutomaticBrightnessStrategy.setAutoBrightnessApplied(false);
}
}
} else {
@@ -1333,6 +1344,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// to clamping so that they don't go beyond the current max as specified by HBM
// Controller.
brightnessState = clampScreenBrightness(brightnessState);
mAutomaticBrightnessStrategy.setAutoBrightnessApplied(false);
}
// Use default brightness when dozing unless overridden.
@@ -1372,6 +1384,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
}
float ambientLux = mAutomaticBrightnessController == null ? 0
: mAutomaticBrightnessController.getAmbientLux();
for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
follower.setBrightnessToFollow(rawBrightnessState,
mDisplayBrightnessController.convertToNits(rawBrightnessState),
ambientLux, slowChange);
}
// Now that a desired brightness has been calculated, apply brightness throttling. The
// dimming and low power transformations that follow can only dim brightness further.
//
@@ -1394,15 +1415,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mAppliedThrottling = false;
}
float ambientLux = mAutomaticBrightnessController == null ? 0
: mAutomaticBrightnessController.getAmbientLux();
for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
follower.setBrightnessToFollow(rawBrightnessState,
mDisplayBrightnessController.convertToNits(rawBrightnessState),
ambientLux);
}
if (updateScreenBrightnessSetting) {
// Tell the rest of the system about the new brightness in case we had to change it
// for things like auto-brightness or high-brightness-mode. Note that we do this
@@ -1804,9 +1816,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken,
displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData,
(sdrBrightness, maxDesiredHdrSdrRatio) ->
return mInjector.getHighBrightnessModeController(mHandler, info.width, info.height,
displayToken, displayUniqueId, PowerManager.BRIGHTNESS_MIN,
PowerManager.BRIGHTNESS_MAX, hbmData, (sdrBrightness, maxDesiredHdrSdrRatio) ->
mDisplayDeviceConfig.getHdrBrightnessFromSdr(sdrBrightness,
maxDesiredHdrSdrRatio), modeChangeCallback, hbmMetadata, mContext);
}
@@ -2189,7 +2201,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
boolean slowChange) {
mBrightnessRangeController.onAmbientLuxChange(ambientLux);
if (nits < 0) {
mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
@@ -2202,6 +2215,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
}
}
mBrightnessToFollowSlowChange = slowChange;
sendUpdatePowerState();
}
@@ -2261,7 +2275,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayBrightnessFollowers.remove(follower.getDisplayId());
mHandler.postAtTime(() -> follower.setBrightnessToFollow(
PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
/* ambientLux= */ 0), mClock.uptimeMillis());
/* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
}
}
@@ -2271,7 +2285,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i);
mHandler.postAtTime(() -> follower.setBrightnessToFollow(
PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
/* ambientLux= */ 0), mClock.uptimeMillis());
/* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
}
mDisplayBrightnessFollowers.clear();
}
@@ -2341,6 +2355,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
pw.println(" mReportedToPolicy="
+ reportedToPolicyToString(mReportedScreenStateToPolicy));
pw.println(" mIsRbcActive=" + mIsRbcActive);
pw.println(" mBrightnessToFollowSlowChange=" + mBrightnessToFollowSlowChange);
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
mAutomaticBrightnessStrategy.dump(ipw);
@@ -2892,6 +2907,17 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
brightnessMapper
);
}
HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
Context context) {
return new HighBrightnessModeController(handler, width, height, displayToken,
displayUniqueId, brightnessMin, brightnessMax, hbmData, hdrBrightnessCfg,
hbmChangeCallback, hbmMetadata, context);
}
}
static class CachedBrightnessInfo {

View File

@@ -201,8 +201,10 @@ public interface DisplayPowerControllerInterface {
* @param nits The brightness value in nits if the device supports nits. Set to a negative
* number otherwise.
* @param ambientLux The lux value that will be passed to {@link HighBrightnessModeController}
* @param slowChange Indicates whether we should slowly animate to the given brightness value.
*/
void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux);
void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
boolean slowChange);
/**
* Add an additional display that will copy the brightness value from this display. This is used

View File

@@ -287,8 +287,6 @@ public class AutomaticBrightnessStrategy {
mAutoBrightnessAdjustmentReasonsFlags = isTemporaryAutoBrightnessAdjustmentApplied()
? BrightnessReason.ADJUSTMENT_AUTO_TEMP
: BrightnessReason.ADJUSTMENT_AUTO;
mAppliedAutoBrightness = BrightnessUtils.isValidBrightnessValue(brightnessState)
|| brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT;
float newAutoBrightnessAdjustment =
(mAutomaticBrightnessController != null)
? mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()
@@ -345,8 +343,7 @@ public class AutomaticBrightnessStrategy {
/**
* Sets if the auto-brightness is applied on the latest brightness change.
*/
@VisibleForTesting
void setAutoBrightnessApplied(boolean autoBrightnessApplied) {
public void setAutoBrightnessApplied(boolean autoBrightnessApplied) {
mAppliedAutoBrightness = autoBrightnessApplied;
}

View File

@@ -46,6 +46,7 @@ import android.hardware.SensorManager;
import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemProperties;
@@ -95,6 +96,10 @@ public final class DisplayPowerController2Test {
private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1;
private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789";
private static final float PROX_SENSOR_MAX_RANGE = 5;
private static final float BRIGHTNESS_RAMP_RATE_FAST_DECREASE = 0.3f;
private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f;
private OffsettableClock mClock;
private TestLooper mTestLooper;
@@ -296,6 +301,8 @@ public final class DisplayPowerController2Test {
public void testDisplayBrightnessFollowers_BothDpcsSupportNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -334,14 +341,18 @@ public final class DisplayPowerController2Test {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
public void testDisplayBrightnessFollowers_FollowerDoesNotSupportNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -362,14 +373,18 @@ public final class DisplayPowerController2Test {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
public void testDisplayBrightnessFollowers_LeadDpcDoesNotSupportNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -388,14 +403,18 @@ public final class DisplayPowerController2Test {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
public void testDisplayBrightnessFollowers_NeitherDpcSupportsNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -416,8 +435,10 @@ public final class DisplayPowerController2Test {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
@@ -425,24 +446,70 @@ public final class DisplayPowerController2Test {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
final float brightness = 0.4f;
final float nits = 300;
final float ambientLux = 3000;
when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
.thenReturn(brightness);
when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
.thenReturn(0.3f);
when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
DisplayPowerController2 followerDpc = mock(DisplayPowerController2.class);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
float leadBrightness = 0.1f;
float rawLeadBrightness = 0.3f;
float followerBrightness = 0.4f;
float nits = 300;
float ambientLux = 3000;
when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
.thenReturn(rawLeadBrightness);
when(mHolder.automaticBrightnessController
.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
.thenReturn(leadBrightness);
when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness))
.thenReturn(nits);
when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(followerBrightness);
mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
mHolder.dpc.addDisplayBrightnessFollower(followerDpc);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
verify(followerDpc).setBrightnessToFollow(brightness, nits, ambientLux);
verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
// One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow
verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux);
verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
clearInvocations(mHolder.animator, followerDpc.animator);
leadBrightness = 0.05f;
rawLeadBrightness = 0.2f;
followerBrightness = 0.3f;
nits = 200;
ambientLux = 2000;
when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
.thenReturn(rawLeadBrightness);
when(mHolder.automaticBrightnessController
.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
.thenReturn(leadBrightness);
when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness))
.thenReturn(nits);
when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(followerBrightness);
mHolder.dpc.updateBrightness();
advanceTime(1); // Run updatePowerState
// The second time, the animation rate should be slow
verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux);
verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
}
@Test
@@ -451,6 +518,9 @@ public final class DisplayPowerController2Test {
FOLLOWER_UNIQUE_ID);
DisplayPowerControllerHolder secondFollowerDpc = createDisplayPowerController(
SECOND_FOLLOWER_DISPLAY_ID, SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(secondFollowerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -472,9 +542,11 @@ public final class DisplayPowerController2Test {
when(followerDpc.brightnessSetting.getBrightness()).thenReturn(initialFollowerBrightness);
followerListener.onBrightnessChanged(initialFollowerBrightness);
advanceTime(1);
verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(followerDpc.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
mHolder.dpc.addDisplayBrightnessFollower(secondFollowerDpc.dpc);
@@ -491,17 +563,26 @@ public final class DisplayPowerController2Test {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(secondFollowerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
clearInvocations(mHolder.animator, followerDpc.animator, secondFollowerDpc.animator);
// Remove the first follower and validate it goes back to its original brightness.
mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc);
advanceTime(1);
verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
when(followerDpc.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
clearInvocations(followerDpc.animator);
// Change the brightness of the lead display and validate only the second follower responds
@@ -515,9 +596,11 @@ public final class DisplayPowerController2Test {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat());
verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
@@ -527,6 +610,9 @@ public final class DisplayPowerController2Test {
DisplayPowerControllerHolder secondFollowerHolder =
createDisplayPowerController(SECOND_FOLLOWER_DISPLAY_ID,
SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(secondFollowerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -556,10 +642,15 @@ public final class DisplayPowerController2Test {
followerListener.onBrightnessChanged(initialFollowerBrightness);
secondFollowerListener.onBrightnessChanged(initialFollowerBrightness);
advanceTime(1);
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(followerHolder.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
when(secondFollowerHolder.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
mHolder.dpc.addDisplayBrightnessFollower(followerHolder.dpc);
mHolder.dpc.addDisplayBrightnessFollower(secondFollowerHolder.dpc);
@@ -576,19 +667,25 @@ public final class DisplayPowerController2Test {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(secondFollowerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
clearInvocations(mHolder.animator, followerHolder.animator, secondFollowerHolder.animator);
// Stop the lead DPC and validate that the followers go back to their original brightness.
mHolder.dpc.stop();
advanceTime(1);
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
clearInvocations(followerHolder.animator, secondFollowerHolder.animator);
}
@@ -901,6 +998,14 @@ public final class DisplayPowerController2Test {
});
when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
.thenReturn(new int[0]);
when(displayDeviceConfigMock.getBrightnessRampFastDecrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE);
when(displayDeviceConfigMock.getBrightnessRampFastIncrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_FAST_INCREASE);
when(displayDeviceConfigMock.getBrightnessRampSlowDecrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE);
when(displayDeviceConfigMock.getBrightnessRampSlowIncrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE);
}
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
@@ -920,10 +1025,13 @@ public final class DisplayPowerController2Test {
final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
mock(ScreenOffBrightnessSensorController.class);
final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class);
when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
TestInjector injector = spy(new TestInjector(displayPowerState, animator,
automaticBrightnessController, wakelockController, brightnessMappingStrategy,
hysteresisLevels, screenOffBrightnessSensorController));
hysteresisLevels, screenOffBrightnessSensorController, hbmController));
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -941,8 +1049,8 @@ public final class DisplayPowerController2Test {
return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
animator, automaticBrightnessController, wakelockController,
screenOffBrightnessSensorController, hbmMetadata, brightnessMappingStrategy,
injector);
screenOffBrightnessSensorController, hbmController, hbmMetadata,
brightnessMappingStrategy, injector);
}
/**
@@ -958,6 +1066,7 @@ public final class DisplayPowerController2Test {
public final AutomaticBrightnessController automaticBrightnessController;
public final WakelockController wakelockController;
public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
public final HighBrightnessModeController hbmController;
public final HighBrightnessModeMetadata hbmMetadata;
public final BrightnessMappingStrategy brightnessMappingStrategy;
public final DisplayPowerController2.Injector injector;
@@ -968,6 +1077,7 @@ public final class DisplayPowerController2Test {
AutomaticBrightnessController automaticBrightnessController,
WakelockController wakelockController,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
HighBrightnessModeController hbmController,
HighBrightnessModeMetadata hbmMetadata,
BrightnessMappingStrategy brightnessMappingStrategy,
DisplayPowerController2.Injector injector) {
@@ -979,6 +1089,7 @@ public final class DisplayPowerController2Test {
this.automaticBrightnessController = automaticBrightnessController;
this.wakelockController = wakelockController;
this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
this.hbmController = hbmController;
this.hbmMetadata = hbmMetadata;
this.brightnessMappingStrategy = brightnessMappingStrategy;
this.injector = injector;
@@ -993,13 +1104,15 @@ public final class DisplayPowerController2Test {
private final BrightnessMappingStrategy mBrightnessMappingStrategy;
private final HysteresisLevels mHysteresisLevels;
private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
private final HighBrightnessModeController mHighBrightnessModeController;
TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
WakelockController wakelockController,
BrightnessMappingStrategy brightnessMappingStrategy,
HysteresisLevels hysteresisLevels,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController) {
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
HighBrightnessModeController highBrightnessModeController) {
mDisplayPowerState = dps;
mAnimator = animator;
mAutomaticBrightnessController = automaticBrightnessController;
@@ -1007,6 +1120,7 @@ public final class DisplayPowerController2Test {
mBrightnessMappingStrategy = brightnessMappingStrategy;
mHysteresisLevels = hysteresisLevels;
mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
mHighBrightnessModeController = highBrightnessModeController;
}
@Override
@@ -1100,5 +1214,15 @@ public final class DisplayPowerController2Test {
BrightnessMappingStrategy brightnessMapper) {
return mScreenOffBrightnessSensorController;
}
@Override
HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
Context context) {
return mHighBrightnessModeController;
}
}
}

View File

@@ -46,6 +46,7 @@ import android.hardware.SensorManager;
import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemProperties;
@@ -95,6 +96,10 @@ public final class DisplayPowerControllerTest {
private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1;
private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789";
private static final float PROX_SENSOR_MAX_RANGE = 5;
private static final float BRIGHTNESS_RAMP_RATE_FAST_DECREASE = 0.3f;
private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f;
private OffsettableClock mClock;
private TestLooper mTestLooper;
@@ -299,6 +304,8 @@ public final class DisplayPowerControllerTest {
public void testDisplayBrightnessFollowers_BothDpcsSupportNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -322,10 +329,13 @@ public final class DisplayPowerControllerTest {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness);
listener.onBrightnessChanged(leadBrightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
anyFloat());
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
clearInvocations(mHolder.animator, followerDpc.animator);
// Test the same float scale value
@@ -337,14 +347,18 @@ public final class DisplayPowerControllerTest {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
public void testDisplayBrightnessFollowers_FollowerDoesNotSupportNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -365,14 +379,18 @@ public final class DisplayPowerControllerTest {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
public void testDisplayBrightnessFollowers_LeadDpcDoesNotSupportNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -391,14 +409,18 @@ public final class DisplayPowerControllerTest {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
public void testDisplayBrightnessFollowers_NeitherDpcSupportsNits() {
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -419,8 +441,10 @@ public final class DisplayPowerControllerTest {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
@@ -428,38 +452,86 @@ public final class DisplayPowerControllerTest {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
final float brightness = 0.4f;
final float nits = 300;
final float ambientLux = 3000;
when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
.thenReturn(brightness);
when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
.thenReturn(0.3f);
when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
DisplayPowerControllerHolder followerDpc =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
DisplayPowerController followerDpc = mock(DisplayPowerController.class);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
float leadBrightness = 0.1f;
float rawLeadBrightness = 0.3f;
float followerBrightness = 0.4f;
float nits = 300;
float ambientLux = 3000;
when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
.thenReturn(rawLeadBrightness);
when(mHolder.automaticBrightnessController
.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
.thenReturn(leadBrightness);
when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness))
.thenReturn(nits);
when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(followerBrightness);
mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
mHolder.dpc.addDisplayBrightnessFollower(followerDpc);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
verify(followerDpc).setBrightnessToFollow(brightness, nits, ambientLux);
verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
// One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow
verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux);
verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
clearInvocations(mHolder.animator, followerDpc.animator);
leadBrightness = 0.05f;
rawLeadBrightness = 0.2f;
followerBrightness = 0.3f;
nits = 200;
ambientLux = 2000;
when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
.thenReturn(rawLeadBrightness);
when(mHolder.automaticBrightnessController
.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
.thenReturn(leadBrightness);
when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness))
.thenReturn(nits);
when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(followerBrightness);
mHolder.dpc.updateBrightness();
advanceTime(1); // Run updatePowerState
// The second time, the animation rate should be slow
verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux);
verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
}
@Test
public void testDisplayBrightnessFollowersRemoval_RemoveSingleFollower() {
DisplayPowerControllerHolder followerHolder =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
DisplayPowerControllerHolder secondFollowerHolder =
createDisplayPowerController(SECOND_FOLLOWER_DISPLAY_ID,
SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
DisplayPowerControllerHolder followerDpc = createDisplayPowerController(FOLLOWER_DISPLAY_ID,
FOLLOWER_UNIQUE_ID);
DisplayPowerControllerHolder secondFollowerDpc = createDisplayPowerController(
SECOND_FOLLOWER_DISPLAY_ID, SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(secondFollowerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
followerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
secondFollowerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
secondFollowerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
@@ -470,58 +542,71 @@ public final class DisplayPowerControllerTest {
// Set the initial brightness on the DPC we're going to remove so we have a fixed value for
// it to return to.
listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
verify(followerHolder.brightnessSetting).registerListener(listenerCaptor.capture());
verify(followerDpc.brightnessSetting).registerListener(listenerCaptor.capture());
BrightnessSetting.BrightnessSettingListener followerListener = listenerCaptor.getValue();
final float initialFollowerBrightness = 0.3f;
when(followerHolder.brightnessSetting.getBrightness()).thenReturn(
initialFollowerBrightness);
when(followerDpc.brightnessSetting.getBrightness()).thenReturn(initialFollowerBrightness);
followerListener.onBrightnessChanged(initialFollowerBrightness);
advanceTime(1);
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
mHolder.dpc.addDisplayBrightnessFollower(followerHolder.dpc);
mHolder.dpc.addDisplayBrightnessFollower(secondFollowerHolder.dpc);
clearInvocations(followerHolder.animator);
when(followerDpc.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
mHolder.dpc.addDisplayBrightnessFollower(secondFollowerDpc.dpc);
clearInvocations(followerDpc.animator);
// Validate both followers are correctly registered and receiving brightness updates
float brightness = 0.6f;
float nits = 600;
when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
when(followerHolder.automaticBrightnessController.convertToFloatScale(nits))
when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(brightness);
when(secondFollowerHolder.automaticBrightnessController.convertToFloatScale(nits))
when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(brightness);
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
clearInvocations(mHolder.animator, followerHolder.animator, secondFollowerHolder.animator);
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(secondFollowerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
clearInvocations(mHolder.animator, followerDpc.animator, secondFollowerDpc.animator);
// Remove the first follower and validate it goes back to its original brightness.
mHolder.dpc.removeDisplayBrightnessFollower(followerHolder.dpc);
mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc);
advanceTime(1);
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
clearInvocations(followerHolder.animator);
verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
when(followerDpc.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
clearInvocations(followerDpc.animator);
// Change the brightness of the lead display and validate only the second follower responds
brightness = 0.7f;
nits = 700;
when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
when(followerHolder.automaticBrightnessController.convertToFloatScale(nits))
when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(brightness);
when(secondFollowerHolder.automaticBrightnessController.convertToFloatScale(nits))
when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits))
.thenReturn(brightness);
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerHolder.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat());
verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
}
@Test
@@ -531,6 +616,9 @@ public final class DisplayPowerControllerTest {
DisplayPowerControllerHolder secondFollowerHolder =
createDisplayPowerController(SECOND_FOLLOWER_DISPLAY_ID,
SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(followerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(secondFollowerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
@@ -560,10 +648,15 @@ public final class DisplayPowerControllerTest {
followerListener.onBrightnessChanged(initialFollowerBrightness);
secondFollowerListener.onBrightnessChanged(initialFollowerBrightness);
advanceTime(1);
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(followerHolder.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
when(secondFollowerHolder.displayPowerState.getScreenBrightness())
.thenReturn(initialFollowerBrightness);
mHolder.dpc.addDisplayBrightnessFollower(followerHolder.dpc);
mHolder.dpc.addDisplayBrightnessFollower(secondFollowerHolder.dpc);
@@ -580,19 +673,25 @@ public final class DisplayPowerControllerTest {
when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
listener.onBrightnessChanged(brightness);
advanceTime(1); // Send messages, run updatePowerState
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
when(secondFollowerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
clearInvocations(mHolder.animator, followerHolder.animator, secondFollowerHolder.animator);
// Stop the lead DPC and validate that the followers go back to their original brightness.
mHolder.dpc.stop();
advanceTime(1);
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
clearInvocations(followerHolder.animator, secondFollowerHolder.animator);
}
@@ -907,6 +1006,14 @@ public final class DisplayPowerControllerTest {
});
when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
.thenReturn(new int[0]);
when(displayDeviceConfigMock.getBrightnessRampFastDecrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE);
when(displayDeviceConfigMock.getBrightnessRampFastIncrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_FAST_INCREASE);
when(displayDeviceConfigMock.getBrightnessRampSlowDecrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE);
when(displayDeviceConfigMock.getBrightnessRampSlowIncrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE);
}
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
@@ -925,10 +1032,13 @@ public final class DisplayPowerControllerTest {
final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
mock(ScreenOffBrightnessSensorController.class);
final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class);
when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
DisplayPowerController.Injector injector = spy(new TestInjector(displayPowerState, animator,
automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels,
screenOffBrightnessSensorController));
screenOffBrightnessSensorController, hbmController));
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -946,7 +1056,7 @@ public final class DisplayPowerControllerTest {
return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
animator, automaticBrightnessController, screenOffBrightnessSensorController,
hbmMetadata, brightnessMappingStrategy, injector);
hbmController, hbmMetadata, brightnessMappingStrategy, injector);
}
/**
@@ -961,6 +1071,7 @@ public final class DisplayPowerControllerTest {
public final DualRampAnimator<DisplayPowerState> animator;
public final AutomaticBrightnessController automaticBrightnessController;
public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
public final HighBrightnessModeController hbmController;
public final HighBrightnessModeMetadata hbmMetadata;
public final BrightnessMappingStrategy brightnessMappingStrategy;
public final DisplayPowerController.Injector injector;
@@ -970,6 +1081,7 @@ public final class DisplayPowerControllerTest {
DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
HighBrightnessModeController hbmController,
HighBrightnessModeMetadata hbmMetadata,
BrightnessMappingStrategy brightnessMappingStrategy,
DisplayPowerController.Injector injector) {
@@ -980,6 +1092,7 @@ public final class DisplayPowerControllerTest {
this.animator = animator;
this.automaticBrightnessController = automaticBrightnessController;
this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
this.hbmController = hbmController;
this.hbmMetadata = hbmMetadata;
this.brightnessMappingStrategy = brightnessMappingStrategy;
this.injector = injector;
@@ -993,18 +1106,21 @@ public final class DisplayPowerControllerTest {
private final BrightnessMappingStrategy mBrightnessMappingStrategy;
private final HysteresisLevels mHysteresisLevels;
private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
private final HighBrightnessModeController mHighBrightnessModeController;
TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
BrightnessMappingStrategy brightnessMappingStrategy,
HysteresisLevels hysteresisLevels,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController) {
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
HighBrightnessModeController highBrightnessModeController) {
mDisplayPowerState = dps;
mAnimator = animator;
mAutomaticBrightnessController = automaticBrightnessController;
mBrightnessMappingStrategy = brightnessMappingStrategy;
mHysteresisLevels = hysteresisLevels;
mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
mHighBrightnessModeController = highBrightnessModeController;
}
@Override
@@ -1076,5 +1192,15 @@ public final class DisplayPowerControllerTest {
BrightnessMappingStrategy brightnessMapper) {
return mScreenOffBrightnessSensorController;
}
@Override
HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
Context context) {
return mHighBrightnessModeController;
}
}
}

View File

@@ -210,7 +210,6 @@ public class AutomaticBrightnessStrategyTest {
when(mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()).thenReturn(
autoBrightnessAdjustment);
mAutomaticBrightnessStrategy.adjustAutomaticBrightnessStateIfValid(brightnessState);
assertTrue(mAutomaticBrightnessStrategy.hasAppliedAutoBrightness());
assertEquals(autoBrightnessAdjustment,
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
assertEquals(autoBrightnessAdjustment, Settings.System.getFloatForUser(
@@ -222,7 +221,6 @@ public class AutomaticBrightnessStrategyTest {
float invalidBrightness = -0.5f;
mAutomaticBrightnessStrategy
.adjustAutomaticBrightnessStateIfValid(invalidBrightness);
assertFalse(mAutomaticBrightnessStrategy.hasAppliedAutoBrightness());
assertEquals(autoBrightnessAdjustment,
mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
assertEquals(0,