失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > android自动亮度流程 Android 亮度自动调节是如何实现的?

android自动亮度流程 Android 亮度自动调节是如何实现的?

时间:2019-03-14 09:13:27

相关推荐

android自动亮度流程 Android 亮度自动调节是如何实现的?

下拉状态栏有个亮度的进度条,如果开启了亮度自动调节开关,会随着周围光线变化,这个进度条也会随着变化,接下来就是看看这个功能是如何实现的。

源码版本

基于 Android 9.0 分析。

BrightnessDialog,位于:frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java

ToggleSliderView,位于:frameworks/base/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java

DisplayPowerController,位于:frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java

AutomaticBrightnessController,位于:frameworks/base/services/core/java/com/android/server/display/AutomaticBrightnessController.java

BrightnessMappingStrategy,

概述

状态栏里亮度页面是 BrightnessDialog,其中进度条设置是 ToggleSliderView,亮度自动调节主要是 DisplayPowerController 和 AutomaticBrightnessController 两个类,当亮度发生变化时,如果关联到 ToggleSliderView,用的是 ContentObserver,Uri 为 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ。

源码梳理

1、BrightnessDialog#onCreate:

@Override

protectedvoidonCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

//省略部分代码

mBrightnessController = newBrightnessController( this, icon, slider);

}

2、这里进行了 BrightnessController 初始化,来看下:

publicBrightnessController(Context context, ImageView icon, ToggleSlider control){

//省略部分代码

mBrightnessObserver = newBrightnessObserver(mHandler);

//省略部分代码

}

又进行了 BrightnessObserver 初始化:

/** ContentObserver to watch brightness **/

privateclassBrightnessObserverextendsContentObserver{

//省略部分代码

privatefinalUri BRIGHTNESS_FOR_VR_URI =

Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR);

//Add By WuXiaolong for AutomaticBrightness

privatefinalUri BRIGHTNESS_ADJ_URI =

Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ);

publicBrightnessObserver(Handler handler){

super(handler);

}

@Override

publicvoidonChange(booleanselfChange){

onChange(selfChange, null);

}

@Override

publicvoidonChange(booleanselfChange, Uri uri){

if(selfChange) return;

if(BRIGHTNESS_MODE_URI.equals(uri)) {

mBackgroundHandler.post(mUpdateModeRunnable);

mBackgroundHandler.post(mUpdateSliderRunnable);

}

//省略部分代码

//Add By WuXiaolong for AutomaticBrightness

elseif(BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) {

mBackgroundHandler.post(mUpdateSliderRunnable);

} else{

mBackgroundHandler.post(mUpdateModeRunnable);

mBackgroundHandler.post(mUpdateSliderRunnable);

}

for(BrightnessStateChangeCallback cb : mChangeCallbacks) {

cb.onBrightnessLevelChanged();

}

}

publicvoidstartObserving(){

finalContentResolver cr = mContext.getContentResolver();

cr.unregisterContentObserver( this);

//省略部分代码

cr.registerContentObserver(

BRIGHTNESS_FOR_VR_URI,

false, this, UserHandle.USER_ALL);

//Add By WuXiaolong for AutomaticBrightness

cr.registerContentObserver(

BRIGHTNESS_ADJ_URI,

false, this, UserHandle.USER_ALL);

}

publicvoidstopObserving(){

finalContentResolver cr = mContext.getContentResolver();

cr.unregisterContentObserver( this);

}

}

其实我目前下载的源码,这块功能是不全的,我已经加上了,哪里进行 BrightnessObserver 的 ContentObserver 注册呢?

3、回到 BrightnessDialog#onStart:

@Override

protectedvoidonStart(){

super.onStart();

mBrightnessController.registerCallbacks();

MetricsLogger.visible( this, MetricsEvent.BRIGHTNESS_DIALOG);

}

4、调用mBrightnessController.registerCallbacks();最终走到 mStartListeningRunnable:

privatefinalRunnable mStartListeningRunnable = newRunnable() {

@Override

publicvoidrun(){

//BrightnessObserver 注册

mBrightnessObserver.startObserving();

mUserTracker.startTracking();

// Update the slider and mode before attaching the listener so we don't

// receive the onChanged notifications for the initial values.

mUpdateModeRunnable.run();

mUpdateSliderRunnable.run();

mHandler.sendEmptyMessage(MSG_ATTACH_LISTENER);

}

};

当亮度有变化时,会走 BrightnessObserver#onChange,最终走到:

privatefinalHandler mHandler = newHandler() {

@Override

publicvoidhandleMessage(Message msg){

mExternalChange = true;

try{

switch(msg.what) {

//省略部分代码

caseMSG_UPDATE_SLIDER:

updateSlider(msg.arg1, msg.arg2 != 0);

break;

//省略部分代码

default:

super.handleMessage(msg);

}

} finally{

mExternalChange = false;

}

}

};

走 updateSlider方法,到 :

privatevoidanimateSliderTo(inttarget){

if(!mControlValueInitialized) {

// Don't animate the first value since it's default state isn't mea

mControl.setValue(target);

mControlValueInitialized = true;

}

//省略部分代码

}

5、跳到 ToggleSliderView#setValue:

@Override

publicvoidsetValue(intvalue){

//这里正是修改进度条

mSlider.setProgress(value);

if(mMirror != null) {

mMirror.setValue(value);

}

}

接下来就是看看亮度自动调节主要的两个类 DisplayPowerController 和 AutomaticBrightnessController。DisplayPowerController 属于 Display 模块,其控制设备屏幕亮灭、背光、与Power关系密切,这里主要看下屏幕亮度的控制这方面的逻辑。

6、首先,在 DisplayManagerService 中初始化 DisplayPowerController,如下:

privatefinalclassLocalServiceextendsDisplayManagerInternal{

@Override

publicvoidinitPowerManagement(finalDisplayPowerCallbacks callbacks, Handler handler,

SensorManager sensorManager){

synchronized(mSyncRoot) {

//省略部分代码

mDisplayPowerController = newDisplayPowerController(

mContext, callbacks, handler, sensorManager, blanker);

}

mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);

}

7、接着看下 DisplayPowerController 构造方法,如下:

publicDisplayPowerController(Context context,

DisplayPowerCallbacks callbacks, Handler handler,

SensorManager sensorManager, DisplayBlanker blanker){

//省略部分代码

mUseSoftwareAutoBrightnessConfig = resources.getBoolean(

com.android.internal.R.bool.config_automatic_brightness_available);

//省略部分代码

if(mUseSoftwareAutoBrightnessConfig) {

//省略部分代码

mBrightnessMapper = BrightnessMappingStrategy.create(resources);

if(mBrightnessMapper != null) {

mAutomaticBrightnessController = newAutomaticBrightnessController( this,

handler.getLooper(), sensorManager, mBrightnessMapper,

lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,

mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,

initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,

autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels);

} else{

mUseSoftwareAutoBrightnessConfig = false;

}

}

//省略部分代码

mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();

mTemporaryAutoBrightnessAdjustment = Float.NaN;

//省略部分代码

}

由于亮屏之后屏幕自动亮度才会生效,所以在亮屏的时候,流程会走到 DisplayPowerController 中的核心函数 updatePowerState():

privatevoidupdatePowerState(){

// Update the power state request.

//省略部分代码

finalbooleanautoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();

if(autoBrightnessAdjustmentChanged) {

mTemporaryAutoBrightnessAdjustment = Float.NaN;

}

// Use the autobrightness adjustment override if set.

finalfloatautoBrightnessAdjustment;

if(!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {

autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;

mAppliedTemporaryAutoBrightnessAdjustment = true;

} else{

autoBrightnessAdjustment = mAutoBrightnessAdjustment;

mAppliedTemporaryAutoBrightnessAdjustment = false;

}

booleanhadUserBrightnessPoint = false;

// Configure auto-brightness.

if(mAutomaticBrightnessController != null) {

hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();

mAutomaticBrightnessController.configure(autoBrightnessEnabled,

mBrightnessConfiguration,

mLastUserSetScreenBrightness / ( float) PowerManager.BRIGHTNESS_ON,

userSetBrightnessChanged, autoBrightnessAdjustment,

autoBrightnessAdjustmentChanged, mPowerRequest.policy);

}

// Apply auto-brightness.

booleanslowChange = false;

if(brightness < 0) {

floatnewAutoBrightnessAdjustment = autoBrightnessAdjustment;

if(autoBrightnessEnabled) {

brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();

newAutoBrightnessAdjustment =

mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();

}

if(brightness >= 0) {

// Use current auto-brightness value and slowly adjust to changes.

brightness = clampScreenBrightness(brightness);

if(mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {

slowChange = true; // slowly adapt to auto-brightness

}

// Tell the rest of the system about the new brightness. Note that we do this

// before applying the low power or dim transformations so that the slider

// accurately represents the full possible range, even if they range changes what

// it means in absolute terms.

putScreenBrightnessSetting(brightness);

mAppliedAutoBrightness = true;

} else{

mAppliedAutoBrightness = false;

}

if(autoBrightnessAdjustment != newAutoBrightnessAdjustment) {

// If the autobrightness controller has decided to change the adjustment value

// used, make sure that's reflected in settings.

putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);

}

} else{

mAppliedAutoBrightness = false;

}

//省略部分代码

}

接下来分别看看 autoBrightnessAdjustment 和 newAutoBrightnessAdjustment 怎么来的?

autoBrightnessAdjustment 是来自 mTemporaryAutoBrightnessAdjustment 或 mAutoBrightnessAdjustment 赋值,mAutoBrightnessAdjustment 在第 7 步mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();有初始化,看下 getAutoBrightnessAdjustmentSetting():

privatefloatgetAutoBrightnessAdjustmentSetting(){

finalfloatadj = Settings.System.getFloatForUser(mContext.getContentResolver(),

Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);

returnFloat.isNaN(adj) ? 0.0f: clampAutoBrightnessAdjustment(adj);

}

继续看下 clampAutoBrightnessAdjustment:

privatestaticfloatclampAutoBrightnessAdjustment(floatvalue){

returnMathUtils.constrain( value, -1.0f, 1.0f);

}

这里注意下 MathUtils.constrain() 表示百分比缩放函数,比如 MathUtils.constrain(0.5, 0, 255) 表示 (255-0)*0.5。

这样了解了 autoBrightnessAdjustment,接下来看 newAutoBrightnessAdjustment。

8、回到 DisplayPowerController#updatePowerState(),看到 newAutoBrightnessAdjustment 调用了 AutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(),最终是到了 BrightnessMapper#getAutoBrightnessAdjustment() 其中 mAutoBrightnessAdjustment 变量,赋值是在 BrightnessMapper#setAutoBrightnessAdjustment:

@Override

publicbooleansetAutoBrightnessAdjustment(floatadjustment){

adjustment = MathUtils.constrain(adjustment, - 1, 1);

if(adjustment == mAutoBrightnessAdjustment) {

returnfalse;

}

if(DEBUG) {

Slog.d(TAG, "setAutoBrightnessAdjustment: "+ mAutoBrightnessAdjustment + " => "+

adjustment);

PLOG.start( "auto-brightness adjustment");

}

mAutoBrightnessAdjustment = adjustment;

computeSpline();

returntrue;

}

9、BrightnessMapper#setAutoBrightnessAdjustment 这个方法调用又回到了 AutomaticBrightnessController#setAutoBrightnessAdjustment:

privatebooleansetAutoBrightnessAdjustment(floatadjustment){

returnmBrightnessMapper.setAutoBrightnessAdjustment(adjustment);

}

AutomaticBrightnessController#setAutoBrightnessAdjustment调用是来到 AutomaticBrightnessController#configure()方法:

publicvoidconfigure(booleanenable, @Nullable BrightnessConfiguration configuration,

floatbrightness, booleanuserChangedBrightness, floatadjustment,

booleanuserChangedAutoBrightnessAdjustment, intdisplayPolicy){

// 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

// and hold onto the last computed screen auto brightness. We save the dozing flag for

// debugging purposes.

booleandozing = (displayPolicy == DisplayPowerRequest.POLICY_DOZE);

booleanchanged = setBrightnessConfiguration(configuration);

changed |= setDisplayPolicy(displayPolicy);

if(userChangedAutoBrightnessAdjustment) {

changed |= setAutoBrightnessAdjustment(adjustment);

}

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.

changed |= setScreenBrightnessByUser(brightness);

}

finalbooleanuserInitiatedChange =

userChangedBrightness || userChangedAutoBrightnessAdjustment;

if(userInitiatedChange && enable && !dozing) {

prepareBrightnessAdjustmentSample();

}

changed |= setLightSensorEnabled(enable && !dozing);

if(changed) {

updateAutoBrightness( false/*sendUpdate*/);

}

}

AutomaticBrightnessController#configure()调用来到了 DisplayPowerController #updatePowerState()。

这样也知道了 newAutoBrightnessAdjustment,继续 putAutoBrightnessAdjustmentSetting:

privatevoidputAutoBrightnessAdjustmentSetting(floatadjustment){

mAutoBrightnessAdjustment = adjustment;

Settings.System.putFloatForUser(mContext.getContentResolver(),

Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, UserHandle.USER_CURRENT);

}

就调到第 4 步 BrightnessObserver#onChange,进度条随之变化,Over!

如果觉得《android自动亮度流程 Android 亮度自动调节是如何实现的?》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。