Loading services/core/java/com/android/server/display/AutomaticBrightnessController.java +23 −2 Original line number Diff line number Diff line Loading @@ -54,6 +54,10 @@ class AutomaticBrightnessController { private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false; public static final int AUTO_BRIGHTNESS_ENABLED = 1; public static final int AUTO_BRIGHTNESS_DISABLED = 2; public static final int AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE = 3; // How long the current sensor reading is assumed to be valid beyond the current time. // This provides a bit of prediction, as well as ensures that the weight for the last sample is // non-zero, which in turn ensures that the total weight is non-zero. Loading Loading @@ -214,6 +218,7 @@ class AutomaticBrightnessController { private IActivityTaskManager mActivityTaskManager; private PackageManager mPackageManager; private Context mContext; private int mState = AUTO_BRIGHTNESS_DISABLED; private final Injector mInjector; Loading Loading @@ -331,10 +336,11 @@ class AutomaticBrightnessController { return mCurrentBrightnessMapper.getAutoBrightnessAdjustment(); } public void configure(boolean enable, @Nullable BrightnessConfiguration configuration, public void configure(int state, @Nullable BrightnessConfiguration configuration, float brightness, boolean userChangedBrightness, float adjustment, boolean userChangedAutoBrightnessAdjustment, int displayPolicy) { mHbmController.setAutoBrightnessEnabled(enable); mState = state; mHbmController.setAutoBrightnessEnabled(mState); // While dozing, the application processor may be suspended which will prevent us from // receiving new information from the light sensor. On some devices, we may be able to // switch to a wake-up light sensor instead but for now we will simply disable the sensor Loading @@ -346,6 +352,7 @@ class AutomaticBrightnessController { if (userChangedAutoBrightnessAdjustment) { changed |= setAutoBrightnessAdjustment(adjustment); } final boolean enable = mState == AUTO_BRIGHTNESS_ENABLED; if (userChangedBrightness && enable) { // Update the brightness curve with the new user control point. It's critical this // happens after we update the autobrightness adjustment since it may reset it. Loading Loading @@ -459,6 +466,7 @@ class AutomaticBrightnessController { public void dump(PrintWriter pw) { pw.println(); pw.println("Automatic Brightness Controller Configuration:"); pw.println(" mState=" + configStateToString(mState)); pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); pw.println(" mDozeScaleFactor=" + mDozeScaleFactor); Loading Loading @@ -520,6 +528,19 @@ class AutomaticBrightnessController { mScreenBrightnessThresholds.dump(pw); } private String configStateToString(int state) { switch (state) { case AUTO_BRIGHTNESS_ENABLED: return "AUTO_BRIGHTNESS_ENABLED"; case AUTO_BRIGHTNESS_DISABLED: return "AUTO_BRIGHTNESS_DISABLED"; case AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE: return "AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE"; default: return String.valueOf(state); } } private boolean setLightSensorEnabled(boolean enable) { if (enable) { if (!mLightSensorEnabled) { Loading services/core/java/com/android/server/display/DisplayPowerController.java +70 −4 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.display.BrightnessSynchronizer; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FrameworkStatsLog; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.display.RampAnimator.DualRampAnimator; Loading Loading @@ -127,6 +128,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final int MSG_STOP = 9; private static final int MSG_UPDATE_BRIGHTNESS = 10; private static final int MSG_UPDATE_RBC = 11; private static final int MSG_STATSD_HBM_BRIGHTNESS = 12; private static final int PROXIMITY_UNKNOWN = -1; private static final int PROXIMITY_NEGATIVE = 0; Loading @@ -136,6 +138,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0; private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250; private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500; // Trigger proximity if distance is less than 5 cm. private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; Loading Loading @@ -356,6 +360,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private float mBrightnessRampRateSlowDecrease; private float mBrightnessRampRateSlowIncrease; // Report HBM brightness change to StatsD private int mDisplayStatsId; private float mLastStatsBrightness = PowerManager.BRIGHTNESS_MIN; // Whether or not to skip the initial brightness ramps into STATE_ON. private final boolean mSkipScreenOnBrightnessRamp; Loading Loading @@ -466,6 +473,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call TAG = "DisplayPowerController[" + mDisplayId + "]"; mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); mDisplayStatsId = mUniqueDisplayId.hashCode(); mHandler = new DisplayControllerHandler(handler.getLooper()); if (mDisplayId == Display.DEFAULT_DISPLAY) { Loading Loading @@ -763,6 +771,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mDisplayDevice != device) { mDisplayDevice = device; mUniqueDisplayId = uniqueId; mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayDeviceConfig = config; loadFromDisplayDeviceConfig(token, info); updatePowerState(); Loading Loading @@ -816,7 +825,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call loadNitsRange(mContext.getResources()); setUpAutoBrightness(mContext.getResources(), mHandler); reloadReduceBrightColours(); mHbmController.resetHbmData(info.width, info.height, token, mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mDisplayDeviceConfig.getHighBrightnessModeData()); } Loading Loading @@ -1004,7 +1013,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } }; private final RampAnimator.Listener mRampAnimatorListener = this::sendUpdatePowerState; private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() { @Override public void onAnimationEnd() { sendUpdatePowerState(); final float brightness = mPowerState.getScreenBrightness(); reportStats(brightness); } }; /** Clean up all resources that are accessed via the {@link #mHandler} thread. */ private void cleanupHandlerThreadAfterStop() { Loading Loading @@ -1179,6 +1196,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) && Float.isNaN(brightnessState) && mAutomaticBrightnessController != null; final boolean autoBrightnessDisabledDueToDisplayOff = mPowerRequest.useAutoBrightness && !(state == Display.STATE_ON || autoBrightnessEnabledInDoze); final int autoBrightnessState = autoBrightnessEnabled ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED : autoBrightnessDisabledDueToDisplayOff ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED; final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); Loading Loading @@ -1229,7 +1253,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Configure auto-brightness. if (mAutomaticBrightnessController != null) { hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints(); mAutomaticBrightnessController.configure(autoBrightnessEnabled, mAutomaticBrightnessController.configure(autoBrightnessState, mBrightnessConfiguration, mLastUserSetScreenBrightness, userSetBrightnessChanged, autoBrightnessAdjustment, Loading Loading @@ -1626,11 +1650,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); final IBinder displayToken = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked(); final String displayUniqueId = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); final DisplayDeviceConfig.HighBrightnessModeData hbmData = ddConfig != null ? ddConfig.getHighBrightnessModeData() : null; final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData, displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData, () -> { sendUpdatePowerStateLocked(); postBrightnessChangeRunnable(); Loading Loading @@ -2462,6 +2488,42 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } private void reportStats(float brightness) { float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX; synchronized(mCachedBrightnessInfo) { if (mCachedBrightnessInfo.hbmTransitionPoint == null) { return; } hbmTransitionPoint = mCachedBrightnessInfo.hbmTransitionPoint.value; } final boolean aboveTransition = brightness > hbmTransitionPoint; final boolean oldAboveTransition = mLastStatsBrightness > hbmTransitionPoint; if (aboveTransition || oldAboveTransition) { mLastStatsBrightness = brightness; mHandler.removeMessages(MSG_STATSD_HBM_BRIGHTNESS); if (aboveTransition != oldAboveTransition) { // report immediately logHbmBrightnessStats(brightness, mDisplayStatsId); } else { // delay for rate limiting Message msg = mHandler.obtainMessage(); msg.what = MSG_STATSD_HBM_BRIGHTNESS; msg.arg1 = Float.floatToIntBits(brightness); msg.arg2 = mDisplayStatsId; mHandler.sendMessageDelayed(msg, BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS); } } } private final void logHbmBrightnessStats(float brightness, int displayStatsId) { synchronized (mHandler) { FrameworkStatsLog.write( FrameworkStatsLog.DISPLAY_HBM_BRIGHTNESS_CHANGED, displayStatsId, brightness); } } private final class DisplayControllerHandler extends Handler { public DisplayControllerHandler(Looper looper) { super(looper, null, true /*async*/); Loading Loading @@ -2526,6 +2588,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call final int justActivated = msg.arg2; handleRbcChanged(strengthChanged == 1, justActivated == 1); break; case MSG_STATSD_HBM_BRIGHTNESS: logHbmBrightnessStats(Float.intBitsToFloat(msg.arg1), msg.arg2); break; } } } Loading services/core/java/com/android/server/display/HighBrightnessModeController.java +63 −8 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.util.TimeUtils; import android.view.SurfaceControlHdrLayerInfoListener; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData; import com.android.server.display.DisplayManagerService.Clock; Loading Loading @@ -80,6 +81,7 @@ class HighBrightnessModeController { private boolean mIsInAllowedAmbientRange = false; private boolean mIsTimeAvailable = false; private boolean mIsAutoBrightnessEnabled = false; private boolean mIsAutoBrightnessOffByState = false; private float mBrightness; private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; private boolean mIsHdrLayerPresent = false; Loading @@ -88,6 +90,7 @@ class HighBrightnessModeController { private int mWidth; private int mHeight; private float mAmbientLux; private int mDisplayStatsId; /** * If HBM is currently running, this is the start time for the current HBM session. Loading @@ -102,15 +105,15 @@ class HighBrightnessModeController { private LinkedList<HbmEvent> mEvents = new LinkedList<>(); HighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken, float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback, Context context) { this(new Injector(), handler, width, height, displayToken, brightnessMin, brightnessMax, hbmData, hbmChangeCallback, context); String displayUniqueId, float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback, Context context) { this(new Injector(), handler, width, height, displayToken, displayUniqueId, brightnessMin, brightnessMax, hbmData, hbmChangeCallback, context); } @VisibleForTesting HighBrightnessModeController(Injector injector, Handler handler, int width, int height, IBinder displayToken, float brightnessMin, float brightnessMax, IBinder displayToken, String displayUniqueId, float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback, Context context) { mInjector = injector; Loading @@ -126,10 +129,13 @@ class HighBrightnessModeController { mRecalcRunnable = this::recalculateTimeAllowance; mHdrListener = new HdrListener(); resetHbmData(width, height, displayToken, hbmData); resetHbmData(width, height, displayToken, displayUniqueId, hbmData); } void setAutoBrightnessEnabled(boolean isEnabled) { void setAutoBrightnessEnabled(int state) { final boolean isEnabled = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED; mIsAutoBrightnessOffByState = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE; if (!deviceSupportsHbm() || isEnabled == mIsAutoBrightnessEnabled) { return; } Loading Loading @@ -231,10 +237,12 @@ class HighBrightnessModeController { mSettingsObserver.stopObserving(); } void resetHbmData(int width, int height, IBinder displayToken, HighBrightnessModeData hbmData) { void resetHbmData(int width, int height, IBinder displayToken, String displayUniqueId, HighBrightnessModeData hbmData) { mWidth = width; mHeight = height; mHbmData = hbmData; mDisplayStatsId = displayUniqueId.hashCode(); unregisterHdrListener(); mSkinThermalStatusObserver.stopObserving(); Loading Loading @@ -275,6 +283,7 @@ class HighBrightnessModeController { + (mIsAutoBrightnessEnabled ? "" : " (old/invalid)")); pw.println(" mIsInAllowedAmbientRange=" + mIsInAllowedAmbientRange); pw.println(" mIsAutoBrightnessEnabled=" + mIsAutoBrightnessEnabled); pw.println(" mIsAutoBrightnessOffByState=" + mIsAutoBrightnessOffByState); pw.println(" mIsHdrLayerPresent=" + mIsHdrLayerPresent); pw.println(" mBrightnessMin=" + mBrightnessMin); pw.println(" mBrightnessMax=" + mBrightnessMax); Loading Loading @@ -436,11 +445,52 @@ class HighBrightnessModeController { private void updateHbmMode() { int newHbmMode = calculateHighBrightnessMode(); if (mHbmMode != newHbmMode) { updateHbmStats(mHbmMode, newHbmMode); mHbmMode = newHbmMode; mHbmChangeCallback.run(); } } private void updateHbmStats(int mode, int newMode) { int state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF; if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_HDR; } else if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT; } int reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN; boolean oldHbmSv = (mode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT); boolean newHbmSv = (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT); if (oldHbmSv && !newHbmSv) { // If more than one conditions are flipped and turn off HBM sunlight // visibility, only one condition will be reported to make it simple. if (!mIsAutoBrightnessEnabled && mIsAutoBrightnessOffByState) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_DISPLAY_OFF; } else if (!mIsAutoBrightnessEnabled) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_AUTOBRIGHTNESS_OFF; } else if (!mIsInAllowedAmbientRange) { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_LUX_DROP; } else if (!mIsTimeAvailable) { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_TIME_LIMIT; } else if (!mIsThermalStatusWithinLimit) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT; } else if (mIsHdrLayerPresent) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_HDR_PLAYING; } else if (mIsBlockedByLowPowerMode) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_BATTERY_SAVE_ON; } } mInjector.reportHbmStateChange(mDisplayStatsId, state, reason); } private int calculateHighBrightnessMode() { if (!deviceSupportsHbm()) { return BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; Loading Loading @@ -642,5 +692,10 @@ class HighBrightnessModeController { return IThermalService.Stub.asInterface( ServiceManager.getService(Context.THERMAL_SERVICE)); } public void reportHbmStateChange(int display, int state, int reason) { FrameworkStatsLog.write( FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED, display, state, reason); } } } services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +6 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.display; import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; Loading Loading @@ -111,7 +113,7 @@ public class AutomaticBrightnessControllerTest { // Configure the brightness controller and grab an instance of the sensor listener, // through which we can deliver fake (for test) sensor values. controller.configure(true /* enable */, null /* configuration */, controller.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0 /* brightness */, false /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading Loading @@ -227,7 +229,7 @@ public class AutomaticBrightnessControllerTest { listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 1000)); // User sets brightness to 100 mController.configure(true /* enable */, null /* configuration */, mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading @@ -250,7 +252,7 @@ public class AutomaticBrightnessControllerTest { listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 1000)); // User sets brightness to 100 mController.configure(true /* enable */, null /* configuration */, mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading @@ -267,7 +269,7 @@ public class AutomaticBrightnessControllerTest { verifyNoMoreInteractions(mBrightnessMappingStrategy); // User sets idle brightness to 0.5 mController.configure(true /* enable */, null /* configuration */, mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java +158 −19 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/display/AutomaticBrightnessController.java +23 −2 Original line number Diff line number Diff line Loading @@ -54,6 +54,10 @@ class AutomaticBrightnessController { private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false; public static final int AUTO_BRIGHTNESS_ENABLED = 1; public static final int AUTO_BRIGHTNESS_DISABLED = 2; public static final int AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE = 3; // How long the current sensor reading is assumed to be valid beyond the current time. // This provides a bit of prediction, as well as ensures that the weight for the last sample is // non-zero, which in turn ensures that the total weight is non-zero. Loading Loading @@ -214,6 +218,7 @@ class AutomaticBrightnessController { private IActivityTaskManager mActivityTaskManager; private PackageManager mPackageManager; private Context mContext; private int mState = AUTO_BRIGHTNESS_DISABLED; private final Injector mInjector; Loading Loading @@ -331,10 +336,11 @@ class AutomaticBrightnessController { return mCurrentBrightnessMapper.getAutoBrightnessAdjustment(); } public void configure(boolean enable, @Nullable BrightnessConfiguration configuration, public void configure(int state, @Nullable BrightnessConfiguration configuration, float brightness, boolean userChangedBrightness, float adjustment, boolean userChangedAutoBrightnessAdjustment, int displayPolicy) { mHbmController.setAutoBrightnessEnabled(enable); mState = state; mHbmController.setAutoBrightnessEnabled(mState); // While dozing, the application processor may be suspended which will prevent us from // receiving new information from the light sensor. On some devices, we may be able to // switch to a wake-up light sensor instead but for now we will simply disable the sensor Loading @@ -346,6 +352,7 @@ class AutomaticBrightnessController { if (userChangedAutoBrightnessAdjustment) { changed |= setAutoBrightnessAdjustment(adjustment); } final boolean enable = mState == AUTO_BRIGHTNESS_ENABLED; if (userChangedBrightness && enable) { // Update the brightness curve with the new user control point. It's critical this // happens after we update the autobrightness adjustment since it may reset it. Loading Loading @@ -459,6 +466,7 @@ class AutomaticBrightnessController { public void dump(PrintWriter pw) { pw.println(); pw.println("Automatic Brightness Controller Configuration:"); pw.println(" mState=" + configStateToString(mState)); pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); pw.println(" mDozeScaleFactor=" + mDozeScaleFactor); Loading Loading @@ -520,6 +528,19 @@ class AutomaticBrightnessController { mScreenBrightnessThresholds.dump(pw); } private String configStateToString(int state) { switch (state) { case AUTO_BRIGHTNESS_ENABLED: return "AUTO_BRIGHTNESS_ENABLED"; case AUTO_BRIGHTNESS_DISABLED: return "AUTO_BRIGHTNESS_DISABLED"; case AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE: return "AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE"; default: return String.valueOf(state); } } private boolean setLightSensorEnabled(boolean enable) { if (enable) { if (!mLightSensorEnabled) { Loading
services/core/java/com/android/server/display/DisplayPowerController.java +70 −4 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.display.BrightnessSynchronizer; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FrameworkStatsLog; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.display.RampAnimator.DualRampAnimator; Loading Loading @@ -127,6 +128,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final int MSG_STOP = 9; private static final int MSG_UPDATE_BRIGHTNESS = 10; private static final int MSG_UPDATE_RBC = 11; private static final int MSG_STATSD_HBM_BRIGHTNESS = 12; private static final int PROXIMITY_UNKNOWN = -1; private static final int PROXIMITY_NEGATIVE = 0; Loading @@ -136,6 +138,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0; private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250; private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500; // Trigger proximity if distance is less than 5 cm. private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; Loading Loading @@ -356,6 +360,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private float mBrightnessRampRateSlowDecrease; private float mBrightnessRampRateSlowIncrease; // Report HBM brightness change to StatsD private int mDisplayStatsId; private float mLastStatsBrightness = PowerManager.BRIGHTNESS_MIN; // Whether or not to skip the initial brightness ramps into STATE_ON. private final boolean mSkipScreenOnBrightnessRamp; Loading Loading @@ -466,6 +473,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call TAG = "DisplayPowerController[" + mDisplayId + "]"; mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); mDisplayStatsId = mUniqueDisplayId.hashCode(); mHandler = new DisplayControllerHandler(handler.getLooper()); if (mDisplayId == Display.DEFAULT_DISPLAY) { Loading Loading @@ -763,6 +771,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mDisplayDevice != device) { mDisplayDevice = device; mUniqueDisplayId = uniqueId; mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayDeviceConfig = config; loadFromDisplayDeviceConfig(token, info); updatePowerState(); Loading Loading @@ -816,7 +825,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call loadNitsRange(mContext.getResources()); setUpAutoBrightness(mContext.getResources(), mHandler); reloadReduceBrightColours(); mHbmController.resetHbmData(info.width, info.height, token, mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mDisplayDeviceConfig.getHighBrightnessModeData()); } Loading Loading @@ -1004,7 +1013,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } }; private final RampAnimator.Listener mRampAnimatorListener = this::sendUpdatePowerState; private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() { @Override public void onAnimationEnd() { sendUpdatePowerState(); final float brightness = mPowerState.getScreenBrightness(); reportStats(brightness); } }; /** Clean up all resources that are accessed via the {@link #mHandler} thread. */ private void cleanupHandlerThreadAfterStop() { Loading Loading @@ -1179,6 +1196,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) && Float.isNaN(brightnessState) && mAutomaticBrightnessController != null; final boolean autoBrightnessDisabledDueToDisplayOff = mPowerRequest.useAutoBrightness && !(state == Display.STATE_ON || autoBrightnessEnabledInDoze); final int autoBrightnessState = autoBrightnessEnabled ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED : autoBrightnessDisabledDueToDisplayOff ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED; final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); Loading Loading @@ -1229,7 +1253,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Configure auto-brightness. if (mAutomaticBrightnessController != null) { hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints(); mAutomaticBrightnessController.configure(autoBrightnessEnabled, mAutomaticBrightnessController.configure(autoBrightnessState, mBrightnessConfiguration, mLastUserSetScreenBrightness, userSetBrightnessChanged, autoBrightnessAdjustment, Loading Loading @@ -1626,11 +1650,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); final IBinder displayToken = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked(); final String displayUniqueId = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); final DisplayDeviceConfig.HighBrightnessModeData hbmData = ddConfig != null ? ddConfig.getHighBrightnessModeData() : null; final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData, displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData, () -> { sendUpdatePowerStateLocked(); postBrightnessChangeRunnable(); Loading Loading @@ -2462,6 +2488,42 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } private void reportStats(float brightness) { float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX; synchronized(mCachedBrightnessInfo) { if (mCachedBrightnessInfo.hbmTransitionPoint == null) { return; } hbmTransitionPoint = mCachedBrightnessInfo.hbmTransitionPoint.value; } final boolean aboveTransition = brightness > hbmTransitionPoint; final boolean oldAboveTransition = mLastStatsBrightness > hbmTransitionPoint; if (aboveTransition || oldAboveTransition) { mLastStatsBrightness = brightness; mHandler.removeMessages(MSG_STATSD_HBM_BRIGHTNESS); if (aboveTransition != oldAboveTransition) { // report immediately logHbmBrightnessStats(brightness, mDisplayStatsId); } else { // delay for rate limiting Message msg = mHandler.obtainMessage(); msg.what = MSG_STATSD_HBM_BRIGHTNESS; msg.arg1 = Float.floatToIntBits(brightness); msg.arg2 = mDisplayStatsId; mHandler.sendMessageDelayed(msg, BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS); } } } private final void logHbmBrightnessStats(float brightness, int displayStatsId) { synchronized (mHandler) { FrameworkStatsLog.write( FrameworkStatsLog.DISPLAY_HBM_BRIGHTNESS_CHANGED, displayStatsId, brightness); } } private final class DisplayControllerHandler extends Handler { public DisplayControllerHandler(Looper looper) { super(looper, null, true /*async*/); Loading Loading @@ -2526,6 +2588,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call final int justActivated = msg.arg2; handleRbcChanged(strengthChanged == 1, justActivated == 1); break; case MSG_STATSD_HBM_BRIGHTNESS: logHbmBrightnessStats(Float.intBitsToFloat(msg.arg1), msg.arg2); break; } } } Loading
services/core/java/com/android/server/display/HighBrightnessModeController.java +63 −8 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.util.TimeUtils; import android.view.SurfaceControlHdrLayerInfoListener; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData; import com.android.server.display.DisplayManagerService.Clock; Loading Loading @@ -80,6 +81,7 @@ class HighBrightnessModeController { private boolean mIsInAllowedAmbientRange = false; private boolean mIsTimeAvailable = false; private boolean mIsAutoBrightnessEnabled = false; private boolean mIsAutoBrightnessOffByState = false; private float mBrightness; private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; private boolean mIsHdrLayerPresent = false; Loading @@ -88,6 +90,7 @@ class HighBrightnessModeController { private int mWidth; private int mHeight; private float mAmbientLux; private int mDisplayStatsId; /** * If HBM is currently running, this is the start time for the current HBM session. Loading @@ -102,15 +105,15 @@ class HighBrightnessModeController { private LinkedList<HbmEvent> mEvents = new LinkedList<>(); HighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken, float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback, Context context) { this(new Injector(), handler, width, height, displayToken, brightnessMin, brightnessMax, hbmData, hbmChangeCallback, context); String displayUniqueId, float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback, Context context) { this(new Injector(), handler, width, height, displayToken, displayUniqueId, brightnessMin, brightnessMax, hbmData, hbmChangeCallback, context); } @VisibleForTesting HighBrightnessModeController(Injector injector, Handler handler, int width, int height, IBinder displayToken, float brightnessMin, float brightnessMax, IBinder displayToken, String displayUniqueId, float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback, Context context) { mInjector = injector; Loading @@ -126,10 +129,13 @@ class HighBrightnessModeController { mRecalcRunnable = this::recalculateTimeAllowance; mHdrListener = new HdrListener(); resetHbmData(width, height, displayToken, hbmData); resetHbmData(width, height, displayToken, displayUniqueId, hbmData); } void setAutoBrightnessEnabled(boolean isEnabled) { void setAutoBrightnessEnabled(int state) { final boolean isEnabled = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED; mIsAutoBrightnessOffByState = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE; if (!deviceSupportsHbm() || isEnabled == mIsAutoBrightnessEnabled) { return; } Loading Loading @@ -231,10 +237,12 @@ class HighBrightnessModeController { mSettingsObserver.stopObserving(); } void resetHbmData(int width, int height, IBinder displayToken, HighBrightnessModeData hbmData) { void resetHbmData(int width, int height, IBinder displayToken, String displayUniqueId, HighBrightnessModeData hbmData) { mWidth = width; mHeight = height; mHbmData = hbmData; mDisplayStatsId = displayUniqueId.hashCode(); unregisterHdrListener(); mSkinThermalStatusObserver.stopObserving(); Loading Loading @@ -275,6 +283,7 @@ class HighBrightnessModeController { + (mIsAutoBrightnessEnabled ? "" : " (old/invalid)")); pw.println(" mIsInAllowedAmbientRange=" + mIsInAllowedAmbientRange); pw.println(" mIsAutoBrightnessEnabled=" + mIsAutoBrightnessEnabled); pw.println(" mIsAutoBrightnessOffByState=" + mIsAutoBrightnessOffByState); pw.println(" mIsHdrLayerPresent=" + mIsHdrLayerPresent); pw.println(" mBrightnessMin=" + mBrightnessMin); pw.println(" mBrightnessMax=" + mBrightnessMax); Loading Loading @@ -436,11 +445,52 @@ class HighBrightnessModeController { private void updateHbmMode() { int newHbmMode = calculateHighBrightnessMode(); if (mHbmMode != newHbmMode) { updateHbmStats(mHbmMode, newHbmMode); mHbmMode = newHbmMode; mHbmChangeCallback.run(); } } private void updateHbmStats(int mode, int newMode) { int state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF; if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_HDR; } else if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT; } int reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN; boolean oldHbmSv = (mode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT); boolean newHbmSv = (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT); if (oldHbmSv && !newHbmSv) { // If more than one conditions are flipped and turn off HBM sunlight // visibility, only one condition will be reported to make it simple. if (!mIsAutoBrightnessEnabled && mIsAutoBrightnessOffByState) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_DISPLAY_OFF; } else if (!mIsAutoBrightnessEnabled) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_AUTOBRIGHTNESS_OFF; } else if (!mIsInAllowedAmbientRange) { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_LUX_DROP; } else if (!mIsTimeAvailable) { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_TIME_LIMIT; } else if (!mIsThermalStatusWithinLimit) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT; } else if (mIsHdrLayerPresent) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_HDR_PLAYING; } else if (mIsBlockedByLowPowerMode) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_BATTERY_SAVE_ON; } } mInjector.reportHbmStateChange(mDisplayStatsId, state, reason); } private int calculateHighBrightnessMode() { if (!deviceSupportsHbm()) { return BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; Loading Loading @@ -642,5 +692,10 @@ class HighBrightnessModeController { return IThermalService.Stub.asInterface( ServiceManager.getService(Context.THERMAL_SERVICE)); } public void reportHbmStateChange(int display, int state, int reason) { FrameworkStatsLog.write( FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED, display, state, reason); } } }
services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +6 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.display; import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; Loading Loading @@ -111,7 +113,7 @@ public class AutomaticBrightnessControllerTest { // Configure the brightness controller and grab an instance of the sensor listener, // through which we can deliver fake (for test) sensor values. controller.configure(true /* enable */, null /* configuration */, controller.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0 /* brightness */, false /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading Loading @@ -227,7 +229,7 @@ public class AutomaticBrightnessControllerTest { listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 1000)); // User sets brightness to 100 mController.configure(true /* enable */, null /* configuration */, mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading @@ -250,7 +252,7 @@ public class AutomaticBrightnessControllerTest { listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 1000)); // User sets brightness to 100 mController.configure(true /* enable */, null /* configuration */, mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading @@ -267,7 +269,7 @@ public class AutomaticBrightnessControllerTest { verifyNoMoreInteractions(mBrightnessMappingStrategy); // User sets idle brightness to 0.5 mController.configure(true /* enable */, null /* configuration */, mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */, 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); Loading
services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java +158 −19 File changed.Preview size limit exceeded, changes collapsed. Show changes