当前位置:   article > 正文

Android 系统背光设置_android automaticbrightnesscontroller

android automaticbrightnesscontroller

一、一般设置

1、手动设置背光API

  1. // 修改当前Activity界面的窗口亮度
  2. private void setScreenLight(int brightness) {
  3. WindowManager.LayoutParams lp = getWindow().getAttributes();
  4. lp.screenBrightness = Float.valueOf(brightness) * (1f / 255f);
  5. getWindow().setAttributes(lp);
  6. }
  7. // 修改系统的亮度值
  8. public void setScreenLight(int brightness) {
  9. Uri uri = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
  10. ContentResolver contentResolver = getContentResolver();
  11. Settings.System.putInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
  12. contentResolver.notifyChange(uri, null);
  13. }

 

2、设置系统背光默认亮度值

  1. #frameworks/base/core/res/res/values/config.xml
  2. <integer name="config_screenBrightnessSettingMinimum">2</integer>
  3. <integer name="config_screenBrightnessDim">2</integer>

系统背光节点路径:/sys/class/leds/lcd-backlight/brightness

 

3、自动背光配置设置

自动背光涉及光感值与亮度值对应,需要根据项目进行设置光感和背光值数组,一一对应

  1. # frameworks/base/core/res/res/values/config.xml
  2. <integer-array name="config_autoBrightnessLevels">
  3. ... 填写亮度值数组 ...
  4. </integer-array>
  5. <integer-array name="config_autoBrightnessLcdBacklightValues">
  6. ... 填写光感值数组 ...
  7. </integer-array>

 

二、流程分析

系统手动设置,待机休眠等都是通过 PowerManagerService.java 统一管理,自动背光则是由 AutomaticBrightnessController.java 管理。最后统一调用 DisplayPowerController.java 进行处理。

 1、frameworks/base/services/core/java/com/android/server/display/AutomaticBrightnessController.java  主要相关操作:

通过监听L-sersor 值变化发送 handleLightSensorEvent  走到  updateAutoBrightness 函数,最终调用到 DisplayPowerController.java updateBrightness函数。

  1. // 内部创建一个光感监听
  2. private final SensorEventListener mLightSensorListener = new SensorEventListener() {
  3. @Override
  4. public void onSensorChanged(SensorEvent event) {
  5. if (mLightSensorEnabled) {
  6. final long time = SystemClock.uptimeMillis();
  7. final float lux = event.values[0];
  8. handleLightSensorEvent(time, lux);
  9. }
  10. }
  11. @Override
  12. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  13. // Not used.
  14. }
  15. };
  16. // 通知update背光
  17. private void updateAutoBrightness(boolean sendUpdate) {
  18. if (!mAmbientLuxValid) {
  19. return;
  20. }
  21. // 根据光感值计算对应背光值
  22. float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
  23. float gamma = 1.0f;
  24. if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
  25. && mScreenAutoBrightnessAdjustment != 0.0f) {
  26. final float adjGamma = MathUtils.pow(mScreenAutoBrightnessAdjustmentMaxGamma,
  27. Math.min(1.0f, Math.max(-1.0f, -mScreenAutoBrightnessAdjustment)));
  28. gamma *= adjGamma;
  29. if (DEBUG) {
  30. Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
  31. }
  32. }
  33. if (gamma != 1.0f) {
  34. final float in = value;
  35. value = MathUtils.pow(value, gamma);
  36. if (DEBUG) {
  37. Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
  38. + ", in=" + in + ", out=" + value);
  39. }
  40. }
  41. int newScreenAutoBrightness =
  42. clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
  43. if (mScreenAutoBrightness != newScreenAutoBrightness) {
  44. if (DEBUG) {
  45. Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
  46. + mScreenAutoBrightness + ", newScreenAutoBrightness="
  47. + newScreenAutoBrightness);
  48. }
  49. mScreenAutoBrightness = newScreenAutoBrightness;
  50. mLastScreenAutoBrightnessGamma = gamma;
  51. if (sendUpdate) {
  52. // 通知mCallbacks背光改变,mCallbacks 即是 DisplayPowerController 类对象
  53. mCallbacks.updateBrightness();
  54. }
  55. }
  56. }
  57. // mCallbacks中调用获取当前的自动背光值,后续进行设置
  58. public int getAutomaticScreenBrightness() {
  59. if (!mAmbientLuxValid) {
  60. return -1;
  61. }
  62. if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) {
  63. return (int) (mScreenAutoBrightness * mDozeScaleFactor);
  64. }
  65. return mScreenAutoBrightness;
  66. }

 

2、frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java 主要操作:

上层背光相关操作最终都是走到 PowerManagerService ,统一处理,这里只看设置 SCREEN_BRIGHTNESS 值的流程。通过 SettingsObserver 监听值变化,最终调用到 DisplayPowerController.java requestPowerState 函数。

  1. // 系统启动时进行初始化操作
  2. public void systemReady(IAppOpsService appOps) {
  3. ... ...
  4. // 绑定监听
  5. resolver.registerContentObserver(Settings.System.getUriFor(
  6. Settings.System.SCREEN_BRIGHTNESS),
  7. false, mSettingsObserver, UserHandle.USER_ALL);
  8. resolver.registerContentObserver(Settings.System.getUriFor(
  9. Settings.System.SCREEN_BRIGHTNESS_MODE),
  10. false, mSettingsObserver, UserHandle.USER_ALL);
  11. ... ...
  12. }
  13. // 监听变化发送 handleSettingsChangedLocked
  14. private final class SettingsObserver extends ContentObserver {
  15. public SettingsObserver(Handler handler) {
  16. super(handler);
  17. }
  18. @Override
  19. public void onChange(boolean selfChange, Uri uri) {
  20. synchronized (mLock) {
  21. handleSettingsChangedLocked();
  22. }
  23. }
  24. }
  25. //handleSettingsChangedLocked -> updatePowerStateLocked -> updateDisplayPowerStateLocked
  26. /**
  27. *异步更新显示电源状态。 更新完成后,mDisplayReady将设置为true。 显示控制器会发布一条消息,告诉
  28. *我们实际的显示电源状态何时已更新,因此我们回到这里进行仔细检查并完成。
  29. *每次该功能都会重新计算显示功率状态。
  30. *@return如果显示准备就绪,则为True。
  31. */
  32. private boolean updateDisplayPowerStateLocked(int dirty) {
  33. final boolean oldDisplayReady = mDisplayReady;
  34. if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
  35. | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
  36. | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |
  37. DIRTY_QUIESCENT)) != 0) {
  38. mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
  39. ... ...
  40. // 修改更新 mDisplayPowerRequest 亮度值等属性
  41. mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
  42. mDisplayPowerRequest.useAutoBrightness = autoBrightness;
  43. mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
  44. mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
  45. updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
  46. ... ...
  47. // 最终调用 DisplayPowerController 处理
  48. mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,mRequestWaitForNegativeProximity);
  49. ... ...
  50. }
  51. return mDisplayReady && !oldDisplayReady;
  52. }

 

3、frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java 主要相关方法分析

通过  Settings.System.SCREEN_BRIGHTNESS 手动设置值,是从调用 requestPowerState 开始,最终调用 sendUpdatePowerStateLocked,如下

  1. // 通过设置settings值手动更新亮度调用
  2. public boolean requestPowerState(DisplayPowerRequest request,
  3. boolean waitForNegativeProximity) {
  4. if (DEBUG) {
  5. Slog.d(TAG, "requestPowerState: "
  6. + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
  7. }
  8. synchronized (mLock) {
  9. boolean changed = false;
  10. mRequestPowerStateChangedByUser = false;
  11. if (waitForNegativeProximity
  12. && !mPendingWaitForNegativeProximityLocked) {
  13. mPendingWaitForNegativeProximityLocked = true;
  14. changed = true;
  15. }
  16. if (mPendingRequestLocked == null) {
  17. mPendingRequestLocked = new DisplayPowerRequest(request);
  18. changed = true;
  19. } else if (!mPendingRequestLocked.equals(request)) {
  20. // 这里不同是手动设置的调用
  21. mPendingRequestLocked.copyFrom(request);
  22. changed = true;
  23. mRequestPowerStateChangedByUser = true;
  24. }
  25. if (changed) {
  26. mDisplayReadyLocked = false;
  27. }
  28. if (changed && !mPendingRequestChangedLocked) {
  29. mPendingRequestChangedLocked = true;
  30. // 通知更新亮度
  31. sendUpdatePowerStateLocked();
  32. }
  33. return mDisplayReadyLocked;
  34. }
  35. }

自动背光调节的流程调用是从 updateBrightness() 开始,最终也是调用 sendUpdatePowerStateLocked,如下

  1. @Override
  2. public void updateBrightness() {
  3. sendUpdatePowerState();
  4. }
  5. private void sendUpdatePowerState() {
  6. synchronized (mLock) {
  7. sendUpdatePowerStateLocked();
  8. }
  9. }

sendUpdatePowerStateLocked  这个函数就是手动、自动亮度调节最终统一的地方。它里面只是简单的通过handler 发送调用 updatePowerState();updatePowerState() 里面才是真正进行操作的地方。

  1. private void updatePowerState() {
  2. // Update the power state request.
  3. ... ...
  4. // P-Sensor的靠近操作
  5. if (mProximitySensor != null) {
  6. ... ...
  7. } else {
  8. mWaitingForNegativeProximity = false;
  9. }
  10. if (mScreenOffBecauseOfProximity) {
  11. state = Display.STATE_OFF;
  12. }
  13. // 配置自动亮度值
  14. boolean slowChange = false;
  15. if (brightness < 0) {
  16. if (autoBrightnessEnabled) {
  17. // 这里就是获取 AutomaticBrightnessController 保存的自动亮度值
  18. brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
  19. }
  20. if (brightness >= 0) {
  21. // 这里就是保证 brightness 在系统最小最大设置值 10 ~ 255 之间
  22. // 具体看 frameworks/base/core/res/res/values/config.xml 中 config_screenBrightnessSettingMinimum config_screenBrightnessSettingMaximum 值
  23. brightness = clampScreenBrightness(brightness);
  24. if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
  25. slowChange = true; // slowly adapt to auto-brightness
  26. }
  27. mAppliedAutoBrightness = true;
  28. } else {
  29. mAppliedAutoBrightness = false;
  30. }
  31. } else {
  32. mAppliedAutoBrightness = false;
  33. }
  34. // Use default brightness when dozing unless overridden.
  35. if (brightness < 0 && (state == Display.STATE_DOZE
  36. || state == Display.STATE_DOZE_SUSPEND)) {
  37. brightness = mScreenBrightnessDozeConfig;
  38. }
  39. // 这里是我自己添加判断,过滤重复设置亮度
  40. // 保存自动亮度值 mRequestPowerStateAutoBrightness。
  41. // 如果 mRequestPowerStateChangedByUser 手动操作为false,且mRequestPowerStateAutoBrightness也没有变化,就直接return
  42. if (mRequestPowerStateAutoBrightness != brightness) {
  43. mRequestPowerStateAutoBrightness = brightness;
  44. } else if (!mRequestPowerStateChangedByUser) {
  45. Slog.d(TAG, "Brightness no changed");
  46. return;
  47. }
  48. // 这里使用手动亮度值
  49. Slog.d(TAG, "Apply manual brightness " + brightness + " " + mRequestPowerStateAutoBrightness);
  50. if (brightness < 0 || mRequestPowerStateChangedByUser) {
  51. int clampBrightness = clampScreenBrightness(mPowerRequest.screenBrightness);
  52. if (brightness == clampBrightness) {
  53. Slog.d(TAG, "RequestPowerStateChangedByUser Brightness no changed");
  54. return;
  55. }
  56. brightness = clampBrightness;
  57. }
  58. // 这里就是系统自动休眠前,先变暗一会
  59. if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
  60. if (brightness > mScreenBrightnessRangeMinimum) {
  61. brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
  62. mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
  63. }
  64. if (!mAppliedDimming) {
  65. slowChange = false;
  66. }
  67. mAppliedDimming = true;
  68. } else if (mAppliedDimming) {
  69. slowChange = false;
  70. mAppliedDimming = false;
  71. }
  72. ... ...
  73. // 判断屏幕是否是off
  74. if (!mPendingScreenOff) {
  75. ... ...
  76. // 通过判断确定背光响应变化速度
  77. // mBrightnessRampRateSlow 原生是60,是1s调整60亮度
  78. // mBrightnessRampRateFast 原生是180,是1s调整180亮度
  79. boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
  80. if (!mRequestPowerStateChangedByUser && (state == Display.STATE_ON
  81. && mSkipRampState == RAMP_STATE_SKIP_NONE
  82. || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
  83. && !wasOrWillBeInVr) {
  84. // 一般自动亮度变化是会渐变调整的
  85. animateScreenBrightness(brightness,
  86. slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
  87. } else {
  88. // 手动一般是立即变化的,无需动画渐变调整的
  89. animateScreenBrightness(brightness, 0);
  90. }
  91. Slog.d(TAG, "putInt brightness " + brightness);
  92. }
  93. ... ...
  94. }

animateScreenBrightness 内部逻辑是在 frameworks/base/services/core/java/com/android/server/display/RampAnimator.java 中 animateTo 处理。

animateTo 中调用 postAnimationCallback ,在 mAnimationCallback 中一直设置值渐变。

  1. private void postAnimationCallback() {
  2. mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);
  3. }
  4. private void cancelAnimationCallback() {
  5. mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);
  6. }
  7. private final Runnable mAnimationCallback = new Runnable() {
  8. @Override // Choreographer callback
  9. public void run() {
  10. final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
  11. final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)
  12. * 0.000000001f;
  13. mLastFrameTimeNanos = frameTimeNanos;
  14. // Advance the animated value towards the target at the specified rate
  15. // and clamp to the target. This gives us the new current value but
  16. // we keep the animated value around to allow for fractional increments
  17. // towards the target.
  18. final float scale = ValueAnimator.getDurationScale();
  19. if (scale == 0) {
  20. // Animation off.
  21. mAnimatedValue = mTargetValue;
  22. } else {
  23. final float amount = timeDelta * mRate / scale;
  24. if (mTargetValue > mCurrentValue) {
  25. mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue);
  26. } else {
  27. mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue);
  28. }
  29. }
  30. final int oldCurrentValue = mCurrentValue;
  31. mCurrentValue = Math.round(mAnimatedValue);
  32. if (oldCurrentValue != mCurrentValue) {
  33. mProperty.setValue(mObject, mCurrentValue);
  34. }
  35. // mCurrentValue 当前值
  36. // mTargetValue 目标值
  37. if (mTargetValue != mCurrentValue) {
  38. postAnimationCallback();
  39. } else {
  40. mAnimating = false;
  41. if (mListener != null) {
  42. // 通知变化完成
  43. mListener.onAnimationEnd();
  44. }
  45. }
  46. }
  47. };

mProperty.setValue(mObject, mCurrentValue); 

这个方法就是实际操作写入背光值的地方,往下就是通过 native 调用处理。到这里背光设置就完成了。

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/713825
推荐阅读
相关标签
  

闽ICP备14008679号