android-lightsensor

Android P自动背光原理

2020-04-02  本文已影响0人  xuefeng_apple

目录:
1,sensor 基本架构图
2,Lsensor UI 手动设定
3,Lsensor 自动算法

关键词:
lux : 环境光线
nit: 屏幕亮度
backlight:UI 中设定进度条显示数字

1-sensor 基本架构图
Light sensor 属于sensor 其中的一个设备, 因此架构都一样,light sensor 有I2C 接口,spi 接口,要从硬件上选择一种就可以, 最好选择I2C , 进行i2c通信就可以获取lux 值

图片.png

Lsensor 数据获取步骤(获取lux 可定制开发app)
Setp0:获取传获取传感器对象
Setp1:感器管理器对象
Setp2:定义事件监听器-----》下面有给出在原生code 中获取lux(onSensorChanged)
Setp3:注册事件监听器
Setp4:卸载事件监听器

图片.png

2,Lsensor UI 手动设定
在原生android P code 中,亮度的调节分为三中方式

1) 在设置中手动设定亮度方式

2) 在system UI 中手动设定亮度

3) 在播放视频时候设定亮度

上面的几种方式最后调用都到了updatePowerState(), 手动更改亮度,对自动亮度的调整有影响

2.1 System UI , 设置中进行了设定亮度

frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
图片.png

最后背光的修改都要走到下面的函数

frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
private void animateScreenBrightness(int target, int rate) {……….}

3,Lsensor 自动算法
基本思路:
Stetp 1:创建三条曲线 lux---nits---backlight

mNitsToBacklightSpline = Spline.createSpline(nits, normalizedBacklight);
mBacklightToNitsSpline = Spline.createSpline(normalizedBacklight, nits);
mBrightnessSpline = Spline.createSpline(lux, nits);----->最重要的曲线, lux-->nits (由nits->bightlight)

Step 2:
手动调整了亮度-> addUserDataPoint(float lux, float brightness) ->重新调整曲线(mBrightnessSpline = Spline.createSpline(lux, nits))--->记录用户调整值,根据用户的习惯,重新拟合曲线

Step 3:
最后调用animateScreenBrightness,这里利用设定背光时间rate,逐步更新,达到不闪烁

3.1 code 流程
创建曲线:

frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
frameworks/base/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
public DisplayPowerController(Context context,
        DisplayPowerCallbacks callbacks, Handler handler,SensorManager sensorManager, DisplayBlanker blanker) {
      mBrightnessMapper = BrightnessMappingStrategy.create(resources);
}

下面都是制造商的配置数组, 然后根据配置建立样条曲线

int[] brightnessLevelsBacklight---->config_autoBrightnessLcdBacklightValues
float[] luxLevels------------------>config_autoBrightnessLevels
float[] brightnessLevelsNits------->config_autoBrightnessDisplayValuesNits
float[] nitsRange------------------>config_screenBrightnessNits
int[] backlightRange -------------->config_screenBrightnessBacklight
图片.png
mBrightnessSpline = Spline.createSpline(lux, nits);

用户手动调整了亮度:

frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
frameworks/base/services/core/java/com/android/server/display/AutomaticBrightnessController.java
DisplayPowerController--> BrightnessMappingStrategy.create()-AutomaticBrightnessController-----> mAutomaticBrightnessController.configure
图片.png

下图进行了对比,默认曲线有用户调整后曲线的情况:


图片.png

问题:什么时候用户清除配置,reset 动作 (感觉nrea 不需要考虑)
1, 切换用户
2, BrightnessConfigure 重新配置
3, 屏幕由交互状态进入非交互状态时,这个是有display 状态决定

3.2 animateScreenBrightness 分析

有上面可以知道event 携带参数lux ,根据lux (利用拟合曲线)算出backlight 值,最后由animateScreenBrightness(int target, int rate)函数进行更新,在参数中就有目标target, 更新rate (分fast,slow)。
如果rate = 0 ,直接更新,可能闪屏。
如果rate > 0 ,根据rate 速度逐步进行更新背光值

frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java

rate 配置:


图片.png

更新目标背光流程:

animateScreenBrightness-->mScreenBrightnessRampAnimator.animateTo(target, rate)--->postAnimationCallback();--->mAnimationCallback-->mProperty.setValue(mObject, mCurrentValue);--->

最后走到了:DisplayPowerState.java: setValue-->setScreenBrightness


图片.png
frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java:
图片.png
上一篇 下一篇

猜你喜欢

热点阅读