diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index a817cea1a6748..05d32d1d90235 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -148,6 +148,12 @@ class AutomaticBrightnessController { // The currently accepted nominal ambient light level. private float mAmbientLux; + // The last calculated ambient light level (long time window). + private float mSlowAmbientLux; + + // The last calculated ambient light level (short time window). + private float mFastAmbientLux; + // The last ambient lux value prior to passing the darkening or brightening threshold. private float mPreThresholdLux; @@ -440,6 +446,14 @@ class AutomaticBrightnessController { return mAmbientLux; } + float getSlowAmbientLux() { + return mSlowAmbientLux; + } + + float getFastAmbientLux() { + return mFastAmbientLux; + } + private boolean setDisplayPolicy(int policy) { if (mDisplayPolicy == policy) { return false; @@ -812,20 +826,20 @@ class AutomaticBrightnessController { // proposed ambient light value since the slow value might be sufficiently far enough away // from the fast value to cause a recalculation while its actually just converging on // the fast value still. - float slowAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonLong); - float fastAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonShort); + mSlowAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonLong); + mFastAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonShort); - if ((slowAmbientLux >= mAmbientBrighteningThreshold - && fastAmbientLux >= mAmbientBrighteningThreshold + if ((mSlowAmbientLux >= mAmbientBrighteningThreshold + && mFastAmbientLux >= mAmbientBrighteningThreshold && nextBrightenTransition <= time) - || (slowAmbientLux <= mAmbientDarkeningThreshold - && fastAmbientLux <= mAmbientDarkeningThreshold + || (mSlowAmbientLux <= mAmbientDarkeningThreshold + && mFastAmbientLux <= mAmbientDarkeningThreshold && nextDarkenTransition <= time)) { mPreThresholdLux = mAmbientLux; - setAmbientLux(fastAmbientLux); + setAmbientLux(mFastAmbientLux); if (mLoggingEnabled) { Slog.d(TAG, "updateAmbientLux: " - + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + + ((mFastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + "mBrighteningLuxThreshold=" + mAmbientBrighteningThreshold + ", " + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + "mAmbientLux=" + mAmbientLux); diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 90e4596af420a..20d2d15730527 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -1643,11 +1643,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // brightness cap, RBC state, etc. mTempBrightnessEvent.setTime(System.currentTimeMillis()); mTempBrightnessEvent.setBrightness(brightnessState); + mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId); mTempBrightnessEvent.setReason(mBrightnessReason); mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax()); mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode()); mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags() | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)); + mTempBrightnessEvent.setRbcStrength((mCdsi != null && mCdsi.isReduceBrightColorsActivated()) + ? mCdsi.getReduceBrightColorsStrength() : -1); + mTempBrightnessEvent.setPowerFactor( + mPowerRequest.lowPowerMode ? mPowerRequest.screenLowPowerBrightnessFactor : 1.0f); // 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 = @@ -1656,9 +1661,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call == BrightnessReason.REASON_TEMPORARY; if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition) || brightnessAdjustmentFlags != 0) { + float lastBrightness = mLastBrightnessEvent.getBrightness(); + mTempBrightnessEvent.setInitialBrightness(lastBrightness); + mTempBrightnessEvent.setFastAmbientLux( + mAutomaticBrightnessController == null + ? -1 : mAutomaticBrightnessController.getFastAmbientLux()); + mTempBrightnessEvent.setSlowAmbientLux( + mAutomaticBrightnessController == null + ? -1 : mAutomaticBrightnessController.getSlowAmbientLux()); + mTempBrightnessEvent.setAutomaticBrightnessEnabled(mPowerRequest.useAutoBrightness); 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.setAdjustmentFlags(brightnessAdjustmentFlags); @@ -1666,6 +1679,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call ? BrightnessEvent.FLAG_USER_SET : 0)); Slog.i(mTag, newEvent.toString(/* includeTime= */ false)); + if (userSetBrightnessChanged) { + logManualBrightnessEvent(newEvent); + } if (mBrightnessEventRingBuffer != null) { mBrightnessEventRingBuffer.append(newEvent); } @@ -2753,6 +2769,30 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } + private void logManualBrightnessEvent(BrightnessEvent event) { + float hbmMaxNits = + event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF + ? -1f : convertToNits(event.getHbmMax()); + + // thermalCapNits set to -1 if not currently capping max brightness + float thermalCapNits = + event.getThermalMax() == PowerManager.BRIGHTNESS_MAX + ? -1f : convertToNits(event.getThermalMax()); + + FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED, + convertToNits(event.getInitialBrightness()), + convertToNits(event.getBrightness()), + event.getSlowAmbientLux(), + event.getPhysicalDisplayId(), + event.isShortTermModelActive(), + event.getPowerFactor(), + event.getRbcStrength(), + hbmMaxNits, + thermalCapNits, + event.isAutomaticBrightnessEnabled(), + FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL); + } + private final class DisplayControllerHandler extends Handler { DisplayControllerHandler(Looper looper) { super(looper, null, true /*async*/); diff --git a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java index d831dbd4bb230..70415a3c81c9e 100644 --- a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java +++ b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java @@ -33,17 +33,24 @@ public final class BrightnessEvent { private BrightnessReason mReason = new BrightnessReason(); private int mDisplayId; - private float mLux; - private float mPreThresholdLux; + private String mPhysicalDisplayId; private long mTime; + private float mLux; + private float mFastAmbientLux; + private float mSlowAmbientLux; + private float mPreThresholdLux; + private float mInitialBrightness; private float mBrightness; private float mRecommendedBrightness; private float mPreThresholdBrightness; - private float mHbmMax; - private float mThermalMax; private int mHbmMode; + private float mHbmMax; + private int mRbcStrength; + private float mThermalMax; + private float mPowerFactor; private int mFlags; private int mAdjustmentFlags; + private boolean mAutomaticBrightnessEnabled; public BrightnessEvent(BrightnessEvent that) { copyFrom(that); @@ -60,37 +67,59 @@ public final class BrightnessEvent { * @param that BrightnessEvent which is to be copied */ public void copyFrom(BrightnessEvent that) { + mReason.set(that.getReason()); mDisplayId = that.getDisplayId(); + mPhysicalDisplayId = that.getPhysicalDisplayId(); mTime = that.getTime(); + // Lux values mLux = that.getLux(); + mFastAmbientLux = that.getFastAmbientLux(); + mSlowAmbientLux = that.getSlowAmbientLux(); mPreThresholdLux = that.getPreThresholdLux(); + // Brightness values + mInitialBrightness = that.getInitialBrightness(); mBrightness = that.getBrightness(); mRecommendedBrightness = that.getRecommendedBrightness(); mPreThresholdBrightness = that.getPreThresholdBrightness(); - mHbmMax = that.getHbmMax(); - mThermalMax = that.getThermalMax(); - mFlags = that.getFlags(); + // Different brightness modulations mHbmMode = that.getHbmMode(); - mReason.set(that.getReason()); + mHbmMax = that.getHbmMax(); + mRbcStrength = that.getRbcStrength(); + mThermalMax = that.getThermalMax(); + mPowerFactor = that.getPowerFactor(); + mFlags = that.getFlags(); mAdjustmentFlags = that.getAdjustmentFlags(); + // Auto-brightness setting + mAutomaticBrightnessEnabled = that.isAutomaticBrightnessEnabled(); } /** * A utility to reset the BrightnessEvent to default values */ public void reset() { + mReason.set(null); mTime = SystemClock.uptimeMillis(); + mPhysicalDisplayId = ""; + // Lux values + mLux = 0; + mFastAmbientLux = 0; + mSlowAmbientLux = 0; + mPreThresholdLux = 0; + // Brightness values + mInitialBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; 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; + // Different brightness modulations mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; - mReason.set(null); + mHbmMax = PowerManager.BRIGHTNESS_MAX; + mRbcStrength = 0; + mThermalMax = PowerManager.BRIGHTNESS_MAX; + mPowerFactor = 1f; + mFlags = 0; mAdjustmentFlags = 0; + // Auto-brightness setting + mAutomaticBrightnessEnabled = true; } /** @@ -104,23 +133,34 @@ public final class BrightnessEvent { 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 + return mReason.equals(that.mReason) + && mDisplayId == that.mDisplayId + && mPhysicalDisplayId.equals(that.mPhysicalDisplayId) + && Float.floatToRawIntBits(mLux) == Float.floatToRawIntBits(that.mLux) + && Float.floatToRawIntBits(mFastAmbientLux) + == Float.floatToRawIntBits(that.mFastAmbientLux) + && Float.floatToRawIntBits(mSlowAmbientLux) + == Float.floatToRawIntBits(that.mSlowAmbientLux) + && Float.floatToRawIntBits(mPreThresholdLux) + == Float.floatToRawIntBits(that.mPreThresholdLux) + && Float.floatToRawIntBits(mInitialBrightness) + == Float.floatToRawIntBits(that.mInitialBrightness) && 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(mHbmMax) == Float.floatToRawIntBits(that.mHbmMax) + && mRbcStrength == that.mRbcStrength && Float.floatToRawIntBits(mThermalMax) == Float.floatToRawIntBits(that.mThermalMax) + && Float.floatToRawIntBits(mPowerFactor) + == Float.floatToRawIntBits(that.mPowerFactor) && mFlags == that.mFlags && mAdjustmentFlags == that.mAdjustmentFlags - && mReason.equals(that.mReason); + && mAutomaticBrightnessEnabled == that.mAutomaticBrightnessEnabled; } /** @@ -133,16 +173,23 @@ public final class BrightnessEvent { return (includeTime ? TimeUtils.formatForLogging(mTime) + " - " : "") + "BrightnessEvent: " + "disp=" + mDisplayId + + ", physDisp=" + mPhysicalDisplayId + ", brt=" + mBrightness + ((mFlags & FLAG_USER_SET) != 0 ? "(user_set)" : "") + + ", initBrt=" + mInitialBrightness + ", rcmdBrt=" + mRecommendedBrightness + ", preBrt=" + mPreThresholdBrightness + ", lux=" + mLux + + ", fastLux=" + mFastAmbientLux + + ", slowLux=" + mSlowAmbientLux + ", preLux=" + mPreThresholdLux + ", hbmMax=" + mHbmMax + ", hbmMode=" + BrightnessInfo.hbmToString(mHbmMode) + + ", rbcStrength=" + mRbcStrength + ", thrmMax=" + mThermalMax + + ", powerFactor=" + mPowerFactor + ", flags=" + flagsToString() - + ", reason=" + mReason.toString(mAdjustmentFlags); + + ", reason=" + mReason.toString(mAdjustmentFlags) + + ", autoBrightness=" + mAutomaticBrightnessEnabled; } @Override @@ -150,12 +197,20 @@ public final class BrightnessEvent { return toString(/* includeTime */ true); } + public BrightnessReason getReason() { + return mReason; + } + public void setReason(BrightnessReason reason) { this.mReason = reason; } - public BrightnessReason getReason() { - return mReason; + public long getTime() { + return mTime; + } + + public void setTime(long time) { + this.mTime = time; } public int getDisplayId() { @@ -166,6 +221,14 @@ public final class BrightnessEvent { this.mDisplayId = displayId; } + public String getPhysicalDisplayId() { + return mPhysicalDisplayId; + } + + public void setPhysicalDisplayId(String mPhysicalDisplayId) { + this.mPhysicalDisplayId = mPhysicalDisplayId; + } + public float getLux() { return mLux; } @@ -174,6 +237,22 @@ public final class BrightnessEvent { this.mLux = lux; } + public float getFastAmbientLux() { + return mFastAmbientLux; + } + + public void setFastAmbientLux(float mFastAmbientLux) { + this.mFastAmbientLux = mFastAmbientLux; + } + + public float getSlowAmbientLux() { + return mSlowAmbientLux; + } + + public void setSlowAmbientLux(float mSlowAmbientLux) { + this.mSlowAmbientLux = mSlowAmbientLux; + } + public float getPreThresholdLux() { return mPreThresholdLux; } @@ -182,12 +261,12 @@ public final class BrightnessEvent { this.mPreThresholdLux = preThresholdLux; } - public long getTime() { - return mTime; + public float getInitialBrightness() { + return mInitialBrightness; } - public void setTime(long time) { - this.mTime = time; + public void setInitialBrightness(float mInitialBrightness) { + this.mInitialBrightness = mInitialBrightness; } public float getBrightness() { @@ -214,6 +293,14 @@ public final class BrightnessEvent { this.mPreThresholdBrightness = preThresholdBrightness; } + public int getHbmMode() { + return mHbmMode; + } + + public void setHbmMode(int hbmMode) { + this.mHbmMode = hbmMode; + } + public float getHbmMax() { return mHbmMax; } @@ -222,6 +309,14 @@ public final class BrightnessEvent { this.mHbmMax = hbmMax; } + public int getRbcStrength() { + return mRbcStrength; + } + + public void setRbcStrength(int mRbcStrength) { + this.mRbcStrength = mRbcStrength; + } + public float getThermalMax() { return mThermalMax; } @@ -230,12 +325,12 @@ public final class BrightnessEvent { this.mThermalMax = thermalMax; } - public int getHbmMode() { - return mHbmMode; + public float getPowerFactor() { + return mPowerFactor; } - public void setHbmMode(int hbmMode) { - this.mHbmMode = hbmMode; + public void setPowerFactor(float mPowerFactor) { + this.mPowerFactor = mPowerFactor; } public int getFlags() { @@ -246,6 +341,10 @@ public final class BrightnessEvent { this.mFlags = flags; } + public boolean isShortTermModelActive() { + return (mFlags & FLAG_USER_SET) != 0; + } + public int getAdjustmentFlags() { return mAdjustmentFlags; } @@ -254,6 +353,14 @@ public final class BrightnessEvent { this.mAdjustmentFlags = adjustmentFlags; } + public boolean isAutomaticBrightnessEnabled() { + return mAutomaticBrightnessEnabled; + } + + public void setAutomaticBrightnessEnabled(boolean mAutomaticBrightnessEnabled) { + this.mAutomaticBrightnessEnabled = mAutomaticBrightnessEnabled; + } + private String flagsToString() { return ((mFlags & FLAG_USER_SET) != 0 ? "user_set " : "") + ((mFlags & FLAG_RBC) != 0 ? "rbc " : "") diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java index 6e304163995be..366dfd1efd29a 100644 --- a/services/core/java/com/android/server/display/color/ColorDisplayService.java +++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java @@ -1515,6 +1515,10 @@ public final class ColorDisplayService extends SystemService { return mReduceBrightColorsTintController.isActivated(); } + public int getReduceBrightColorsStrength() { + return mReduceBrightColorsTintController.getStrength(); + } + /** * Gets the computed brightness, in nits, when the reduce bright colors feature is applied * at the current strength. 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 index e305957c62905..c4435b77628a7 100644 --- a/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java +++ b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java @@ -39,16 +39,23 @@ public final class BrightnessEventTest { mBrightnessEvent = new BrightnessEvent(1); mBrightnessEvent.setReason( getReason(BrightnessReason.REASON_DOZE, BrightnessReason.MODIFIER_LOW_POWER)); + mBrightnessEvent.setPhysicalDisplayId("test"); mBrightnessEvent.setLux(100.0f); + mBrightnessEvent.setFastAmbientLux(90.0f); + mBrightnessEvent.setSlowAmbientLux(85.0f); mBrightnessEvent.setPreThresholdLux(150.0f); mBrightnessEvent.setTime(System.currentTimeMillis()); + mBrightnessEvent.setInitialBrightness(25.0f); mBrightnessEvent.setBrightness(0.6f); mBrightnessEvent.setRecommendedBrightness(0.6f); mBrightnessEvent.setHbmMax(0.62f); + mBrightnessEvent.setRbcStrength(-1); mBrightnessEvent.setThermalMax(0.65f); + mBrightnessEvent.setPowerFactor(0.2f); mBrightnessEvent.setHbmMode(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF); mBrightnessEvent.setFlags(0); mBrightnessEvent.setAdjustmentFlags(0); + mBrightnessEvent.setAutomaticBrightnessEnabled(true); } @Test @@ -63,12 +70,15 @@ public final class BrightnessEventTest { 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 ]"; + "BrightnessEvent: disp=1, physDisp=test, brt=0.6, initBrt=25.0, rcmdBrt=0.6," + + " preBrt=NaN, lux=100.0, fastLux=90.0, slowLux=85.0, preLux=150.0, hbmMax=0.62," + + " hbmMode=off, rbcStrength=-1, thrmMax=0.65, powerFactor=0.2, flags=, reason=doze" + + " [ low_pwr ], autoBrightness=true"; assertEquals(actualString, expectedString); } + + private BrightnessReason getReason(int reason, int modifier) { BrightnessReason brightnessReason = new BrightnessReason(); brightnessReason.setReason(reason);