Add follower strategy

Bug: 241307563
Test: Flash to a device with multiple internal displays on, see that the brightness value is always shared between them.
Test: atest com.android.server.display
Change-Id: I3c54451a1ad1756060fcbaa87cf70c8ec9ba7f59
This commit is contained in:
Piotr Wilczyński
2022-12-14 15:53:57 +00:00
parent e83680e21e
commit 9a90d78c5a
27 changed files with 456 additions and 17 deletions

View File

@@ -1127,6 +1127,14 @@ class AutomaticBrightnessController {
}
}
public float convertToFloatScale(float nits) {
if (mCurrentBrightnessMapper != null) {
return mCurrentBrightnessMapper.convertToFloatScale(nits);
} else {
return -1.0f;
}
}
public void recalculateSplines(boolean applyAdjustment, float[] adjustment) {
mCurrentBrightnessMapper.recalculateSplines(applyAdjustment, adjustment);

View File

@@ -321,6 +321,13 @@ public abstract class BrightnessMappingStrategy {
*/
public abstract float convertToNits(float brightness);
/**
* Converts the provided nits value to a float value if possible.
*
* Returns -1.0f if there's no available mapping for the nits to float.
*/
public abstract float convertToFloatScale(float nits);
/**
* Adds a user interaction data point to the brightness mapping.
*
@@ -670,6 +677,11 @@ public abstract class BrightnessMappingStrategy {
return -1.0f;
}
@Override
public float convertToFloatScale(float nits) {
return -1.0f;
}
@Override
public void addUserDataPoint(float lux, float brightness) {
float unadjustedBrightness = getUnadjustedBrightness(lux);
@@ -912,6 +924,11 @@ public abstract class BrightnessMappingStrategy {
return mBrightnessToNitsSpline.interpolate(brightness);
}
@Override
public float convertToFloatScale(float nits) {
return mNitsToBrightnessSpline.interpolate(nits);
}
@Override
public void addUserDataPoint(float lux, float brightness) {
float unadjustedBrightness = getUnadjustedBrightness(lux);

View File

@@ -1655,6 +1655,9 @@ public final class DisplayManagerService extends SystemService {
return;
}
// TODO (b/265793751): Set this DPC as a follower of the default DPC if needed,
// clear this DPC's followers if it's not a lead display
final String uniqueId = device.getUniqueId();
HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
dpc.onDisplayChanged(hbmMetadata);

View File

@@ -54,6 +54,7 @@ import android.util.MathUtils;
import android.util.MutableFloat;
import android.util.MutableInt;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
import android.view.Display;
@@ -450,6 +451,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set.
private float mTemporaryScreenBrightness;
// This brightness value is set in concurrent displays mode. It is the brightness value
// of the lead display that this DPC should follow.
private float mBrightnessToFollow;
// 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;
@@ -499,6 +504,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private boolean mIsEnabled;
private boolean mIsInTransition;
// DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
// is one lead display, the additional displays follow the brightness value of the lead display.
@GuardedBy("mLock")
private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
new SparseArray();
/**
* Creates the display power controller.
*/
@@ -635,6 +646,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
loadProximitySensor();
mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
mBrightnessToFollow = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
@@ -701,6 +713,48 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
@Override
public int getDisplayId() {
return mDisplayId;
}
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits) {
if (mAutomaticBrightnessController == null || nits < 0) {
mBrightnessToFollow = leadDisplayBrightness;
} else {
float brightness = mAutomaticBrightnessController.convertToFloatScale(nits);
if (isValidBrightnessValue(brightness)) {
mBrightnessToFollow = brightness;
} else {
// The device does not support nits
mBrightnessToFollow = leadDisplayBrightness;
}
}
sendUpdatePowerState();
}
@Override
public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
synchronized (mLock) {
mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
}
sendUpdatePowerState();
}
@Override
public void clearDisplayBrightnessFollowers() {
SparseArray<DisplayPowerControllerInterface> followers;
synchronized (mLock) {
followers = mDisplayBrightnessFollowers.clone();
mDisplayBrightnessFollowers.clear();
}
for (int i = 0; i < followers.size(); i++) {
DisplayPowerControllerInterface follower = followers.valueAt(i);
follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1);
}
}
@Nullable
@Override
public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(
@@ -1241,6 +1295,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
int brightnessAdjustmentFlags = 0;
mBrightnessReasonTemp.set(null);
mTempBrightnessEvent.reset();
SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
synchronized (mLock) {
if (mStopped) {
return;
@@ -1269,6 +1324,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
mustNotify = !mDisplayReadyLocked;
displayBrightnessFollowers = mDisplayBrightnessFollowers.clone();
}
// Compute the basic display state using the policy.
@@ -1376,6 +1433,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
}
if (Float.isNaN(brightnessState) && isValidBrightnessValue(mBrightnessToFollow)) {
brightnessState = mBrightnessToFollow;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_FOLLOWER);
}
if ((Float.isNaN(brightnessState))
&& isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {
brightnessState = mPowerRequest.screenBrightnessOverride;
@@ -1557,6 +1619,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAppliedThrottling = false;
}
for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
follower.setBrightnessToFollow(brightnessState, convertToNits(brightnessState));
}
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
@@ -2668,6 +2735,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println(" mPendingScreenBrightnessSetting="
+ mPendingScreenBrightnessSetting);
pw.println(" mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
pw.println(" mBrightnessToFollow=" + mBrightnessToFollow);
pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
pw.println(" mBrightnessReason=" + mBrightnessReason);
pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);

View File

@@ -52,6 +52,7 @@ import android.util.MathUtils;
import android.util.MutableFloat;
import android.util.MutableInt;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import com.android.internal.R;
@@ -409,6 +410,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private boolean mIsEnabled;
private boolean mIsInTransition;
// DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
// is one lead display, the additional displays follow the brightness value of the lead display.
@GuardedBy("mLock")
private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
new SparseArray();
/**
* Creates the display power controller.
*/
@@ -1110,6 +1118,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
boolean mustInitialize = false;
int brightnessAdjustmentFlags = 0;
mTempBrightnessEvent.reset();
SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
synchronized (mLock) {
if (mStopped) {
return;
@@ -1138,6 +1147,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
mustNotify = !mDisplayReadyLocked;
displayBrightnessFollowers = mDisplayBrightnessFollowers.clone();
}
int state = mDisplayStateController
@@ -1321,6 +1332,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mAppliedThrottling = false;
}
for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
follower.setBrightnessToFollow(brightnessState, convertToNits(brightnessState));
}
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
@@ -2097,6 +2113,27 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayBrightnessController.setBrightness(brightnessValue);
}
@Override
public int getDisplayId() {
return mDisplayId;
}
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits) {
if (mAutomaticBrightnessController == null || nits < 0) {
mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
} else {
float brightness = mAutomaticBrightnessController.convertToFloatScale(nits);
if (BrightnessUtils.isValidBrightnessValue(brightness)) {
mDisplayBrightnessController.setBrightnessToFollow(brightness);
} else {
// The device does not support nits
mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
}
}
sendUpdatePowerState();
}
private void putAutoBrightnessAdjustmentSetting(float adjustment) {
if (mDisplayId == Display.DEFAULT_DISPLAY) {
mAutoBrightnessAdjustment = adjustment;
@@ -2146,6 +2183,27 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
return mAutomaticBrightnessController.convertToNits(brightness);
}
@Override
public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
synchronized (mLock) {
mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
}
sendUpdatePowerState();
}
@Override
public void clearDisplayBrightnessFollowers() {
SparseArray<DisplayPowerControllerInterface> followers;
synchronized (mLock) {
followers = mDisplayBrightnessFollowers.clone();
mDisplayBrightnessFollowers.clear();
}
for (int i = 0; i < followers.size(); i++) {
DisplayPowerControllerInterface follower = followers.valueAt(i);
follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1);
}
}
@Override
public void dump(final PrintWriter pw) {
synchronized (mLock) {

View File

@@ -161,4 +161,31 @@ public interface DisplayPowerControllerInterface {
* @param newUserId The new userId
*/
void onSwitchUser(int newUserId);
/**
* Get the ID of the display associated with this DPC.
* @return The display ID
*/
int getDisplayId();
/**
* Set the brightness to follow if this is an additional display in a set of concurrent
* displays.
* @param leadDisplayBrightness The brightness of the lead display in the set of concurrent
* displays
* @param nits The brightness value in nits if the device supports nits
*/
void setBrightnessToFollow(float leadDisplayBrightness, float nits);
/**
* Add an additional display that will copy the brightness value from this display. This is used
* when the device is in concurrent displays mode.
* @param follower The DPC that should copy the brightness value from this DPC
*/
void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower);
/**
* Clear all the additional displays following the brightness value of this display.
*/
void clearDisplayBrightnessFollowers();
}

View File

@@ -38,7 +38,8 @@ public final class BrightnessReason {
public static final int REASON_TEMPORARY = 7;
public static final int REASON_BOOST = 8;
public static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 9;
public static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
public static final int REASON_FOLLOWER = 10;
public static final int REASON_MAX = REASON_FOLLOWER;
public static final int MODIFIER_DIMMED = 0x1;
public static final int MODIFIER_LOW_POWER = 0x2;
@@ -193,6 +194,8 @@ public final class BrightnessReason {
return "boost";
case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
return "screen_off_brightness_sensor";
case REASON_FOLLOWER:
return "follower";
default:
return Integer.toString(reason);
}

View File

@@ -128,6 +128,16 @@ public final class DisplayBrightnessController {
}
}
/**
* Sets the brightness to follow
*/
public void setBrightnessToFollow(Float brightnessToFollow) {
synchronized (mLock) {
mDisplayBrightnessStrategySelector.getFollowerDisplayBrightnessStrategy()
.setBrightnessToFollow(brightnessToFollow);
}
}
/**
* Returns a boolean flag indicating if the light sensor is to be used to decide the screen
* brightness when dozing

View File

@@ -28,6 +28,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.brightness.strategy.BoostBrightnessStrategy;
import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy;
import com.android.server.display.brightness.strategy.DozeBrightnessStrategy;
import com.android.server.display.brightness.strategy.FollowerBrightnessStrategy;
import com.android.server.display.brightness.strategy.InvalidBrightnessStrategy;
import com.android.server.display.brightness.strategy.OverrideBrightnessStrategy;
import com.android.server.display.brightness.strategy.ScreenOffBrightnessStrategy;
@@ -55,6 +56,8 @@ public class DisplayBrightnessStrategySelector {
private final TemporaryBrightnessStrategy mTemporaryBrightnessStrategy;
// The brightness strategy used to manage the brightness state when boost is requested
private final BoostBrightnessStrategy mBoostBrightnessStrategy;
// The brightness strategy used for additional displays
private final FollowerBrightnessStrategy mFollowerBrightnessStrategy;
// The brightness strategy used to manage the brightness state when the request is invalid.
private final InvalidBrightnessStrategy mInvalidBrightnessStrategy;
@@ -76,6 +79,7 @@ public class DisplayBrightnessStrategySelector {
mOverrideBrightnessStrategy = injector.getOverrideBrightnessStrategy();
mTemporaryBrightnessStrategy = injector.getTemporaryBrightnessStrategy();
mBoostBrightnessStrategy = injector.getBoostBrightnessStrategy();
mFollowerBrightnessStrategy = injector.getFollowerBrightnessStrategy(displayId);
mInvalidBrightnessStrategy = injector.getInvalidBrightnessStrategy();
mAllowAutoBrightnessWhileDozingConfig = context.getResources().getBoolean(
R.bool.config_allowAutoBrightnessWhileDozing);
@@ -93,10 +97,13 @@ public class DisplayBrightnessStrategySelector {
DisplayBrightnessStrategy displayBrightnessStrategy = mInvalidBrightnessStrategy;
if (targetDisplayState == Display.STATE_OFF) {
displayBrightnessStrategy = mScreenOffBrightnessStrategy;
} else if (displayPowerRequest.boostScreenBrightness) {
displayBrightnessStrategy = mBoostBrightnessStrategy;
} else if (shouldUseDozeBrightnessStrategy(displayPowerRequest)) {
displayBrightnessStrategy = mDozeBrightnessStrategy;
} else if (BrightnessUtils.isValidBrightnessValue(
mFollowerBrightnessStrategy.getBrightnessToFollow())) {
displayBrightnessStrategy = mFollowerBrightnessStrategy;
} else if (displayPowerRequest.boostScreenBrightness) {
displayBrightnessStrategy = mBoostBrightnessStrategy;
} else if (BrightnessUtils
.isValidBrightnessValue(displayPowerRequest.screenBrightnessOverride)) {
displayBrightnessStrategy = mOverrideBrightnessStrategy;
@@ -119,6 +126,10 @@ public class DisplayBrightnessStrategySelector {
return mTemporaryBrightnessStrategy;
}
public FollowerBrightnessStrategy getFollowerDisplayBrightnessStrategy() {
return mFollowerBrightnessStrategy;
}
/**
* Returns a boolean flag indicating if the light sensor is to be used to decide the screen
* brightness when dozing
@@ -180,6 +191,10 @@ public class DisplayBrightnessStrategySelector {
return new BoostBrightnessStrategy();
}
FollowerBrightnessStrategy getFollowerBrightnessStrategy(int displayId) {
return new FollowerBrightnessStrategy(displayId);
}
InvalidBrightnessStrategy getInvalidBrightnessStrategy() {
return new InvalidBrightnessStrategy();
}

View File

@@ -35,7 +35,8 @@ public class BoostBrightnessStrategy implements DisplayBrightnessStrategy {
@Override
public DisplayBrightnessState updateBrightness(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
// Todo(brup): Introduce a validator class and add validations before setting the brightness
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
DisplayBrightnessState displayBrightnessState =
BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_BOOST,
PowerManager.BRIGHTNESS_MAX,

View File

@@ -30,7 +30,8 @@ public class DozeBrightnessStrategy implements DisplayBrightnessStrategy {
@Override
public DisplayBrightnessState updateBrightness(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
// Todo(brup): Introduce a validator class and add validations before setting the brightness
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_DOZE,
displayPowerRequest.dozeScreenBrightness, displayPowerRequest.dozeScreenBrightness);
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2022 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.hardware.display.DisplayManagerInternal;
import android.os.PowerManager;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.brightness.BrightnessUtils;
import java.io.PrintWriter;
/**
* Manages the brightness of an additional display that copies the brightness value from the lead
* display when the device is using concurrent displays.
*/
public class FollowerBrightnessStrategy implements DisplayBrightnessStrategy {
// The ID of the LogicalDisplay using this strategy.
private final int mDisplayId;
// Set to PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no brightness to follow set.
private float mBrightnessToFollow;
public FollowerBrightnessStrategy(int displayId) {
mDisplayId = displayId;
mBrightnessToFollow = PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
@Override
public DisplayBrightnessState updateBrightness(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_FOLLOWER,
mBrightnessToFollow, mBrightnessToFollow);
}
@Override
public String getName() {
return "FollowerBrightnessStrategy";
}
public float getBrightnessToFollow() {
return mBrightnessToFollow;
}
public void setBrightnessToFollow(float brightnessToFollow) {
mBrightnessToFollow = brightnessToFollow;
}
/**
* Dumps the state of this class.
*/
public void dump(PrintWriter writer) {
writer.println("FollowerBrightnessStrategy:");
writer.println(" mDisplayId=" + mDisplayId);
writer.println(" mBrightnessToFollow:" + mBrightnessToFollow);
}
}

View File

@@ -29,7 +29,8 @@ public class OverrideBrightnessStrategy implements DisplayBrightnessStrategy {
@Override
public DisplayBrightnessState updateBrightness(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
// Todo(brup): Introduce a validator class and add validations before setting the brightness
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_OVERRIDE,
displayPowerRequest.screenBrightnessOverride,
displayPowerRequest.screenBrightnessOverride);

View File

@@ -30,7 +30,8 @@ public class ScreenOffBrightnessStrategy implements DisplayBrightnessStrategy {
@Override
public DisplayBrightnessState updateBrightness(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
// Todo(brup): Introduce a validator class and add validations before setting the brightness
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_SCREEN_OFF,
PowerManager.BRIGHTNESS_OFF_FLOAT,
PowerManager.BRIGHTNESS_OFF_FLOAT);

View File

@@ -43,7 +43,8 @@ public class TemporaryBrightnessStrategy implements DisplayBrightnessStrategy {
@Override
public DisplayBrightnessState updateBrightness(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
// Todo(brup): Introduce a validator class and add validations before setting the brightness
// Todo(b/241308599): Introduce a validator class and add validations before setting
// the brightness
DisplayBrightnessState displayBrightnessState =
BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_TEMPORARY,
mTemporaryScreenBrightness,

View File

@@ -18,6 +18,8 @@ package com.android.server.display;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
@@ -253,4 +255,35 @@ public final class DisplayPowerController2Test {
});
when(mDisplayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
}
@Test
public void testDisplayBrightnessFollowers() {
setUpDisplay(DISPLAY_ID, UNIQUE_DISPLAY_ID);
DisplayPowerController2 defaultDpc = new DisplayPowerController2(
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
}, mHighBrightnessModeMetadataMock);
DisplayPowerController2 followerDpc = new DisplayPowerController2(
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
}, mHighBrightnessModeMetadataMock);
defaultDpc.addDisplayBrightnessFollower(followerDpc);
defaultDpc.setBrightness(0.3f);
assertEquals(defaultDpc.getBrightnessInfo().brightness,
followerDpc.getBrightnessInfo().brightness, 0);
defaultDpc.setBrightness(0.6f);
assertEquals(defaultDpc.getBrightnessInfo().brightness,
followerDpc.getBrightnessInfo().brightness, 0);
float brightness = 0.1f;
defaultDpc.clearDisplayBrightnessFollowers();
defaultDpc.setBrightness(brightness);
assertNotEquals(brightness, followerDpc.getBrightnessInfo().brightness, 0);
}
}

View File

@@ -19,6 +19,8 @@ package com.android.server.display;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
@@ -235,4 +237,35 @@ public final class DisplayPowerControllerTest {
});
when(mDisplayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
}
@Test
public void testDisplayBrightnessFollowers() {
setUpDisplay(DISPLAY_ID, UNIQUE_DISPLAY_ID);
DisplayPowerController defaultDpc = new DisplayPowerController(
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
}, mHighBrightnessModeMetadataMock);
DisplayPowerController followerDpc = new DisplayPowerController(
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
}, mHighBrightnessModeMetadataMock);
defaultDpc.addDisplayBrightnessFollower(followerDpc);
defaultDpc.setBrightness(0.3f);
assertEquals(defaultDpc.getBrightnessInfo().brightness,
followerDpc.getBrightnessInfo().brightness, 0);
defaultDpc.setBrightness(0.6f);
assertEquals(defaultDpc.getBrightnessInfo().brightness,
followerDpc.getBrightnessInfo().brightness, 0);
float brightness = 0.1f;
defaultDpc.clearDisplayBrightnessFollowers();
defaultDpc.setBrightness(brightness);
assertNotEquals(brightness, followerDpc.getBrightnessInfo().brightness, 0);
}
}

View File

@@ -164,7 +164,7 @@ public final class DisplayDeviceConfigTest {
assertArrayEquals(new int[]{-1, 10, 20, 30, 40},
mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux());
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
// Todo: Add asserts for BrightnessThrottlingData, DensityMapping,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
}
@@ -236,7 +236,7 @@ public final class DisplayDeviceConfigTest {
assertArrayEquals(mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(),
HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
// Todo: Add asserts for BrightnessThrottlingData, DensityMapping,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
}

View File

@@ -65,7 +65,7 @@ public final class BrightnessReasonTest {
@Test
public void setReasonDoesntSetIfModifierIsBeyondExtremes() {
int extremeReason = 10;
int extremeReason = BrightnessReason.REASON_MAX + 1;
mBrightnessReason.setReason(extremeReason);
assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_DOZE);

View File

@@ -75,7 +75,7 @@ public final class DisplayBrightnessControllerTest {
}
@Test
public void updateBrightness() {
public void testUpdateBrightness() {
DisplayPowerRequest displayPowerRequest = mock(DisplayPowerRequest.class);
DisplayBrightnessStrategy displayBrightnessStrategy = mock(DisplayBrightnessStrategy.class);
int targetDisplayState = Display.STATE_DOZE;

View File

@@ -31,6 +31,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
import com.android.server.display.brightness.strategy.BoostBrightnessStrategy;
import com.android.server.display.brightness.strategy.DozeBrightnessStrategy;
import com.android.server.display.brightness.strategy.FollowerBrightnessStrategy;
import com.android.server.display.brightness.strategy.InvalidBrightnessStrategy;
import com.android.server.display.brightness.strategy.OverrideBrightnessStrategy;
import com.android.server.display.brightness.strategy.ScreenOffBrightnessStrategy;
@@ -61,6 +62,8 @@ public final class DisplayBrightnessStrategySelectorTest {
@Mock
private InvalidBrightnessStrategy mInvalidBrightnessStrategy;
@Mock
private FollowerBrightnessStrategy mFollowerBrightnessStrategy;
@Mock
private Context mContext;
@Mock
private Resources mResources;
@@ -99,6 +102,11 @@ public final class DisplayBrightnessStrategySelectorTest {
return mBoostBrightnessStrategy;
}
@Override
FollowerBrightnessStrategy getFollowerBrightnessStrategy(int displayId) {
return mFollowerBrightnessStrategy;
}
@Override
InvalidBrightnessStrategy getInvalidBrightnessStrategy() {
return mInvalidBrightnessStrategy;
@@ -133,6 +141,7 @@ public final class DisplayBrightnessStrategySelectorTest {
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
displayPowerRequest.screenBrightnessOverride = 0.4f;
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest,
Display.STATE_ON), mOverrideBrightnessStrategy);
}
@@ -142,6 +151,7 @@ public final class DisplayBrightnessStrategySelectorTest {
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
displayPowerRequest.screenBrightnessOverride = Float.NaN;
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(0.3f);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest,
Display.STATE_ON), mTemporaryBrightnessStrategy);
@@ -152,6 +162,7 @@ public final class DisplayBrightnessStrategySelectorTest {
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
displayPowerRequest.boostScreenBrightness = true;
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
displayPowerRequest.screenBrightnessOverride = Float.NaN;
when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(Float.NaN);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest,
@@ -163,8 +174,18 @@ public final class DisplayBrightnessStrategySelectorTest {
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
displayPowerRequest.screenBrightnessOverride = Float.NaN;
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(Float.NaN);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest,
Display.STATE_ON), mInvalidBrightnessStrategy);
}
@Test
public void selectStrategySelectsFollowerStrategyWhenValid() {
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(0.3f);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest,
Display.STATE_ON), mFollowerBrightnessStrategy);
}
}

View File

@@ -44,7 +44,7 @@ public class BoostBrightnessStrategyTest {
}
@Test
public void updateBrightnessWorksAsExpectedWhenBoostBrightnessIsRequested() {
public void testUpdateBrightnessWhenBoostBrightnessIsRequested() {
DisplayManagerInternal.DisplayPowerRequest
displayPowerRequest = new DisplayManagerInternal.DisplayPowerRequest();
displayPowerRequest.boostScreenBrightness = true;

View File

@@ -41,7 +41,7 @@ public class DozeBrightnessStrategyTest {
}
@Test
public void updateBrightnessWorksAsExpectedWhenScreenDozeStateIsRequested() {
public void testUpdateBrightnessWhenScreenDozeStateIsRequested() {
DisplayPowerRequest displayPowerRequest = new DisplayPowerRequest();
float dozeScreenBrightness = 0.2f;
displayPowerRequest.dozeScreenBrightness = dozeScreenBrightness;

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2022 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 android.hardware.display.DisplayManagerInternal;
import android.view.Display;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.brightness.BrightnessReason;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class FollowerBrightnessStrategyTest {
private FollowerBrightnessStrategy mFollowerBrightnessStrategy;
@Before
public void before() {
mFollowerBrightnessStrategy = new FollowerBrightnessStrategy(Display.DEFAULT_DISPLAY);
}
@Test
public void testUpdateBrightness() {
DisplayManagerInternal.DisplayPowerRequest
displayPowerRequest = new DisplayManagerInternal.DisplayPowerRequest();
float brightnessToFollow = 0.2f;
mFollowerBrightnessStrategy.setBrightnessToFollow(brightnessToFollow);
BrightnessReason brightnessReason = new BrightnessReason();
brightnessReason.setReason(BrightnessReason.REASON_FOLLOWER);
DisplayBrightnessState expectedDisplayBrightnessState =
new DisplayBrightnessState.Builder()
.setBrightness(brightnessToFollow)
.setBrightnessReason(brightnessReason)
.setSdrBrightness(brightnessToFollow)
.build();
DisplayBrightnessState updatedDisplayBrightnessState =
mFollowerBrightnessStrategy.updateBrightness(displayPowerRequest);
assertEquals(expectedDisplayBrightnessState, updatedDisplayBrightnessState);
}
}

View File

@@ -43,7 +43,7 @@ public class OverrideBrightnessStrategyTest {
}
@Test
public void updateBrightnessWorksAsExpectedWhenScreenDozeStateIsRequested() {
public void testUpdateBrightnessWhenScreenDozeStateIsRequested() {
DisplayManagerInternal.DisplayPowerRequest
displayPowerRequest = new DisplayManagerInternal.DisplayPowerRequest();
float overrideBrightness = 0.2f;

View File

@@ -43,7 +43,7 @@ public final class ScreenOffBrightnessStrategyTest {
}
@Test
public void updateBrightnessWorksAsExpectedWhenScreenOffDisplayState() {
public void testUpdateBrightnessWhenScreenOffDisplayState() {
DisplayPowerRequest displayPowerRequest = new DisplayPowerRequest();
BrightnessReason brightnessReason = new BrightnessReason();
brightnessReason.setReason(BrightnessReason.REASON_SCREEN_OFF);

View File

@@ -43,7 +43,7 @@ public class TemporaryBrightnessStrategyTest {
}
@Test
public void updateBrightnessWorksAsExpectedWhenTemporaryBrightnessIsSet() {
public void testUpdateBrightnessWhenTemporaryBrightnessIsSet() {
DisplayManagerInternal.DisplayPowerRequest
displayPowerRequest = new DisplayManagerInternal.DisplayPowerRequest();
float temporaryBrightness = 0.2f;