diff options
| author | 2022-07-26 15:39:51 +0000 | |
|---|---|---|
| committer | 2022-07-26 15:39:51 +0000 | |
| commit | 5098721c204cfebceed43e5d5c922a809db90333 (patch) | |
| tree | cc82e0248edc3bc3a922e78592f0a4090a550aa5 | |
| parent | 0709493f0ec75948eabdd4e279190b38a9f9f363 (diff) | |
| parent | 373794989baaf46d724431694831e9aa388ab783 (diff) | |
Merge "Moving BrightnessInfo and BrightnessReason outside of DisplayPowerController to have the support of declaring the brightness relevant states in DisplayPowerController agnostic fashion."
6 files changed, 661 insertions, 264 deletions
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 6fd88411593f..114690a03324 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -46,7 +46,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.display.BrightnessSynchronizer; import com.android.internal.os.BackgroundThread; import com.android.server.EventLogTags; -import com.android.server.display.DisplayPowerController.BrightnessEvent; +import com.android.server.display.brightness.BrightnessEvent; import java.io.PrintWriter; @@ -337,14 +337,15 @@ class AutomaticBrightnessController { float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) { if (brightnessEvent != null) { - brightnessEvent.lux = - mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT; - brightnessEvent.preThresholdLux = mPreThresholdLux; - brightnessEvent.preThresholdBrightness = mPreThresholdBrightness; - brightnessEvent.recommendedBrightness = mScreenAutoBrightness; - brightnessEvent.flags |= (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0) + brightnessEvent.setLux( + mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT); + brightnessEvent.setPreThresholdLux(mPreThresholdLux); + brightnessEvent.setPreThresholdBrightness(mPreThresholdBrightness); + brightnessEvent.setRecommendedBrightness(mScreenAutoBrightness); + brightnessEvent.setFlags(brightnessEvent.getFlags() + | (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0) | (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE - ? BrightnessEvent.FLAG_DOZE_SCALE : 0); + ? BrightnessEvent.FLAG_DOZE_SCALE : 0)); } if (!mAmbientLuxValid) { diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 95c8fef12976..4e33fd07c28e 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -67,6 +67,8 @@ import com.android.internal.util.RingBuffer; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.display.RampAnimator.DualRampAnimator; +import com.android.server.display.brightness.BrightnessEvent; +import com.android.server.display.brightness.BrightnessReason; import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal; import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener; import com.android.server.display.utils.SensorUtils; @@ -76,7 +78,6 @@ import com.android.server.display.whitebalance.DisplayWhiteBalanceSettings; import com.android.server.policy.WindowManagerPolicy; import java.io.PrintWriter; -import java.util.Objects; /** * Controls the power state of the display. @@ -1430,7 +1431,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // we broadcast this change through setting. final float unthrottledBrightnessState = brightnessState; if (mBrightnessThrottler.isThrottled()) { - mTempBrightnessEvent.thermalMax = mBrightnessThrottler.getBrightnessCap(); + mTempBrightnessEvent.setThermalMax(mBrightnessThrottler.getBrightnessCap()); brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap()); mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED); if (!mAppliedThrottling) { @@ -1551,8 +1552,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be // done in HighBrightnessModeController. if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR - && ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0 - || (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) { + && ((mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0 + || (mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_LOW_POWER) + == 0)) { // We want to scale HDR brightness level with the SDR level animateValue = mHbmController.getHdrBrightnessValue(); } @@ -1615,7 +1617,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags) + "', previous reason: '" + mBrightnessReason + "'."); mBrightnessReason.set(mBrightnessReasonTemp); - } else if (mBrightnessReasonTemp.reason == BrightnessReason.REASON_MANUAL + } else if (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_MANUAL && userSetBrightnessChanged) { Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment."); } @@ -1624,17 +1626,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Log brightness events when a detail of significance has changed. Generally this is the // brightness itself changing, but also includes data like HBM cap, thermal throttling // brightness cap, RBC state, etc. - mTempBrightnessEvent.time = System.currentTimeMillis(); - mTempBrightnessEvent.brightness = brightnessState; - mTempBrightnessEvent.reason.set(mBrightnessReason); - mTempBrightnessEvent.hbmMax = mHbmController.getCurrentBrightnessMax(); - mTempBrightnessEvent.hbmMode = mHbmController.getHighBrightnessMode(); - mTempBrightnessEvent.flags |= (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0); + mTempBrightnessEvent.setTime(System.currentTimeMillis()); + mTempBrightnessEvent.setBrightness(brightnessState); + mTempBrightnessEvent.setReason(mBrightnessReason); + mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax()); + mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode()); + mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags() + | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)); // Temporary is what we use during slider interactions. We avoid logging those so that // we don't spam logcat when the slider is being used. boolean tempToTempTransition = - mTempBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY - && mLastBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY; + mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY + && mLastBrightnessEvent.getReason().getReason() + == BrightnessReason.REASON_TEMPORARY; if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition) || brightnessAdjustmentFlags != 0) { mLastBrightnessEvent.copyFrom(mTempBrightnessEvent); @@ -1642,8 +1646,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Adjustment flags (and user-set flag) only get added after the equality checks since // they are transient. - newEvent.adjustmentFlags = brightnessAdjustmentFlags; - newEvent.flags |= (userSetBrightnessChanged ? BrightnessEvent.FLAG_USER_SET : 0); + newEvent.setAdjustmentFlags(brightnessAdjustmentFlags); + newEvent.setFlags(newEvent.getFlags() | (userSetBrightnessChanged + ? BrightnessEvent.FLAG_USER_SET : 0)); Slog.i(TAG, newEvent.toString(/* includeTime= */ false)); if (mBrightnessEventRingBuffer != null) { @@ -2734,117 +2739,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } - class BrightnessEvent { - static final int FLAG_RBC = 0x1; - static final int FLAG_INVALID_LUX = 0x2; - static final int FLAG_DOZE_SCALE = 0x3; - static final int FLAG_USER_SET = 0x4; - - public final BrightnessReason reason = new BrightnessReason(); - - public int displayId; - public float lux; - public float preThresholdLux; - public long time; - public float brightness; - public float recommendedBrightness; - public float preThresholdBrightness; - public float hbmMax; - public float thermalMax; - public int hbmMode; - public int flags; - public int adjustmentFlags; - - BrightnessEvent(BrightnessEvent that) { - copyFrom(that); - } - - BrightnessEvent(int displayId) { - this.displayId = displayId; - reset(); - } - - void copyFrom(BrightnessEvent that) { - displayId = that.displayId; - time = that.time; - lux = that.lux; - preThresholdLux = that.preThresholdLux; - brightness = that.brightness; - recommendedBrightness = that.recommendedBrightness; - preThresholdBrightness = that.preThresholdBrightness; - hbmMax = that.hbmMax; - thermalMax = that.thermalMax; - flags = that.flags; - hbmMode = that.hbmMode; - reason.set(that.reason); - adjustmentFlags = that.adjustmentFlags; - } - - void reset() { - time = SystemClock.uptimeMillis(); - brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; - recommendedBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; - lux = 0; - preThresholdLux = 0; - preThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; - hbmMax = PowerManager.BRIGHTNESS_MAX; - thermalMax = PowerManager.BRIGHTNESS_MAX; - flags = 0; - hbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; - reason.set(null); - adjustmentFlags = 0; - } - - boolean equalsMainData(BrightnessEvent that) { - // This equals comparison purposefully ignores time since it is regularly changing and - // we don't want to log a brightness event just because the time changed. - return displayId == that.displayId - && Float.floatToRawIntBits(brightness) - == Float.floatToRawIntBits(that.brightness) - && Float.floatToRawIntBits(recommendedBrightness) - == Float.floatToRawIntBits(that.recommendedBrightness) - && Float.floatToRawIntBits(preThresholdBrightness) - == Float.floatToRawIntBits(that.preThresholdBrightness) - && Float.floatToRawIntBits(lux) == Float.floatToRawIntBits(that.lux) - && Float.floatToRawIntBits(preThresholdLux) - == Float.floatToRawIntBits(that.preThresholdLux) - && Float.floatToRawIntBits(hbmMax) == Float.floatToRawIntBits(that.hbmMax) - && hbmMode == that.hbmMode - && Float.floatToRawIntBits(thermalMax) - == Float.floatToRawIntBits(that.thermalMax) - && flags == that.flags - && adjustmentFlags == that.adjustmentFlags - && reason.equals(that.reason); - } - - public String toString(boolean includeTime) { - return (includeTime ? TimeUtils.formatForLogging(time) + " - " : "") - + "BrightnessEvent: " - + "disp=" + displayId - + ", brt=" + brightness + ((flags & FLAG_USER_SET) != 0 ? "(user_set)" : "") - + ", rcmdBrt=" + recommendedBrightness - + ", preBrt=" + preThresholdBrightness - + ", lux=" + lux - + ", preLux=" + preThresholdLux - + ", hbmMax=" + hbmMax - + ", hbmMode=" + BrightnessInfo.hbmToString(hbmMode) - + ", thrmMax=" + thermalMax - + ", flags=" + flagsToString() - + ", reason=" + reason.toString(adjustmentFlags); - } - - @Override - public String toString() { - return toString(/* includeTime */ true); - } - private String flagsToString() { - return ((flags & FLAG_USER_SET) != 0 ? "user_set " : "") - + ((flags & FLAG_RBC) != 0 ? "rbc " : "") - + ((flags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "") - + ((flags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : ""); - } - } private final class DisplayControllerHandler extends Handler { public DisplayControllerHandler(Looper looper) { @@ -2996,137 +2891,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } - /** - * Stores data about why the brightness was changed. Made up of one main - * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*} - * modifiers. - */ - private final class BrightnessReason { - static final int REASON_UNKNOWN = 0; - static final int REASON_MANUAL = 1; - static final int REASON_DOZE = 2; - static final int REASON_DOZE_DEFAULT = 3; - static final int REASON_AUTOMATIC = 4; - static final int REASON_SCREEN_OFF = 5; - static final int REASON_VR = 6; - static final int REASON_OVERRIDE = 7; - static final int REASON_TEMPORARY = 8; - static final int REASON_BOOST = 9; - static final int REASON_MAX = REASON_BOOST; - - static final int MODIFIER_DIMMED = 0x1; - static final int MODIFIER_LOW_POWER = 0x2; - static final int MODIFIER_HDR = 0x4; - static final int MODIFIER_THROTTLED = 0x8; - static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR - | MODIFIER_THROTTLED; - - // ADJUSTMENT_* - // These things can happen at any point, even if the main brightness reason doesn't - // fundamentally change, so they're not stored. - - // Auto-brightness adjustment factor changed - static final int ADJUSTMENT_AUTO_TEMP = 0x1; - // Temporary adjustment to the auto-brightness adjustment factor. - static final int ADJUSTMENT_AUTO = 0x2; - - // One of REASON_* - public int reason; - // Any number of MODIFIER_* - public int modifier; - - public void set(BrightnessReason other) { - setReason(other == null ? REASON_UNKNOWN : other.reason); - setModifier(other == null ? 0 : other.modifier); - } - - public void setReason(int reason) { - if (reason < REASON_UNKNOWN || reason > REASON_MAX) { - Slog.w(TAG, "brightness reason out of bounds: " + reason); - } else { - this.reason = reason; - } - } - - public void setModifier(int modifier) { - if ((modifier & ~MODIFIER_MASK) != 0) { - Slog.w(TAG, "brightness modifier out of bounds: 0x" - + Integer.toHexString(modifier)); - } else { - this.modifier = modifier; - } - } - - public void addModifier(int modifier) { - setModifier(modifier | this.modifier); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof BrightnessReason)) { - return false; - } - BrightnessReason other = (BrightnessReason) obj; - return other.reason == reason && other.modifier == modifier; - } - - @Override - public int hashCode() { - return Objects.hash(reason, modifier); - } - - @Override - public String toString() { - return toString(0); - } - - public String toString(int adjustments) { - final StringBuilder sb = new StringBuilder(); - sb.append(reasonToString(reason)); - sb.append(" ["); - if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) { - sb.append(" temp_adj"); - } - if ((adjustments & ADJUSTMENT_AUTO) != 0) { - sb.append(" auto_adj"); - } - if ((modifier & MODIFIER_LOW_POWER) != 0) { - sb.append(" low_pwr"); - } - if ((modifier & MODIFIER_DIMMED) != 0) { - sb.append(" dim"); - } - if ((modifier & MODIFIER_HDR) != 0) { - sb.append(" hdr"); - } - if ((modifier & MODIFIER_THROTTLED) != 0) { - sb.append(" throttled"); - } - int strlen = sb.length(); - if (sb.charAt(strlen - 1) == '[') { - sb.setLength(strlen - 2); - } else { - sb.append(" ]"); - } - return sb.toString(); - } - - private String reasonToString(int reason) { - switch (reason) { - case REASON_MANUAL: return "manual"; - case REASON_DOZE: return "doze"; - case REASON_DOZE_DEFAULT: return "doze_default"; - case REASON_AUTOMATIC: return "automatic"; - case REASON_SCREEN_OFF: return "screen_off"; - case REASON_VR: return "vr"; - case REASON_OVERRIDE: return "override"; - case REASON_TEMPORARY: return "temporary"; - case REASON_BOOST: return "boost"; - default: return Integer.toString(reason); - } - } - } - static class CachedBrightnessInfo { public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT); public MutableFloat adjustedBrightness = diff --git a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java new file mode 100644 index 000000000000..6698612dc652 --- /dev/null +++ b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java @@ -0,0 +1,262 @@ +/* + * 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; + +import android.hardware.display.BrightnessInfo; +import android.os.PowerManager; +import android.os.SystemClock; +import android.util.TimeUtils; + +/** + * Represents a particular brightness change event. + */ +public final class BrightnessEvent { + public static final int FLAG_RBC = 0x1; + public static final int FLAG_INVALID_LUX = 0x2; + public static final int FLAG_DOZE_SCALE = 0x3; + public static final int FLAG_USER_SET = 0x4; + + private BrightnessReason mReason = new BrightnessReason(); + private int mDisplayId; + private float mLux; + private float mPreThresholdLux; + private long mTime; + private float mBrightness; + private float mRecommendedBrightness; + private float mPreThresholdBrightness; + private float mHbmMax; + private float mThermalMax; + private int mHbmMode; + private int mFlags; + private int mAdjustmentFlags; + + public BrightnessEvent(BrightnessEvent that) { + copyFrom(that); + } + + public BrightnessEvent(int displayId) { + this.mDisplayId = displayId; + reset(); + } + + /** + * A utility to clone a brightness event into another event + * + * @param that BrightnessEvent which is to be copied + */ + public void copyFrom(BrightnessEvent that) { + mDisplayId = that.getDisplayId(); + mTime = that.getTime(); + mLux = that.getLux(); + mPreThresholdLux = that.getPreThresholdLux(); + mBrightness = that.getBrightness(); + mRecommendedBrightness = that.getRecommendedBrightness(); + mPreThresholdBrightness = that.getPreThresholdBrightness(); + mHbmMax = that.getHbmMax(); + mThermalMax = that.getThermalMax(); + mFlags = that.getFlags(); + mHbmMode = that.getHbmMode(); + mReason.set(that.getReason()); + mAdjustmentFlags = that.getAdjustmentFlags(); + } + + /** + * A utility to reset the BrightnessEvent to default values + */ + public void reset() { + mTime = SystemClock.uptimeMillis(); + mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mRecommendedBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mLux = 0; + mPreThresholdLux = 0; + mPreThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mHbmMax = PowerManager.BRIGHTNESS_MAX; + mThermalMax = PowerManager.BRIGHTNESS_MAX; + mFlags = 0; + mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; + mReason.set(null); + mAdjustmentFlags = 0; + } + + /** + * A utility to compare two BrightnessEvents. This purposefully ignores comparing time as the + * two events might have been created at different times, but essentially hold the same + * underlying values + * + * @param that The brightnessEvent with which the current brightnessEvent is to be compared + * @return A boolean value representing if the two events are same or not. + */ + public boolean equalsMainData(BrightnessEvent that) { + // This equals comparison purposefully ignores time since it is regularly changing and + // we don't want to log a brightness event just because the time changed. + return mDisplayId == that.mDisplayId + && Float.floatToRawIntBits(mBrightness) + == Float.floatToRawIntBits(that.mBrightness) + && Float.floatToRawIntBits(mRecommendedBrightness) + == Float.floatToRawIntBits(that.mRecommendedBrightness) + && Float.floatToRawIntBits(mPreThresholdBrightness) + == Float.floatToRawIntBits(that.mPreThresholdBrightness) + && Float.floatToRawIntBits(mLux) == Float.floatToRawIntBits(that.mLux) + && Float.floatToRawIntBits(mPreThresholdLux) + == Float.floatToRawIntBits(that.mPreThresholdLux) + && Float.floatToRawIntBits(mHbmMax) == Float.floatToRawIntBits(that.mHbmMax) + && mHbmMode == that.mHbmMode + && Float.floatToRawIntBits(mThermalMax) + == Float.floatToRawIntBits(that.mThermalMax) + && mFlags == that.mFlags + && mAdjustmentFlags == that.mAdjustmentFlags + && mReason.equals(that.mReason); + } + + /** + * A utility to stringify a BrightnessEvent + * @param includeTime Indicates if the time field is to be added in the stringify version of the + * BrightnessEvent + * @return A stringified BrightnessEvent + */ + public String toString(boolean includeTime) { + return (includeTime ? TimeUtils.formatForLogging(mTime) + " - " : "") + + "BrightnessEvent: " + + "disp=" + mDisplayId + + ", brt=" + mBrightness + ((mFlags & FLAG_USER_SET) != 0 ? "(user_set)" : "") + + ", rcmdBrt=" + mRecommendedBrightness + + ", preBrt=" + mPreThresholdBrightness + + ", lux=" + mLux + + ", preLux=" + mPreThresholdLux + + ", hbmMax=" + mHbmMax + + ", hbmMode=" + BrightnessInfo.hbmToString(mHbmMode) + + ", thrmMax=" + mThermalMax + + ", flags=" + flagsToString() + + ", reason=" + mReason.toString(mAdjustmentFlags); + } + + @Override + public String toString() { + return toString(/* includeTime */ true); + } + + public void setReason(BrightnessReason reason) { + this.mReason = reason; + } + + public BrightnessReason getReason() { + return mReason; + } + + public int getDisplayId() { + return mDisplayId; + } + + public void setDisplayId(int displayId) { + this.mDisplayId = displayId; + } + + public float getLux() { + return mLux; + } + + public void setLux(float lux) { + this.mLux = lux; + } + + public float getPreThresholdLux() { + return mPreThresholdLux; + } + + public void setPreThresholdLux(float preThresholdLux) { + this.mPreThresholdLux = preThresholdLux; + } + + public long getTime() { + return mTime; + } + + public void setTime(long time) { + this.mTime = time; + } + + public float getBrightness() { + return mBrightness; + } + + public void setBrightness(float brightness) { + this.mBrightness = brightness; + } + + public float getRecommendedBrightness() { + return mRecommendedBrightness; + } + + public void setRecommendedBrightness(float recommendedBrightness) { + this.mRecommendedBrightness = recommendedBrightness; + } + + public float getPreThresholdBrightness() { + return mPreThresholdBrightness; + } + + public void setPreThresholdBrightness(float preThresholdBrightness) { + this.mPreThresholdBrightness = preThresholdBrightness; + } + + public float getHbmMax() { + return mHbmMax; + } + + public void setHbmMax(float hbmMax) { + this.mHbmMax = hbmMax; + } + + public float getThermalMax() { + return mThermalMax; + } + + public void setThermalMax(float thermalMax) { + this.mThermalMax = thermalMax; + } + + public int getHbmMode() { + return mHbmMode; + } + + public void setHbmMode(int hbmMode) { + this.mHbmMode = hbmMode; + } + + public int getFlags() { + return mFlags; + } + + public void setFlags(int flags) { + this.mFlags = flags; + } + + public int getAdjustmentFlags() { + return mAdjustmentFlags; + } + + public void setAdjustmentFlags(int adjustmentFlags) { + this.mAdjustmentFlags = adjustmentFlags; + } + + private String flagsToString() { + return ((mFlags & FLAG_USER_SET) != 0 ? "user_set " : "") + + ((mFlags & FLAG_RBC) != 0 ? "rbc " : "") + + ((mFlags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "") + + ((mFlags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : ""); + } +} diff --git a/services/core/java/com/android/server/display/brightness/BrightnessReason.java b/services/core/java/com/android/server/display/brightness/BrightnessReason.java new file mode 100644 index 000000000000..d8eacd930d40 --- /dev/null +++ b/services/core/java/com/android/server/display/brightness/BrightnessReason.java @@ -0,0 +1,200 @@ +/* + * 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; + +import android.util.Slog; + +import java.util.Objects; + +/** + * Stores data about why the brightness was changed. Made up of one main + * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*} + * modifiers. + */ +public final class BrightnessReason { + private static final String TAG = "BrightnessReason"; + + public static final int REASON_UNKNOWN = 0; + public static final int REASON_MANUAL = 1; + public static final int REASON_DOZE = 2; + public static final int REASON_DOZE_DEFAULT = 3; + public static final int REASON_AUTOMATIC = 4; + public static final int REASON_SCREEN_OFF = 5; + public static final int REASON_VR = 6; + public static final int REASON_OVERRIDE = 7; + public static final int REASON_TEMPORARY = 8; + public static final int REASON_BOOST = 9; + public static final int REASON_MAX = REASON_BOOST; + + public static final int MODIFIER_DIMMED = 0x1; + public static final int MODIFIER_LOW_POWER = 0x2; + public static final int MODIFIER_HDR = 0x4; + public static final int MODIFIER_THROTTLED = 0x8; + public static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR + | MODIFIER_THROTTLED; + + // ADJUSTMENT_* + // These things can happen at any point, even if the main brightness reason doesn't + // fundamentally change, so they're not stored. + + // Auto-brightness adjustment factor changed + public static final int ADJUSTMENT_AUTO_TEMP = 0x1; + // Temporary adjustment to the auto-brightness adjustment factor. + public static final int ADJUSTMENT_AUTO = 0x2; + + // One of REASON_* + private int mReason; + // Any number of MODIFIER_* + private int mModifier; + + /** + * A utility to clone a BrightnessReason from another BrightnessReason event + * + * @param other The BrightnessReason object which is to be cloned + */ + public void set(BrightnessReason other) { + setReason(other == null ? REASON_UNKNOWN : other.mReason); + setModifier(other == null ? 0 : other.mModifier); + } + + /** + * A utility to add a modifier to the BrightnessReason object + * + * @param modifier The modifier which is to be added + */ + public void addModifier(int modifier) { + setModifier(modifier | this.mModifier); + } + + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof BrightnessReason)) { + return false; + } + BrightnessReason other = (BrightnessReason) obj; + return other.mReason == mReason && other.mModifier == mModifier; + } + + @Override + public int hashCode() { + return Objects.hash(mReason, mModifier); + } + + @Override + public String toString() { + return toString(0); + } + + /** + * A utility to stringify a BrightnessReason + * + * @param adjustments Indicates if the adjustments field is to be added in the stringify version + * of the BrightnessReason + * @return A stringified BrightnessReason + */ + public String toString(int adjustments) { + final StringBuilder sb = new StringBuilder(); + sb.append(reasonToString(mReason)); + sb.append(" ["); + if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) { + sb.append(" temp_adj"); + } + if ((adjustments & ADJUSTMENT_AUTO) != 0) { + sb.append(" auto_adj"); + } + if ((mModifier & MODIFIER_LOW_POWER) != 0) { + sb.append(" low_pwr"); + } + if ((mModifier & MODIFIER_DIMMED) != 0) { + sb.append(" dim"); + } + if ((mModifier & MODIFIER_HDR) != 0) { + sb.append(" hdr"); + } + if ((mModifier & MODIFIER_THROTTLED) != 0) { + sb.append(" throttled"); + } + int strlen = sb.length(); + if (sb.charAt(strlen - 1) == '[') { + sb.setLength(strlen - 2); + } else { + sb.append(" ]"); + } + return sb.toString(); + } + + /** + * A utility to set the reason of the BrightnessReason object + * + * @param reason The value to which the reason is to be updated. + */ + public void setReason(int reason) { + if (reason < REASON_UNKNOWN || reason > REASON_MAX) { + Slog.w(TAG, "brightness reason out of bounds: " + reason); + } else { + this.mReason = reason; + } + } + + public int getReason() { + return mReason; + } + + public int getModifier() { + return mModifier; + } + + /** + * A utility to set the modified of the current BrightnessReason object + * + * @param modifier The value to which the modifier is to be updated + */ + public void setModifier(int modifier) { + if ((modifier & ~MODIFIER_MASK) != 0) { + Slog.w(TAG, "brightness modifier out of bounds: 0x" + + Integer.toHexString(modifier)); + } else { + this.mModifier = modifier; + } + } + + private String reasonToString(int reason) { + switch (reason) { + case REASON_MANUAL: + return "manual"; + case REASON_DOZE: + return "doze"; + case REASON_DOZE_DEFAULT: + return "doze_default"; + case REASON_AUTOMATIC: + return "automatic"; + case REASON_SCREEN_OFF: + return "screen_off"; + case REASON_VR: + return "vr"; + case REASON_OVERRIDE: + return "override"; + case REASON_TEMPORARY: + return "temporary"; + case REASON_BOOST: + return "boost"; + default: + return Integer.toString(reason); + } + } +} diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java new file mode 100644 index 000000000000..e305957c6290 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java @@ -0,0 +1,78 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; + +import android.hardware.display.BrightnessInfo; +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@Presubmit +@RunWith(AndroidJUnit4.class) +public final class BrightnessEventTest { + private BrightnessEvent mBrightnessEvent; + + @Before + public void setUp() { + mBrightnessEvent = new BrightnessEvent(1); + mBrightnessEvent.setReason( + getReason(BrightnessReason.REASON_DOZE, BrightnessReason.MODIFIER_LOW_POWER)); + mBrightnessEvent.setLux(100.0f); + mBrightnessEvent.setPreThresholdLux(150.0f); + mBrightnessEvent.setTime(System.currentTimeMillis()); + mBrightnessEvent.setBrightness(0.6f); + mBrightnessEvent.setRecommendedBrightness(0.6f); + mBrightnessEvent.setHbmMax(0.62f); + mBrightnessEvent.setThermalMax(0.65f); + mBrightnessEvent.setHbmMode(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF); + mBrightnessEvent.setFlags(0); + mBrightnessEvent.setAdjustmentFlags(0); + } + + @Test + public void testEqualsMainDataComparesAllFieldsExceptTime() { + BrightnessEvent secondBrightnessEvent = new BrightnessEvent(1); + secondBrightnessEvent.copyFrom(mBrightnessEvent); + secondBrightnessEvent.setTime(0); + assertEquals(secondBrightnessEvent.equalsMainData(mBrightnessEvent), true); + } + + @Test + public void testToStringWorksAsExpected() { + String actualString = mBrightnessEvent.toString(false); + String expectedString = + "BrightnessEvent: disp=1, brt=0.6, rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150" + + ".0, hbmMax=0.62, hbmMode=off, thrmMax=0.65, flags=, reason=doze [ " + + "low_pwr ]"; + assertEquals(actualString, expectedString); + } + + private BrightnessReason getReason(int reason, int modifier) { + BrightnessReason brightnessReason = new BrightnessReason(); + brightnessReason.setReason(reason); + brightnessReason.setModifier(modifier); + return brightnessReason; + } +} diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java new file mode 100644 index 000000000000..ffc2e0dfe26c --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java @@ -0,0 +1,92 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@Presubmit +@RunWith(AndroidJUnit4.class) +public final class BrightnessReasonTest { + private BrightnessReason mBrightnessReason; + + @Before + public void setUp() { + mBrightnessReason = getReason(BrightnessReason.REASON_DOZE, + BrightnessReason.MODIFIER_LOW_POWER); + } + + @Test + public void setSetsAppropriateValues() { + mBrightnessReason.set(null); + assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_UNKNOWN); + assertEquals(mBrightnessReason.getModifier(), 0); + + mBrightnessReason.set( + getReason(BrightnessReason.REASON_BOOST, BrightnessReason.MODIFIER_THROTTLED)); + assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_BOOST); + assertEquals(mBrightnessReason.getModifier(), BrightnessReason.MODIFIER_THROTTLED); + } + + @Test + public void toStringGeneratesExpectedString() { + String actualString = mBrightnessReason.toString(); + String expectedString = "doze [ low_pwr ]"; + assertEquals(actualString, expectedString); + } + + @Test + public void setModifierDoesntSetIfModifierIsBeyondExtremes() { + int extremeModifier = 0x16; + mBrightnessReason.setModifier(extremeModifier); + assertEquals(mBrightnessReason.getModifier(), BrightnessReason.MODIFIER_LOW_POWER); + } + + @Test + public void setReasonDoesntSetIfModifierIsBeyondExtremes() { + int extremeReason = 10; + mBrightnessReason.setReason(extremeReason); + assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_DOZE); + + extremeReason = -1; + mBrightnessReason.setReason(extremeReason); + assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_DOZE); + } + + @Test + public void addModifierWorksAsExpected() { + mBrightnessReason.addModifier(BrightnessReason.REASON_BOOST); + assertEquals(mBrightnessReason.getModifier(), + BrightnessReason.REASON_DOZE | BrightnessReason.REASON_BOOST); + } + + private BrightnessReason getReason(int reason, int modifier) { + BrightnessReason brightnessReason = new BrightnessReason(); + brightnessReason.setReason(reason); + brightnessReason.setModifier(modifier); + return brightnessReason; + } +} |