Merge "Moving low power handling to LowPowerModeClamper" into udc-qpr-dev

This commit is contained in:
Oleg Petšjonkin
2023-08-09 16:04:04 +00:00
committed by Android (Google) Code Review
7 changed files with 264 additions and 29 deletions

View File

@@ -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.
*/

View File

@@ -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));

View File

@@ -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;

View File

@@ -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);
}
}
/**

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}