目錄:
1,sensor 基本架構圖
2,Lsensor UI 手動設定
3,Lsensor 自動算法
關鍵詞:
lux : 環(huán)境光線
nit: 屏幕亮度
backlight:UI 中設定進度條顯示數字
1-sensor 基本架構圖
Light sensor 屬于sensor 其中的一個設備, 因此架構都一樣,light sensor 有I2C 接口,spi 接口,要從硬件上選擇一種就可以, 最好選擇I2C , 進行i2c通信就可以獲取lux 值

Lsensor 數據獲取步驟(獲取lux 可定制開發(fā)app)
Setp0:獲取傳獲取傳感器對象
Setp1:感器管理器對象
Setp2:定義事件監(jiān)聽器-----》下面有給出在原生code 中獲取lux(onSensorChanged)
Setp3:注冊事件監(jiān)聽器
Setp4:卸載事件監(jiān)聽器

2,Lsensor UI 手動設定
在原生android P code 中,亮度的調節(jié)分為三中方式
1) 在設置中手動設定亮度方式
2) 在system UI 中手動設定亮度
3) 在播放視頻時候設定亮度
上面的幾種方式最后調用都到了updatePowerState(), 手動更改亮度,對自動亮度的調整有影響
2.1 System UI , 設置中進行了設定亮度
frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java

最后背光的修改都要走到下面的函數
frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
private void animateScreenBrightness(int target, int rate) {……….}
3,Lsensor 自動算法
基本思路:
Stetp 1:創(chuàng)建三條曲線 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 流程
創(chuàng)建曲線:
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

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

下圖進行了對比,默認曲線有用戶調整后曲線的情況:

問題:什么時候用戶清除配置,reset 動作 (感覺nrea 不需要考慮)
1, 切換用戶
2, BrightnessConfigure 重新配置
3, 屏幕由交互狀態(tài)進入非交互狀態(tài)時,這個是有display 狀態(tài)決定
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 配置:

更新目標背光流程:
animateScreenBrightness-->mScreenBrightnessRampAnimator.animateTo(target, rate)--->postAnimationCallback();--->mAnimationCallback-->mProperty.setValue(mObject, mCurrentValue);--->
最后走到了:DisplayPowerState.java: setValue-->setScreenBrightness

frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java:
