diff options
| author | 2022-04-09 00:56:52 +0000 | |
|---|---|---|
| committer | 2022-04-19 11:01:10 +0000 | |
| commit | 0bdd9352a024459192e557bf8ab42bbcd54df6fc (patch) | |
| tree | d0e8ccf023c4896e1ac7bea36c8ba4a9eb0281e4 | |
| parent | 323def835032dfec518750e348e2f2ae36ab3d34 (diff) | |
Add brightness event logging.
- Add more data/context to BrightnessEvents.
- Log BrightnessEvents as they occur.
- Replace BrightnessReason logging with BrightnessEvent.
Example output:
BrightnessEvent: disp=0, brt=0.050589137, rcmdBrt=0.050589137, preBrt=NaN, lux=194.08928, preLux=0.0, hbmMax=0.62, hbmMode=off, thrmMax=1.0, flags=, reason=automatic
Bug: 227483176
Test: Manually verify output of dumpsys and logcat
Test: atest com.android.server.display
Change-Id: I0cb88baf6c66e9ff6b07fb32666258cad4fe434f
| -rw-r--r-- | services/core/java/com/android/server/display/AutomaticBrightnessController.java | 40 | ||||
| -rw-r--r-- | services/core/java/com/android/server/display/DisplayPowerController.java | 187 |
2 files changed, 193 insertions, 34 deletions
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 54e83ec5303a..4bba68671968 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -46,6 +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 java.io.PrintWriter; @@ -147,6 +148,9 @@ class AutomaticBrightnessController { // The currently accepted nominal ambient light level. private float mAmbientLux; + // The last ambient lux value prior to passing the darkening or brightening threshold. + private float mPreThresholdLux; + // True if mAmbientLux holds a valid value. private boolean mAmbientLuxValid; @@ -154,6 +158,9 @@ class AutomaticBrightnessController { private float mAmbientBrighteningThreshold; private float mAmbientDarkeningThreshold; + // The last brightness value prior to passing the darkening or brightening threshold. + private float mPreThresholdBrightness; + // The screen brightness threshold at which to brighten or darken the screen. private float mScreenBrighteningThreshold; private float mScreenDarkeningThreshold; @@ -325,6 +332,21 @@ class AutomaticBrightnessController { } public float getAutomaticScreenBrightness() { + return getAutomaticScreenBrightness(null); + } + + 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) + | (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE + ? BrightnessEvent.FLAG_DOZE_SCALE : 0); + } + if (!mAmbientLuxValid) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } @@ -506,6 +528,8 @@ class AutomaticBrightnessController { pw.println(" mCurrentLightSensorRate=" + mCurrentLightSensorRate); pw.println(" mAmbientLux=" + mAmbientLux); pw.println(" mAmbientLuxValid=" + mAmbientLuxValid); + pw.println(" mPreThesholdLux=" + mPreThresholdLux); + pw.println(" mPreThesholdBrightness=" + mPreThresholdBrightness); pw.println(" mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold); pw.println(" mAmbientDarkeningThreshold=" + mAmbientDarkeningThreshold); pw.println(" mScreenBrighteningThreshold=" + mScreenBrighteningThreshold); @@ -574,7 +598,11 @@ class AutomaticBrightnessController { } else if (mLightSensorEnabled) { mLightSensorEnabled = false; mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; + if (!mAmbientLuxValid) { + mPreThresholdLux = PowerManager.BRIGHTNESS_INVALID_FLOAT; + } mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mPreThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; mRecentLightSamples = 0; mAmbientLightRingBuffer.clear(); mCurrentLightSensorRate = -1; @@ -790,6 +818,7 @@ class AutomaticBrightnessController { || (slowAmbientLux <= mAmbientDarkeningThreshold && fastAmbientLux <= mAmbientDarkeningThreshold && nextDarkenTransition <= time)) { + mPreThresholdLux = mAmbientLux; setAmbientLux(fastAmbientLux); if (mLoggingEnabled) { Slog.d(TAG, "updateAmbientLux: " @@ -834,11 +863,11 @@ class AutomaticBrightnessController { // If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold, // in which case we ignore the new screen brightness if it doesn't differ enough from the // previous one. - if (!Float.isNaN(mScreenAutoBrightness) - && !isManuallySet + boolean withinThreshold = !Float.isNaN(mScreenAutoBrightness) && newScreenAutoBrightness > mScreenDarkeningThreshold - && newScreenAutoBrightness < mScreenBrighteningThreshold - && currentBrightnessWithinAllowedRange) { + && newScreenAutoBrightness < mScreenBrighteningThreshold; + + if (withinThreshold && !isManuallySet && currentBrightnessWithinAllowedRange) { if (mLoggingEnabled) { Slog.d(TAG, "ignoring newScreenAutoBrightness: " + mScreenDarkeningThreshold + " < " + newScreenAutoBrightness @@ -853,6 +882,9 @@ class AutomaticBrightnessController { + "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + "newScreenAutoBrightness=" + newScreenAutoBrightness); } + if (!withinThreshold) { + mPreThresholdBrightness = mScreenAutoBrightness; + } mScreenAutoBrightness = newScreenAutoBrightness; mScreenBrighteningThreshold = clampScreenBrightness( mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness)); diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 67268e23c5b9..698f41f23e98 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -216,9 +216,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private final float mScreenBrightnessDefault; - // Previously logged screen brightness. Used for autobrightness event dumpsys. - private float mPreviousScreenBrightness = Float.NaN; - // The minimum allowed brightness while in VR. private final float mScreenBrightnessForVrRangeMinimum; @@ -394,8 +391,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private final Runnable mOnBrightnessChangeRunnable; - // Used for keeping record in dumpsys for when and to which brightness auto adaptions were made. - private RingBuffer<AutobrightnessEvent> mAutobrightnessEventRingBuffer; + private final BrightnessEvent mLastBrightnessEvent; + private final BrightnessEvent mTempBrightnessEvent; + + // Keeps a record of brightness changes for dumpsys. + private RingBuffer<BrightnessEvent> mBrightnessEventRingBuffer; // A record of state for skipping brightness ramps. private int mSkipRampState = RAMP_STATE_SKIP_NONE; @@ -455,6 +455,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set. private float mTemporaryAutoBrightnessAdjustment; + private boolean mIsRbcActive; + // Animators. private ObjectAnimator mColorFadeOnAnimator; private ObjectAnimator mColorFadeOffAnimator; @@ -481,6 +483,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); mDisplayStatsId = mUniqueDisplayId.hashCode(); mHandler = new DisplayControllerHandler(handler.getLooper()); + mLastBrightnessEvent = new BrightnessEvent(mDisplayId); + mTempBrightnessEvent = new BrightnessEvent(mDisplayId); if (mDisplayId == Display.DEFAULT_DISPLAY) { mBatteryStats = BatteryStatsService.getService(); @@ -634,8 +638,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call for (int i = 0; i < mNitsRange.length; i++) { adjustedNits[i] = mCdsi.getReduceBrightColorsAdjustedBrightnessNits(mNitsRange[i]); } - mAutomaticBrightnessController.recalculateSplines(mCdsi.isReduceBrightColorsActivated(), - adjustedNits); + mIsRbcActive = mCdsi.isReduceBrightColorsActivated(); + mAutomaticBrightnessController.recalculateSplines(mIsRbcActive, adjustedNits); // If rbc is turned on, off or there is a change in strength, we want to reset the short @@ -991,8 +995,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mDisplayDeviceConfig.getAmbientHorizonShort(), mDisplayDeviceConfig.getAmbientHorizonLong()); - mAutobrightnessEventRingBuffer = - new RingBuffer<>(AutobrightnessEvent.class, RINGBUFFER_MAX); + mBrightnessEventRingBuffer = + new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX); } else { mUseSoftwareAutoBrightnessConfig = false; } @@ -1088,6 +1092,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call boolean mustInitialize = false; int brightnessAdjustmentFlags = 0; mBrightnessReasonTemp.set(null); + mTempBrightnessEvent.reset(); synchronized (mLock) { if (mStopped) { return; @@ -1314,7 +1319,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (Float.isNaN(brightnessState)) { float newAutoBrightnessAdjustment = autoBrightnessAdjustment; if (autoBrightnessEnabled) { - brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(); + brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness( + mTempBrightnessEvent); newAutoBrightnessAdjustment = mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); } @@ -1376,6 +1382,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // we broadcast this change through setting. final float unthrottledBrightnessState = brightnessState; if (mBrightnessThrottler.isThrottled()) { + mTempBrightnessEvent.thermalMax = mBrightnessThrottler.getBrightnessCap(); brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap()); mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED); if (!mAppliedThrottling) { @@ -1567,13 +1574,35 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment."); } - // Add any automatic changes to autobrightness ringbuffer for dumpsys. - if (mBrightnessReason.reason == BrightnessReason.REASON_AUTOMATIC - && !BrightnessSynchronizer.floatEquals( - mPreviousScreenBrightness, brightnessState)) { - mPreviousScreenBrightness = brightnessState; - mAutobrightnessEventRingBuffer.append(new AutobrightnessEvent( - System.currentTimeMillis(), brightnessState)); + + // 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); + // 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; + if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition) + || brightnessAdjustmentFlags != 0) { + mLastBrightnessEvent.copyFrom(mTempBrightnessEvent); + BrightnessEvent newEvent = new BrightnessEvent(mTempBrightnessEvent); + + // 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); + Slog.i(TAG, newEvent.toString(/* includeTime= */ false)); + + if (mBrightnessEventRingBuffer != null) { + mBrightnessEventRingBuffer.append(newEvent); + } } // Update display white-balance. @@ -2482,6 +2511,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mPendingScreenOff=" + mPendingScreenOff); pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy)); + pw.println(" mIsRbcActive=" + mIsRbcActive); if (mScreenBrightnessRampAnimator != null) { pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" @@ -2503,7 +2533,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.dump(pw); - dumpAutobrightnessEvents(pw); + dumpBrightnessEvents(pw); } if (mHbmController != null) { @@ -2560,16 +2590,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } - private void dumpAutobrightnessEvents(PrintWriter pw) { - int size = mAutobrightnessEventRingBuffer.size(); + private void dumpBrightnessEvents(PrintWriter pw) { + int size = mBrightnessEventRingBuffer.size(); if (size < 1) { pw.println("No Automatic Brightness Adjustments"); return; } pw.println("Automatic Brightness Adjustments Last " + size + " Events: "); - AutobrightnessEvent[] eventArray = mAutobrightnessEventRingBuffer.toArray(); - for (int i = 0; i < mAutobrightnessEventRingBuffer.size(); i++) { + BrightnessEvent[] eventArray = mBrightnessEventRingBuffer.toArray(); + for (int i = 0; i < mBrightnessEventRingBuffer.size(); i++) { pw.println(" " + eventArray[i].toString()); } } @@ -2646,18 +2676,115 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } - private static class AutobrightnessEvent { - final long mTime; - final float mBrightness; - - AutobrightnessEvent(long time, float brightness) { - mTime = time; - mBrightness = brightness; + 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 TimeUtils.formatForLogging(mTime) + " - Brightness: " + mBrightness; + 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 " : ""); } } |