Merge "Add limitations to HDR." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5b31467f3b
@@ -778,7 +778,6 @@ class AutomaticBrightnessController {
|
|||||||
mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness));
|
mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness));
|
||||||
mScreenDarkeningThreshold = clampScreenBrightness(
|
mScreenDarkeningThreshold = clampScreenBrightness(
|
||||||
mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness));
|
mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness));
|
||||||
mHbmController.onAutoBrightnessChanged(mScreenAutoBrightness);
|
|
||||||
|
|
||||||
if (sendUpdate) {
|
if (sendUpdate) {
|
||||||
mCallbacks.updateBrightness();
|
mCallbacks.updateBrightness();
|
||||||
|
|||||||
@@ -1281,6 +1281,11 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
|
sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
|
||||||
scheduleTraversalLocked(false);
|
scheduleTraversalLocked(false);
|
||||||
mPersistentDataStore.saveIfNeeded();
|
mPersistentDataStore.saveIfNeeded();
|
||||||
|
|
||||||
|
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
|
||||||
|
if (dpc != null) {
|
||||||
|
dpc.onDisplayChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLogicalDisplayFrameRateOverridesChangedLocked(
|
private void handleLogicalDisplayFrameRateOverridesChangedLocked(
|
||||||
@@ -1312,11 +1317,6 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
if (work != null) {
|
if (work != null) {
|
||||||
mHandler.post(work);
|
mHandler.post(work);
|
||||||
}
|
}
|
||||||
final int displayId = display.getDisplayIdLocked();
|
|
||||||
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
|
|
||||||
if (dpc != null) {
|
|
||||||
dpc.onDisplayChanged();
|
|
||||||
}
|
|
||||||
handleLogicalDisplayChangedLocked(display);
|
handleLogicalDisplayChangedLocked(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -511,7 +511,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
mSkipScreenOnBrightnessRamp = resources.getBoolean(
|
mSkipScreenOnBrightnessRamp = resources.getBoolean(
|
||||||
com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
|
com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
|
||||||
|
|
||||||
mHbmController = createHbmController();
|
mHbmController = createHbmControllerLocked();
|
||||||
|
|
||||||
// Seed the cached brightness
|
// Seed the cached brightness
|
||||||
saveBrightnessInfo(getScreenBrightnessSetting());
|
saveBrightnessInfo(getScreenBrightnessSetting());
|
||||||
@@ -717,6 +717,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
final String uniqueId = device.getUniqueId();
|
final String uniqueId = device.getUniqueId();
|
||||||
final DisplayDeviceConfig config = device.getDisplayDeviceConfig();
|
final DisplayDeviceConfig config = device.getDisplayDeviceConfig();
|
||||||
final IBinder token = device.getDisplayTokenLocked();
|
final IBinder token = device.getDisplayTokenLocked();
|
||||||
|
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
|
||||||
mHandler.post(() -> {
|
mHandler.post(() -> {
|
||||||
if (mDisplayDevice == device) {
|
if (mDisplayDevice == device) {
|
||||||
return;
|
return;
|
||||||
@@ -724,7 +725,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
mDisplayDevice = device;
|
mDisplayDevice = device;
|
||||||
mUniqueDisplayId = uniqueId;
|
mUniqueDisplayId = uniqueId;
|
||||||
mDisplayDeviceConfig = config;
|
mDisplayDeviceConfig = config;
|
||||||
loadFromDisplayDeviceConfig(token);
|
loadFromDisplayDeviceConfig(token, info);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -765,7 +766,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadFromDisplayDeviceConfig(IBinder token) {
|
private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) {
|
||||||
// All properties that depend on the associated DisplayDevice and the DDC must be
|
// All properties that depend on the associated DisplayDevice and the DDC must be
|
||||||
// updated here.
|
// updated here.
|
||||||
loadAmbientLightSensor();
|
loadAmbientLightSensor();
|
||||||
@@ -774,7 +775,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
loadNitsRange(mContext.getResources());
|
loadNitsRange(mContext.getResources());
|
||||||
setUpAutoBrightness(mContext.getResources(), mHandler);
|
setUpAutoBrightness(mContext.getResources(), mHandler);
|
||||||
reloadReduceBrightColours();
|
reloadReduceBrightColours();
|
||||||
mHbmController.resetHbmData(token, mDisplayDeviceConfig.getHighBrightnessModeData());
|
mHbmController.resetHbmData(info.width, info.height, token,
|
||||||
|
mDisplayDeviceConfig.getHighBrightnessModeData(), mBrightnessSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendUpdatePowerState() {
|
private void sendUpdatePowerState() {
|
||||||
@@ -1343,6 +1345,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
|
if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
|
||||||
&& ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
|
&& ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
|
||||||
|| (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
|
|| (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
|
||||||
|
// We want to scale HDR brightness level with the SDR level
|
||||||
animateValue = mHbmController.getHdrBrightnessValue();
|
animateValue = mHbmController.getHdrBrightnessValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1514,21 +1517,22 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HighBrightnessModeController createHbmController() {
|
private HighBrightnessModeController createHbmControllerLocked() {
|
||||||
final DisplayDeviceConfig ddConfig =
|
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
|
||||||
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
|
final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
|
||||||
final IBinder displayToken =
|
final IBinder displayToken =
|
||||||
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked();
|
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked();
|
||||||
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
|
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
|
||||||
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
|
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
|
||||||
return new HighBrightnessModeController(mHandler, displayToken, PowerManager.BRIGHTNESS_MIN,
|
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
|
||||||
PowerManager.BRIGHTNESS_MAX, hbmData,
|
return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken,
|
||||||
|
PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData,
|
||||||
() -> {
|
() -> {
|
||||||
sendUpdatePowerStateLocked();
|
sendUpdatePowerStateLocked();
|
||||||
mHandler.post(mOnBrightnessChangeRunnable);
|
mHandler.post(mOnBrightnessChangeRunnable);
|
||||||
// TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
|
// TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
|
||||||
mAutomaticBrightnessController.update();
|
mAutomaticBrightnessController.update();
|
||||||
}, mContext);
|
}, mContext, mBrightnessSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void blockScreenOn() {
|
private void blockScreenOn() {
|
||||||
|
|||||||
@@ -31,11 +31,13 @@ import android.os.SystemClock;
|
|||||||
import android.os.Temperature;
|
import android.os.Temperature;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.util.MathUtils;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
import android.view.SurfaceControlHdrLayerInfoListener;
|
import android.view.SurfaceControlHdrLayerInfoListener;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.server.display.BrightnessSetting.BrightnessSettingListener;
|
||||||
import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
|
import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
|
||||||
import com.android.server.display.DisplayManagerService.Clock;
|
import com.android.server.display.DisplayManagerService.Clock;
|
||||||
|
|
||||||
@@ -56,6 +58,8 @@ class HighBrightnessModeController {
|
|||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
|
private static final float HDR_PERCENT_OF_SCREEN_REQUIRED = 0.50f;
|
||||||
|
|
||||||
private final float mBrightnessMin;
|
private final float mBrightnessMin;
|
||||||
private final float mBrightnessMax;
|
private final float mBrightnessMax;
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
@@ -66,6 +70,7 @@ class HighBrightnessModeController {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final SettingsObserver mSettingsObserver;
|
private final SettingsObserver mSettingsObserver;
|
||||||
private final Injector mInjector;
|
private final Injector mInjector;
|
||||||
|
private final BrightnessSettingListener mBrightnessSettingListener = this::onBrightnessChanged;
|
||||||
|
|
||||||
private SurfaceControlHdrLayerInfoListener mHdrListener;
|
private SurfaceControlHdrLayerInfoListener mHdrListener;
|
||||||
private HighBrightnessModeData mHbmData;
|
private HighBrightnessModeData mHbmData;
|
||||||
@@ -74,11 +79,15 @@ class HighBrightnessModeController {
|
|||||||
private boolean mIsInAllowedAmbientRange = false;
|
private boolean mIsInAllowedAmbientRange = false;
|
||||||
private boolean mIsTimeAvailable = false;
|
private boolean mIsTimeAvailable = false;
|
||||||
private boolean mIsAutoBrightnessEnabled = false;
|
private boolean mIsAutoBrightnessEnabled = false;
|
||||||
private float mAutoBrightness;
|
private float mBrightness;
|
||||||
private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
||||||
private boolean mIsHdrLayerPresent = false;
|
private boolean mIsHdrLayerPresent = false;
|
||||||
private boolean mIsThermalStatusWithinLimit = true;
|
private boolean mIsThermalStatusWithinLimit = true;
|
||||||
private boolean mIsBlockedByLowPowerMode = false;
|
private boolean mIsBlockedByLowPowerMode = false;
|
||||||
|
private int mWidth;
|
||||||
|
private int mHeight;
|
||||||
|
private BrightnessSetting mBrightnessSetting;
|
||||||
|
private float mAmbientLux;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If HBM is currently running, this is the start time for the current HBM session.
|
* If HBM is currently running, this is the start time for the current HBM session.
|
||||||
@@ -92,30 +101,32 @@ class HighBrightnessModeController {
|
|||||||
*/
|
*/
|
||||||
private LinkedList<HbmEvent> mEvents = new LinkedList<>();
|
private LinkedList<HbmEvent> mEvents = new LinkedList<>();
|
||||||
|
|
||||||
HighBrightnessModeController(Handler handler, IBinder displayToken, float brightnessMin,
|
HighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken,
|
||||||
float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback,
|
float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData,
|
||||||
Context context) {
|
Runnable hbmChangeCallback, Context context, BrightnessSetting brightnessSetting) {
|
||||||
this(new Injector(), handler, displayToken, brightnessMin, brightnessMax,
|
this(new Injector(), handler, width, height, displayToken, brightnessMin, brightnessMax,
|
||||||
hbmData, hbmChangeCallback, context);
|
hbmData, hbmChangeCallback, context, brightnessSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
HighBrightnessModeController(Injector injector, Handler handler, IBinder displayToken,
|
HighBrightnessModeController(Injector injector, Handler handler, int width, int height,
|
||||||
float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData,
|
IBinder displayToken, float brightnessMin, float brightnessMax,
|
||||||
Runnable hbmChangeCallback, Context context) {
|
HighBrightnessModeData hbmData, Runnable hbmChangeCallback,
|
||||||
|
Context context, BrightnessSetting brightnessSetting) {
|
||||||
mInjector = injector;
|
mInjector = injector;
|
||||||
|
mContext = context;
|
||||||
mClock = injector.getClock();
|
mClock = injector.getClock();
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
mBrightnessMin = brightnessMin;
|
mBrightnessMin = brightnessMin;
|
||||||
mBrightnessMax = brightnessMax;
|
mBrightnessMax = brightnessMax;
|
||||||
|
mBrightness = brightnessSetting.getBrightness();
|
||||||
mHbmChangeCallback = hbmChangeCallback;
|
mHbmChangeCallback = hbmChangeCallback;
|
||||||
mContext = context;
|
|
||||||
mAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
|
||||||
mRecalcRunnable = this::recalculateTimeAllowance;
|
|
||||||
mHdrListener = new HdrListener();
|
|
||||||
mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
|
mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
|
||||||
mSettingsObserver = new SettingsObserver(mHandler);
|
mSettingsObserver = new SettingsObserver(mHandler);
|
||||||
resetHbmData(displayToken, hbmData);
|
mRecalcRunnable = this::recalculateTimeAllowance;
|
||||||
|
mHdrListener = new HdrListener();
|
||||||
|
|
||||||
|
resetHbmData(width, height, displayToken, hbmData, brightnessSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAutoBrightnessEnabled(boolean isEnabled) {
|
void setAutoBrightnessEnabled(boolean isEnabled) {
|
||||||
@@ -123,7 +134,7 @@ class HighBrightnessModeController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "setAutoBrightness( " + isEnabled + " )");
|
Slog.d(TAG, "setAutoBrightnessEnabled( " + isEnabled + " )");
|
||||||
}
|
}
|
||||||
mIsAutoBrightnessEnabled = isEnabled;
|
mIsAutoBrightnessEnabled = isEnabled;
|
||||||
mIsInAllowedAmbientRange = false; // reset when auto-brightness switches
|
mIsInAllowedAmbientRange = false; // reset when auto-brightness switches
|
||||||
@@ -147,11 +158,22 @@ class HighBrightnessModeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getNormalBrightnessMax() {
|
||||||
|
return deviceSupportsHbm() ? mHbmData.transitionPoint : mBrightnessMax;
|
||||||
|
}
|
||||||
|
|
||||||
float getHdrBrightnessValue() {
|
float getHdrBrightnessValue() {
|
||||||
return mBrightnessMax;
|
// For HDR brightness, we take the current brightness and scale it to the max. The reason
|
||||||
|
// we do this is because we want brightness to go to HBM max when it would normally go
|
||||||
|
// to normal max, meaning it should not wait to go to 10000 lux (or whatever the transition
|
||||||
|
// point happens to be) in order to go full HDR. Likewise, HDR on manual brightness should
|
||||||
|
// automatically scale the brightness without forcing the user to adjust to higher values.
|
||||||
|
return MathUtils.map(getCurrentBrightnessMin(), getCurrentBrightnessMax(),
|
||||||
|
mBrightnessMin, mBrightnessMax, mBrightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAmbientLuxChange(float ambientLux) {
|
void onAmbientLuxChange(float ambientLux) {
|
||||||
|
mAmbientLux = ambientLux;
|
||||||
if (!deviceSupportsHbm() || !mIsAutoBrightnessEnabled) {
|
if (!deviceSupportsHbm() || !mIsAutoBrightnessEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -163,17 +185,17 @@ class HighBrightnessModeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAutoBrightnessChanged(float autoBrightness) {
|
@VisibleForTesting
|
||||||
|
void onBrightnessChanged(float brightness) {
|
||||||
if (!deviceSupportsHbm()) {
|
if (!deviceSupportsHbm()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final float oldAutoBrightness = mAutoBrightness;
|
mBrightness = brightness;
|
||||||
mAutoBrightness = autoBrightness;
|
|
||||||
|
|
||||||
// If we are starting or ending a high brightness mode session, store the current
|
// If we are starting or ending a high brightness mode session, store the current
|
||||||
// session in mRunningStartTimeMillis, or the old one in mEvents.
|
// session in mRunningStartTimeMillis, or the old one in mEvents.
|
||||||
final boolean wasHbmDrainingAvailableTime = mRunningStartTimeMillis != -1;
|
final boolean wasHbmDrainingAvailableTime = mRunningStartTimeMillis != -1;
|
||||||
final boolean shouldHbmDrainAvailableTime = mAutoBrightness > mHbmData.transitionPoint
|
final boolean shouldHbmDrainAvailableTime = mBrightness > mHbmData.transitionPoint
|
||||||
&& !mIsHdrLayerPresent;
|
&& !mIsHdrLayerPresent;
|
||||||
if (wasHbmDrainingAvailableTime != shouldHbmDrainAvailableTime) {
|
if (wasHbmDrainingAvailableTime != shouldHbmDrainAvailableTime) {
|
||||||
final long currentTime = mClock.uptimeMillis();
|
final long currentTime = mClock.uptimeMillis();
|
||||||
@@ -202,8 +224,12 @@ class HighBrightnessModeController {
|
|||||||
mSettingsObserver.stopObserving();
|
mSettingsObserver.stopObserving();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetHbmData(IBinder displayToken, HighBrightnessModeData hbmData) {
|
void resetHbmData(int width, int height, IBinder displayToken, HighBrightnessModeData hbmData,
|
||||||
|
BrightnessSetting brightnessSetting) {
|
||||||
|
mWidth = width;
|
||||||
|
mHeight = height;
|
||||||
mHbmData = hbmData;
|
mHbmData = hbmData;
|
||||||
|
resetBrightnessSetting(brightnessSetting);
|
||||||
unregisterHdrListener();
|
unregisterHdrListener();
|
||||||
mSkinThermalStatusObserver.stopObserving();
|
mSkinThermalStatusObserver.stopObserving();
|
||||||
mSettingsObserver.stopObserving();
|
mSettingsObserver.stopObserving();
|
||||||
@@ -227,21 +253,23 @@ class HighBrightnessModeController {
|
|||||||
|
|
||||||
private void dumpLocal(PrintWriter pw) {
|
private void dumpLocal(PrintWriter pw) {
|
||||||
pw.println("HighBrightnessModeController:");
|
pw.println("HighBrightnessModeController:");
|
||||||
|
pw.println(" mBrightness=" + mBrightness);
|
||||||
pw.println(" mCurrentMin=" + getCurrentBrightnessMin());
|
pw.println(" mCurrentMin=" + getCurrentBrightnessMin());
|
||||||
pw.println(" mCurrentMax=" + getCurrentBrightnessMax());
|
pw.println(" mCurrentMax=" + getCurrentBrightnessMax());
|
||||||
pw.println(" mHbmMode=" + BrightnessInfo.hbmToString(mHbmMode));
|
pw.println(" mHbmMode=" + BrightnessInfo.hbmToString(mHbmMode));
|
||||||
pw.println(" remainingTime=" + calculateRemainingTime(mClock.uptimeMillis()));
|
|
||||||
pw.println(" mHbmData=" + mHbmData);
|
pw.println(" mHbmData=" + mHbmData);
|
||||||
|
pw.println(" mAmbientLux=" + mAmbientLux);
|
||||||
pw.println(" mIsInAllowedAmbientRange=" + mIsInAllowedAmbientRange);
|
pw.println(" mIsInAllowedAmbientRange=" + mIsInAllowedAmbientRange);
|
||||||
pw.println(" mIsTimeAvailable= " + mIsTimeAvailable);
|
|
||||||
pw.println(" mIsAutoBrightnessEnabled=" + mIsAutoBrightnessEnabled);
|
pw.println(" mIsAutoBrightnessEnabled=" + mIsAutoBrightnessEnabled);
|
||||||
pw.println(" mAutoBrightness=" + mAutoBrightness);
|
|
||||||
pw.println(" mIsHdrLayerPresent=" + mIsHdrLayerPresent);
|
pw.println(" mIsHdrLayerPresent=" + mIsHdrLayerPresent);
|
||||||
pw.println(" mBrightnessMin=" + mBrightnessMin);
|
pw.println(" mBrightnessMin=" + mBrightnessMin);
|
||||||
pw.println(" mBrightnessMax=" + mBrightnessMax);
|
pw.println(" mBrightnessMax=" + mBrightnessMax);
|
||||||
|
pw.println(" remainingTime=" + calculateRemainingTime(mClock.uptimeMillis()));
|
||||||
|
pw.println(" mIsTimeAvailable= " + mIsTimeAvailable);
|
||||||
pw.println(" mRunningStartTimeMillis=" + TimeUtils.formatUptime(mRunningStartTimeMillis));
|
pw.println(" mRunningStartTimeMillis=" + TimeUtils.formatUptime(mRunningStartTimeMillis));
|
||||||
pw.println(" mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit);
|
pw.println(" mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit);
|
||||||
pw.println(" mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode);
|
pw.println(" mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode);
|
||||||
|
pw.println(" width*height=" + mWidth + "*" + mHeight);
|
||||||
pw.println(" mEvents=");
|
pw.println(" mEvents=");
|
||||||
final long currentTime = mClock.uptimeMillis();
|
final long currentTime = mClock.uptimeMillis();
|
||||||
long lastStartTime = currentTime;
|
long lastStartTime = currentTime;
|
||||||
@@ -268,9 +296,26 @@ class HighBrightnessModeController {
|
|||||||
return event.startTimeMillis;
|
return event.startTimeMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetBrightnessSetting(BrightnessSetting brightnessSetting) {
|
||||||
|
if (mBrightnessSetting != null) {
|
||||||
|
mBrightnessSetting.unregisterListener(mBrightnessSettingListener);
|
||||||
|
}
|
||||||
|
mBrightnessSetting = brightnessSetting;
|
||||||
|
if (mBrightnessSetting != null) {
|
||||||
|
mBrightnessSetting.registerListener(mBrightnessSettingListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isCurrentlyAllowed() {
|
private boolean isCurrentlyAllowed() {
|
||||||
return mIsHdrLayerPresent
|
// Returns true if HBM is allowed (above the ambient lux threshold) and there's still
|
||||||
|| (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange
|
// time within the current window for additional HBM usage. We return false if there is an
|
||||||
|
// HDR layer because we don't want the brightness MAX to change for HDR, which has its
|
||||||
|
// brightness scaled in a different way than sunlight HBM that doesn't require changing
|
||||||
|
// the MAX. HDR also needs to work under manual brightness which never adjusts the
|
||||||
|
// brightness maximum; so we implement HDR-HBM in a way that doesn't adjust the max.
|
||||||
|
// See {@link #getHdrBrightnessValue}.
|
||||||
|
return !mIsHdrLayerPresent
|
||||||
|
&& (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange
|
||||||
&& mIsThermalStatusWithinLimit && !mIsBlockedByLowPowerMode);
|
&& mIsThermalStatusWithinLimit && !mIsBlockedByLowPowerMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,13 +379,13 @@ class HighBrightnessModeController {
|
|||||||
// or if brightness is already in the high range, if there is any time left at all.
|
// or if brightness is already in the high range, if there is any time left at all.
|
||||||
final boolean isAllowedWithoutRestrictions = remainingTime >= mHbmData.timeMinMillis;
|
final boolean isAllowedWithoutRestrictions = remainingTime >= mHbmData.timeMinMillis;
|
||||||
final boolean isOnlyAllowedToStayOn = !isAllowedWithoutRestrictions
|
final boolean isOnlyAllowedToStayOn = !isAllowedWithoutRestrictions
|
||||||
&& remainingTime > 0 && mAutoBrightness > mHbmData.transitionPoint;
|
&& remainingTime > 0 && mBrightness > mHbmData.transitionPoint;
|
||||||
mIsTimeAvailable = isAllowedWithoutRestrictions || isOnlyAllowedToStayOn;
|
mIsTimeAvailable = isAllowedWithoutRestrictions || isOnlyAllowedToStayOn;
|
||||||
|
|
||||||
// Calculate the time at which we want to recalculate mIsTimeAvailable in case a lux or
|
// Calculate the time at which we want to recalculate mIsTimeAvailable in case a lux or
|
||||||
// brightness change doesn't happen before then.
|
// brightness change doesn't happen before then.
|
||||||
long nextTimeout = -1;
|
long nextTimeout = -1;
|
||||||
if (mAutoBrightness > mHbmData.transitionPoint) {
|
if (mBrightness > mHbmData.transitionPoint) {
|
||||||
// if we're in high-lux now, timeout when we run out of allowed time.
|
// if we're in high-lux now, timeout when we run out of allowed time.
|
||||||
nextTimeout = currentTime + remainingTime;
|
nextTimeout = currentTime + remainingTime;
|
||||||
} else if (!mIsTimeAvailable && mEvents.size() > 0) {
|
} else if (!mIsTimeAvailable && mEvents.size() > 0) {
|
||||||
@@ -370,7 +415,7 @@ class HighBrightnessModeController {
|
|||||||
+ ", mIsInAllowedAmbientRange: " + mIsInAllowedAmbientRange
|
+ ", mIsInAllowedAmbientRange: " + mIsInAllowedAmbientRange
|
||||||
+ ", mIsThermalStatusWithinLimit: " + mIsThermalStatusWithinLimit
|
+ ", mIsThermalStatusWithinLimit: " + mIsThermalStatusWithinLimit
|
||||||
+ ", mIsBlockedByLowPowerMode: " + mIsBlockedByLowPowerMode
|
+ ", mIsBlockedByLowPowerMode: " + mIsBlockedByLowPowerMode
|
||||||
+ ", brightness: " + mAutoBrightness
|
+ ", mBrightness: " + mBrightness
|
||||||
+ ", RunningStartTimeMillis: " + mRunningStartTimeMillis
|
+ ", RunningStartTimeMillis: " + mRunningStartTimeMillis
|
||||||
+ ", nextTimeout: " + (nextTimeout != -1 ? (nextTimeout - currentTime) : -1)
|
+ ", nextTimeout: " + (nextTimeout != -1 ? (nextTimeout - currentTime) : -1)
|
||||||
+ ", events: " + mEvents);
|
+ ", events: " + mEvents);
|
||||||
@@ -447,11 +492,12 @@ class HighBrightnessModeController {
|
|||||||
public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers,
|
public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers,
|
||||||
int maxW, int maxH, int flags) {
|
int maxW, int maxH, int flags) {
|
||||||
mHandler.post(() -> {
|
mHandler.post(() -> {
|
||||||
mIsHdrLayerPresent = numberOfHdrLayers > 0;
|
mIsHdrLayerPresent = numberOfHdrLayers > 0
|
||||||
// Calling the auto-brightness update so that we can recalculate
|
&& (float) (maxW * maxH)
|
||||||
// auto-brightness with HDR in mind. When HDR layers are present,
|
>= ((float) (mWidth * mHeight) * HDR_PERCENT_OF_SCREEN_REQUIRED);
|
||||||
// we don't limit auto-brightness' HBM time limits.
|
// Calling the brightness update so that we can recalculate
|
||||||
onAutoBrightnessChanged(mAutoBrightness);
|
// brightness with HDR in mind.
|
||||||
|
onBrightnessChanged(mBrightness);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ public class HighBrightnessModeControllerTest {
|
|||||||
private static final float DEFAULT_MIN = 0.01f;
|
private static final float DEFAULT_MIN = 0.01f;
|
||||||
private static final float DEFAULT_MAX = 0.80f;
|
private static final float DEFAULT_MAX = 0.80f;
|
||||||
|
|
||||||
|
private static final int DISPLAY_WIDTH = 900;
|
||||||
|
private static final int DISPLAY_HEIGHT = 1600;
|
||||||
|
|
||||||
private static final float EPSILON = 0.000001f;
|
private static final float EPSILON = 0.000001f;
|
||||||
|
|
||||||
private OffsettableClock mClock;
|
private OffsettableClock mClock;
|
||||||
@@ -90,6 +93,8 @@ public class HighBrightnessModeControllerTest {
|
|||||||
|
|
||||||
@Captor ArgumentCaptor<IThermalEventListener> mThermalEventListenerCaptor;
|
@Captor ArgumentCaptor<IThermalEventListener> mThermalEventListenerCaptor;
|
||||||
|
|
||||||
|
@Mock private BrightnessSetting mBrightnessSetting;
|
||||||
|
|
||||||
private static final HighBrightnessModeData DEFAULT_HBM_DATA =
|
private static final HighBrightnessModeData DEFAULT_HBM_DATA =
|
||||||
new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS,
|
new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS,
|
||||||
TIME_ALLOWED_IN_WINDOW_MILLIS, TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS,
|
TIME_ALLOWED_IN_WINDOW_MILLIS, TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS,
|
||||||
@@ -98,6 +103,8 @@ public class HighBrightnessModeControllerTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mClock = new OffsettableClock.Stopped();
|
||||||
|
mTestLooper = new TestLooper(mClock::now);
|
||||||
mDisplayToken = null;
|
mDisplayToken = null;
|
||||||
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
|
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
|
||||||
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
|
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
|
||||||
@@ -114,8 +121,8 @@ public class HighBrightnessModeControllerTest {
|
|||||||
public void testNoHbmData() {
|
public void testNoHbmData() {
|
||||||
initHandler(null);
|
initHandler(null);
|
||||||
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
||||||
mInjectorMock, mHandler, mDisplayToken, DEFAULT_MIN, DEFAULT_MAX, null,
|
mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken, DEFAULT_MIN,
|
||||||
() -> {}, mContextSpy);
|
DEFAULT_MAX, null, () -> {}, mContextSpy, mBrightnessSetting);
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,8 +130,8 @@ public class HighBrightnessModeControllerTest {
|
|||||||
public void testNoHbmData_Enabled() {
|
public void testNoHbmData_Enabled() {
|
||||||
initHandler(null);
|
initHandler(null);
|
||||||
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
||||||
mInjectorMock, mHandler, mDisplayToken, DEFAULT_MIN, DEFAULT_MAX, null,
|
mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken, DEFAULT_MIN,
|
||||||
() -> {}, mContextSpy);
|
DEFAULT_MAX, null, () -> {}, mContextSpy, mBrightnessSetting);
|
||||||
hbmc.setAutoBrightnessEnabled(true);
|
hbmc.setAutoBrightnessEnabled(true);
|
||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
|
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
||||||
@@ -180,7 +187,7 @@ public class HighBrightnessModeControllerTest {
|
|||||||
|
|
||||||
hbmc.setAutoBrightnessEnabled(true);
|
hbmc.setAutoBrightnessEnabled(true);
|
||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT + 0.01f);
|
hbmc.onBrightnessChanged(TRANSITION_POINT + 0.01f);
|
||||||
|
|
||||||
// Verify we are in HBM
|
// Verify we are in HBM
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
||||||
@@ -212,7 +219,7 @@ public class HighBrightnessModeControllerTest {
|
|||||||
|
|
||||||
hbmc.setAutoBrightnessEnabled(true);
|
hbmc.setAutoBrightnessEnabled(true);
|
||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT + 0.01f);
|
hbmc.onBrightnessChanged(TRANSITION_POINT + 0.01f);
|
||||||
|
|
||||||
// Verify we are in HBM
|
// Verify we are in HBM
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
||||||
@@ -237,18 +244,18 @@ public class HighBrightnessModeControllerTest {
|
|||||||
hbmc.setAutoBrightnessEnabled(true);
|
hbmc.setAutoBrightnessEnabled(true);
|
||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
||||||
|
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT + 0.01f);
|
hbmc.onBrightnessChanged(TRANSITION_POINT + 0.01f);
|
||||||
advanceTime(TIME_ALLOWED_IN_WINDOW_MILLIS / 2);
|
advanceTime(TIME_ALLOWED_IN_WINDOW_MILLIS / 2);
|
||||||
|
|
||||||
// Verify we are in HBM
|
// Verify we are in HBM
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
||||||
|
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT - 0.01f);
|
hbmc.onBrightnessChanged(TRANSITION_POINT - 0.01f);
|
||||||
advanceTime(1);
|
advanceTime(1);
|
||||||
|
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
||||||
|
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT + 0.01f);
|
hbmc.onBrightnessChanged(TRANSITION_POINT + 0.01f);
|
||||||
advanceTime(TIME_ALLOWED_IN_WINDOW_MILLIS / 2);
|
advanceTime(TIME_ALLOWED_IN_WINDOW_MILLIS / 2);
|
||||||
|
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
||||||
@@ -267,13 +274,13 @@ public class HighBrightnessModeControllerTest {
|
|||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
||||||
|
|
||||||
// Go into HBM for half the allowed window
|
// Go into HBM for half the allowed window
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT + 0.01f);
|
hbmc.onBrightnessChanged(TRANSITION_POINT + 0.01f);
|
||||||
advanceTime(TIME_ALLOWED_IN_WINDOW_MILLIS / 2);
|
advanceTime(TIME_ALLOWED_IN_WINDOW_MILLIS / 2);
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
||||||
|
|
||||||
// Move lux below threshold (ending first event);
|
// Move lux below threshold (ending first event);
|
||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1);
|
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1);
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT);
|
hbmc.onBrightnessChanged(TRANSITION_POINT);
|
||||||
assertState(hbmc, DEFAULT_MIN, TRANSITION_POINT, HIGH_BRIGHTNESS_MODE_OFF);
|
assertState(hbmc, DEFAULT_MIN, TRANSITION_POINT, HIGH_BRIGHTNESS_MODE_OFF);
|
||||||
|
|
||||||
// Move up some amount of time so that there's still time in the window even after a
|
// Move up some amount of time so that there's still time in the window even after a
|
||||||
@@ -283,7 +290,7 @@ public class HighBrightnessModeControllerTest {
|
|||||||
|
|
||||||
// Go into HBM for just under the second half of allowed window
|
// Go into HBM for just under the second half of allowed window
|
||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
|
||||||
hbmc.onAutoBrightnessChanged(TRANSITION_POINT + 1);
|
hbmc.onBrightnessChanged(TRANSITION_POINT + 1);
|
||||||
advanceTime((TIME_ALLOWED_IN_WINDOW_MILLIS / 2) - 1);
|
advanceTime((TIME_ALLOWED_IN_WINDOW_MILLIS / 2) - 1);
|
||||||
|
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_SUNLIGHT);
|
||||||
@@ -355,8 +362,9 @@ public class HighBrightnessModeControllerTest {
|
|||||||
// Creates instance with standard initialization values.
|
// Creates instance with standard initialization values.
|
||||||
private HighBrightnessModeController createDefaultHbm(OffsettableClock clock) {
|
private HighBrightnessModeController createDefaultHbm(OffsettableClock clock) {
|
||||||
initHandler(clock);
|
initHandler(clock);
|
||||||
return new HighBrightnessModeController(mInjectorMock, mHandler, mDisplayToken, DEFAULT_MIN,
|
return new HighBrightnessModeController(mInjectorMock, mHandler, DISPLAY_WIDTH,
|
||||||
DEFAULT_MAX, DEFAULT_HBM_DATA, () -> {}, mContextSpy);
|
DISPLAY_HEIGHT, mDisplayToken, DEFAULT_MIN, DEFAULT_MAX, DEFAULT_HBM_DATA, () -> {},
|
||||||
|
mContextSpy, mBrightnessSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initHandler(OffsettableClock clock) {
|
private void initHandler(OffsettableClock clock) {
|
||||||
|
|||||||
Reference in New Issue
Block a user