summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rupesh Bansal <brup@google.com> 2022-07-26 15:39:51 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-07-26 15:39:51 +0000
commit5098721c204cfebceed43e5d5c922a809db90333 (patch)
treecc82e0248edc3bc3a922e78592f0a4090a550aa5
parent0709493f0ec75948eabdd4e279190b38a9f9f363 (diff)
parent373794989baaf46d724431694831e9aa388ab783 (diff)
Merge "Moving BrightnessInfo and BrightnessReason outside of DisplayPowerController to have the support of declaring the brightness relevant states in DisplayPowerController agnostic fashion."
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java17
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java276
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessEvent.java262
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessReason.java200
-rw-r--r--services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java78
-rw-r--r--services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java92
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;
+ }
+}