Moving low power handling to LowPowerModeClamper
Bug: b/263362199 Test: atest BrightnessLowPowerModeModifierTest Change-Id: I663c5c848c1cca49db199466b47ccc8adbd234ff
This commit is contained in:
@@ -133,6 +133,13 @@ public final class DisplayBrightnessState {
|
||||
mShouldUseAutoBrightness, mIsSlowChange);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods to create builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* A DisplayBrightnessState's builder class.
|
||||
*/
|
||||
|
||||
@@ -347,7 +347,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
private boolean mDozing;
|
||||
|
||||
private boolean mAppliedDimming;
|
||||
private boolean mAppliedLowPower;
|
||||
|
||||
private boolean mAppliedThrottling;
|
||||
|
||||
// Reason for which the brightness was last changed. See {@link BrightnessReason} for more
|
||||
@@ -1465,24 +1465,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
slowChange = false;
|
||||
mAppliedDimming = false;
|
||||
}
|
||||
// If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
|
||||
// as long as it is above the minimum threshold.
|
||||
if (mPowerRequest.lowPowerMode) {
|
||||
if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
|
||||
final float brightnessFactor =
|
||||
Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
|
||||
final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor);
|
||||
brightnessState = Math.max(lowPowerBrightnessFloat, PowerManager.BRIGHTNESS_MIN);
|
||||
mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
|
||||
}
|
||||
if (!mAppliedLowPower) {
|
||||
slowChange = false;
|
||||
}
|
||||
mAppliedLowPower = true;
|
||||
} else if (mAppliedLowPower) {
|
||||
slowChange = false;
|
||||
mAppliedLowPower = false;
|
||||
}
|
||||
|
||||
DisplayBrightnessState clampedState = mBrightnessClamperController.clamp(mPowerRequest,
|
||||
brightnessState, slowChange);
|
||||
|
||||
brightnessState = clampedState.getBrightness();
|
||||
slowChange = clampedState.isSlowChange();
|
||||
mBrightnessReasonTemp.addModifier(clampedState.getBrightnessReason().getModifier());
|
||||
|
||||
// The current brightness to use has been calculated at this point, and HbmController should
|
||||
// be notified so that it can accurately calculate HDR or HBM levels. We specifically do it
|
||||
@@ -1540,8 +1529,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
// allowed range.
|
||||
float animateValue = clampScreenBrightness(brightnessState);
|
||||
|
||||
animateValue = mBrightnessClamperController.clamp(animateValue);
|
||||
|
||||
// If there are any HDR layers on the screen, we have a special brightness value that we
|
||||
// use instead. We still preserve the calculated brightness for Standard Dynamic Range
|
||||
// (SDR) layers, but the main brightness value will be the one for HDR.
|
||||
@@ -2408,7 +2395,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
pw.println(" mPowerRequest=" + mPowerRequest);
|
||||
pw.println(" mBrightnessReason=" + mBrightnessReason);
|
||||
pw.println(" mAppliedDimming=" + mAppliedDimming);
|
||||
pw.println(" mAppliedLowPower=" + mAppliedLowPower);
|
||||
pw.println(" mAppliedThrottling=" + mAppliedThrottling);
|
||||
pw.println(" mDozing=" + mDozing);
|
||||
pw.println(" mSkipRampState=" + skipRampStateToString(mSkipRampState));
|
||||
|
||||
@@ -21,6 +21,9 @@ import android.os.PowerManager;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Provides max allowed brightness
|
||||
*/
|
||||
abstract class BrightnessClamper<T> {
|
||||
|
||||
protected float mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.android.server.display.brightness.clamper.BrightnessClamper.Ty
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerExecutor;
|
||||
import android.os.PowerManager;
|
||||
@@ -28,6 +29,7 @@ import android.provider.DeviceConfigInterface;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.display.DisplayBrightnessState;
|
||||
import com.android.server.display.DisplayDeviceConfig;
|
||||
import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData;
|
||||
import com.android.server.display.feature.DeviceConfigParameterProvider;
|
||||
@@ -42,7 +44,7 @@ import java.util.concurrent.Executor;
|
||||
*/
|
||||
public class BrightnessClamperController {
|
||||
|
||||
private static final boolean ENABLED = false;
|
||||
private static final boolean THERMAL_ENABLED = false;
|
||||
|
||||
private final DeviceConfigParameterProvider mDeviceConfigParameterProvider;
|
||||
private final Handler mHandler;
|
||||
@@ -50,6 +52,8 @@ public class BrightnessClamperController {
|
||||
|
||||
private final Executor mExecutor;
|
||||
private final List<BrightnessClamper<? super DisplayDeviceData>> mClampers = new ArrayList<>();
|
||||
|
||||
private final List<BrightnessModifier> mModifiers = new ArrayList<>();
|
||||
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
|
||||
properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged);
|
||||
private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
|
||||
@@ -77,11 +81,12 @@ public class BrightnessClamperController {
|
||||
}
|
||||
};
|
||||
|
||||
if (ENABLED) {
|
||||
if (THERMAL_ENABLED) {
|
||||
mClampers.add(
|
||||
new BrightnessThermalClamper(handler, clamperChangeListenerInternal, data));
|
||||
start();
|
||||
}
|
||||
mModifiers.add(new BrightnessLowPowerModeModifier());
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,8 +100,18 @@ public class BrightnessClamperController {
|
||||
* Applies clamping
|
||||
* Called in DisplayControllerHandler
|
||||
*/
|
||||
public float clamp(float value) {
|
||||
return Math.min(value, mBrightnessCap);
|
||||
public DisplayBrightnessState clamp(DisplayManagerInternal.DisplayPowerRequest request,
|
||||
float brightnessValue, boolean slowChange) {
|
||||
float cappedBrightness = Math.min(brightnessValue, mBrightnessCap);
|
||||
|
||||
DisplayBrightnessState.Builder builder = DisplayBrightnessState.builder();
|
||||
builder.setIsSlowChange(slowChange);
|
||||
builder.setBrightness(cappedBrightness);
|
||||
|
||||
for (int i = 0; i < mModifiers.size(); i++) {
|
||||
mModifiers.get(i).apply(request, builder);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,6 +123,7 @@ public class BrightnessClamperController {
|
||||
writer.println(" mClamperType: " + mClamperType);
|
||||
IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " ");
|
||||
mClampers.forEach(clamper -> clamper.dump(ipw));
|
||||
mModifiers.forEach(modifier -> modifier.dump(ipw));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,8 +160,10 @@ public class BrightnessClamperController {
|
||||
}
|
||||
|
||||
private void start() {
|
||||
mDeviceConfigParameterProvider.addOnPropertiesChangedListener(
|
||||
mExecutor, mOnPropertiesChangedListener);
|
||||
if (!mClampers.isEmpty()) {
|
||||
mDeviceConfigParameterProvider.addOnPropertiesChangedListener(
|
||||
mExecutor, mOnPropertiesChangedListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.display.brightness.clamper;
|
||||
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import com.android.server.display.DisplayBrightnessState;
|
||||
import com.android.server.display.brightness.BrightnessReason;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
class BrightnessLowPowerModeModifier implements BrightnessModifier {
|
||||
|
||||
private boolean mAppliedLowPower = false;
|
||||
|
||||
@Override
|
||||
public void apply(DisplayManagerInternal.DisplayPowerRequest request,
|
||||
DisplayBrightnessState.Builder stateBuilder) {
|
||||
// If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
|
||||
// as long as it is above the minimum threshold.
|
||||
if (request.lowPowerMode) {
|
||||
float value = stateBuilder.getBrightness();
|
||||
if (value > PowerManager.BRIGHTNESS_MIN) {
|
||||
final float brightnessFactor =
|
||||
Math.min(request.screenLowPowerBrightnessFactor, 1);
|
||||
final float lowPowerBrightnessFloat = Math.max((value * brightnessFactor),
|
||||
PowerManager.BRIGHTNESS_MIN);
|
||||
stateBuilder.setBrightness(lowPowerBrightnessFloat);
|
||||
stateBuilder.getBrightnessReason().addModifier(BrightnessReason.MODIFIER_LOW_POWER);
|
||||
}
|
||||
if (!mAppliedLowPower) {
|
||||
stateBuilder.setIsSlowChange(false);
|
||||
}
|
||||
mAppliedLowPower = true;
|
||||
} else if (mAppliedLowPower) {
|
||||
stateBuilder.setIsSlowChange(false);
|
||||
mAppliedLowPower = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println("BrightnessLowPowerModeModifier:");
|
||||
pw.println(" mAppliedLowPower=" + mAppliedLowPower);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.display.brightness.clamper;
|
||||
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
|
||||
import com.android.server.display.DisplayBrightnessState;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Modifies current brightness based on request
|
||||
*/
|
||||
interface BrightnessModifier {
|
||||
|
||||
void apply(DisplayManagerInternal.DisplayPowerRequest request,
|
||||
DisplayBrightnessState.Builder builder);
|
||||
|
||||
void dump(PrintWriter pw);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.display.brightness.clamper;
|
||||
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.display.DisplayBrightnessState;
|
||||
import com.android.server.display.brightness.BrightnessReason;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@SmallTest
|
||||
public class BrightnessLowPowerModeModifierTest {
|
||||
private static final float FLOAT_TOLERANCE = 0.001f;
|
||||
private static final float DEFAULT_BRIGHTNESS = 0.5f;
|
||||
private static final float LOW_POWER_BRIGHTNESS_FACTOR = 0.8f;
|
||||
private static final float EXPECTED_LOW_POWER_BRIGHTNESS =
|
||||
DEFAULT_BRIGHTNESS * LOW_POWER_BRIGHTNESS_FACTOR;
|
||||
private final DisplayPowerRequest mRequest = new DisplayPowerRequest();
|
||||
private final DisplayBrightnessState.Builder mBuilder = prepareBuilder();
|
||||
private BrightnessLowPowerModeModifier mClamper;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mClamper = new BrightnessLowPowerModeModifier();
|
||||
mRequest.screenLowPowerBrightnessFactor = LOW_POWER_BRIGHTNESS_FACTOR;
|
||||
mRequest.lowPowerMode = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_lowPowerModeOff() {
|
||||
mRequest.lowPowerMode = false;
|
||||
|
||||
mClamper.apply(mRequest, mBuilder);
|
||||
|
||||
assertEquals(DEFAULT_BRIGHTNESS, mBuilder.getBrightness(), FLOAT_TOLERANCE);
|
||||
assertEquals(0, mBuilder.getBrightnessReason().getModifier());
|
||||
assertTrue(mBuilder.isSlowChange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_lowPowerModeOn() {
|
||||
mClamper.apply(mRequest, mBuilder);
|
||||
|
||||
assertEquals(EXPECTED_LOW_POWER_BRIGHTNESS, mBuilder.getBrightness(), FLOAT_TOLERANCE);
|
||||
assertEquals(BrightnessReason.MODIFIER_LOW_POWER,
|
||||
mBuilder.getBrightnessReason().getModifier());
|
||||
assertFalse(mBuilder.isSlowChange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_lowPowerModeOnAndLowPowerBrightnessFactorHigh() {
|
||||
mRequest.screenLowPowerBrightnessFactor = 1.1f;
|
||||
|
||||
mClamper.apply(mRequest, mBuilder);
|
||||
|
||||
assertEquals(DEFAULT_BRIGHTNESS, mBuilder.getBrightness(), FLOAT_TOLERANCE);
|
||||
assertEquals(BrightnessReason.MODIFIER_LOW_POWER,
|
||||
mBuilder.getBrightnessReason().getModifier());
|
||||
assertFalse(mBuilder.isSlowChange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_lowPowerModeOnAndMinBrightness() {
|
||||
mBuilder.setBrightness(0.0f);
|
||||
mClamper.apply(mRequest, mBuilder);
|
||||
|
||||
assertEquals(0.0f, mBuilder.getBrightness(), FLOAT_TOLERANCE);
|
||||
assertEquals(0, mBuilder.getBrightnessReason().getModifier());
|
||||
assertFalse(mBuilder.isSlowChange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_lowPowerModeOnAndLowPowerAlreadyApplied() {
|
||||
mClamper.apply(mRequest, mBuilder);
|
||||
DisplayBrightnessState.Builder builder = prepareBuilder();
|
||||
|
||||
mClamper.apply(mRequest, builder);
|
||||
|
||||
assertEquals(EXPECTED_LOW_POWER_BRIGHTNESS, builder.getBrightness(), FLOAT_TOLERANCE);
|
||||
assertEquals(BrightnessReason.MODIFIER_LOW_POWER,
|
||||
builder.getBrightnessReason().getModifier());
|
||||
assertTrue(builder.isSlowChange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_lowPowerModeOffAfterLowPowerOn() {
|
||||
mClamper.apply(mRequest, mBuilder);
|
||||
mRequest.lowPowerMode = false;
|
||||
DisplayBrightnessState.Builder builder = prepareBuilder();
|
||||
|
||||
mClamper.apply(mRequest, builder);
|
||||
|
||||
assertEquals(DEFAULT_BRIGHTNESS, builder.getBrightness(), FLOAT_TOLERANCE);
|
||||
assertEquals(0, builder.getBrightnessReason().getModifier());
|
||||
assertFalse(builder.isSlowChange());
|
||||
}
|
||||
|
||||
private DisplayBrightnessState.Builder prepareBuilder() {
|
||||
DisplayBrightnessState.Builder builder = DisplayBrightnessState.builder();
|
||||
builder.setBrightness(DEFAULT_BRIGHTNESS);
|
||||
builder.setIsSlowChange(true);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user