在android 9.0中,相比android 8.1而言,背光部分逻辑有较大的调整,这里就对android P背光机制进行完整的分析。

1.手动调节亮度

1.1.在SystemUI、Settings中手动调节

在界面(SystemUI)和Settings中拖动进度条调节亮度时,调节入口在BrightnessController中:

@Override
public void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic,int value, boolean stopTracking) {final String setting;if (mIsVrModeEnabled) {setting = Settings.System.SCREEN_BRIGHTNESS_FOR_VR;} else {setting = Settings.System.SCREEN_BRIGHTNESS;}//获取亮度值final int val = convertGammaToLinear(value, min, max);//设置亮度值setBrightness(val);if (!tracking) {//在异步任务中将新的亮度值保存在SettingsProvider中AsyncTask.execute(new Runnable() {public void run() {Settings.System.putIntForUser(mContext.getContentResolver(),setting, val, UserHandle.USER_CURRENT);}});}
}

在BrightnessController中,首先根据亮度条的拖动,计算出新的亮度值,然后将调用本类中的setBrightneess()设置亮度,设置完成后,通过异步任务将新的亮度值保存在SettingsProvider中,我们看下一个方法:

private void setBrightness(int brightness) {mDisplayManager.setTemporaryBrightness(brightness);
}

在以上方法中,调用了DisplayManager对象的方法开始设置亮度,这和android8.1的一个不同点,在android 8.1中,设置亮度是由PMS开始,而在9.0中,直接从DisplayManagerService开始了。
当调用mDisplayManager的setTemporaryBrightness()后,经过一系列调用,最终进入了DisplayPowerController·中,这些调用过程代码如下:

//frameworks/base/core/java/android/hardware/display/DisplayManager.java
public void setTemporaryBrightness(int brightness) {mGlobal.setTemporaryBrightness(brightness);
}
//frameworks/base/core/java/android/hardware/display/DisplayManagerGlobal.java
public void setTemporaryBrightness(int brightness) {try {mDm.setTemporaryBrightness(brightness);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}
}//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
@Override // Binder call
public void setTemporaryBrightness(int brightness) {mContext.enforceCallingOrSelfPermission(Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,"Permission required to set the display's brightness");final long token = Binder.clearCallingIdentity();try {synchronized (mSyncRoot) {mDisplayPowerController.setTemporaryBrightness(brightness);}} finally {Binder.restoreCallingIdentity(token);}
}

我们直接进入DisplayPowerController中的setTemporaryBrightness()方法:

public void setTemporaryBrightness(int brightness) {Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,brightness, 0 /*unused*/);msg.sendToTarget();
}

在这个方法中,通过Handler发送一个消息进行处理,这样做的目的是,将最终的亮度调节放在PowerManagerService线程中进行,因为这个Handler对象正是来自于PMS中。
继续下一步流程,来看看Handler中如何处理:

@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_SET_TEMPORARY_BRIGHTNESS:// TODO: Should we have a a timeout for the temporary brightness?//将brightness赋值给了mTemporaryScreenBrightness mTemporaryScreenBrightness = msg.arg1;updatePowerState();break;}}
}

在handleMessage()中,将亮度值赋给了全局变量mTemporaryScreenBrightness ,然后开始调用updatePowerState()方法。
关于updatePowerState()方法,不做全部分析,这里只看亮度调节相关逻辑:

private void updatePowerState() {
// ......//手动设置亮度是否改变final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();if (userSetBrightnessChanged) {mTemporaryScreenBrightness = -1;}// Use the temporary screen brightness if there isn't an override, either from// WindowManager or based on the display state.if (mTemporaryScreenBrightness > 0) {//使用手动设置的亮度brightness = mTemporaryScreenBrightness;mAppliedTemporaryBrightness = true;} else {mAppliedTemporaryBrightness = false;}//........if (!mPendingScreenOff) {final boolean isDisplayContentVisible = mColorFadeEnabled ?(mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f) :(state == Display.STATE_ON && mSkipRampState == RAMP_STATE_SKIP_NONE);if (initialRampSkip || hasBrightnessBuckets|| wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {animateScreenBrightness(brightness, 0);} else {animateScreenBrightness(brightness,slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);}//......
}

updatePowerState()方法中,如果此时mTemporaryScreenBrightness大于0,则设备将使用它作为最终的亮度,而它大于0取决与updateUserSetScreenBrightness()方法的返回值,该方法如下:

private boolean updateUserSetScreenBrightness() {if (mPendingScreenBrightnessSetting < 0) {return false;}//add for bug BEGif (mPendingScreenBrightnessSetting > 0 && (mCurrentScreenBrightnessSetting == mTemporaryScreenBrightness)){return true;}//add for bug ENDif (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) {mPendingScreenBrightnessSetting = -1;return false;}mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting;mPendingScreenBrightnessSetting = -1;return true;
}

这个方法中,实际是根据mPendingScreenBrightnessSetting的值做不同的处理。总结来说,如果mPendingScreenBrightnessSetting大于0,则返回true,并将当前亮度设置为它的值,否则返回false,再进一步概括,就是如果mPendingScreenBrightnessSettingmTemporaryScreenBrightness的值都大于0,那么系统将使用mTemporaryScreenBrightness的值作为亮度值。

mPendingScreenBrightnessSetting则是通过SettingsObserver监测Settings数据库中的值,它获取如下:

private void handleSettingsChange(boolean userSwitch) {mPendingScreenBrightnessSetting = getScreenBrightnessSetting();sendUpdatePowerState();
}private int getScreenBrightnessSetting() {final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessDefault,UserHandle.USER_CURRENT);return clampAbsoluteBrightness(brightness);
}

而对SettingsProvider中的亮度值的保存正是在BrightnessController中setBrightness()之后。

因此,对于手动背光调节,首先调用setBrightnessVal()进入DPC后,将调节亮度设置给全局变量mTemporaryScreenBrightness,然后等待SettingsProvider中保存的亮度值发生改变,当改变完成后,mPendingScreenBrightnessSetting将从SettingsProvider中读取到新的值,然后将使用mTemporaryScreenBrightness作为系统亮度值,并将mTemporaryScreenBrightness重置为-1.

之后的流程和8.1相比差别不大,最终会调用animateScreenBrightness()方法去设置亮度。
通过以上的分析可以发现,将用户调节亮度值表示为"Temporary"也是有原因的,因为在设置完成后,他将又变为-1。

手动调节亮度的时序图如下图所示:

1.2.在视频播放界面手动调节

这块流程还是保留在PMS中,和android 8.1保持一致,因此就不再进行分析。

2.自适应背光调节

android P背光设置流程中最大的差异,是自动背光调节流程。在Google IO上提出,Android P的新特性之一就是自适应背光。Google和DeepMind合作,利用机器学习,创建了自适应背光,通过了解用户在环境中设定亮度滑块的方式,学习你的习惯,从而自动完成亮度调节。下面我们就来看看,androidP中新的自适应背光。
首先我们看自适应背光的架构,了解一些类的功能后,再分析其流程。

2.1.类架构

自动背光相关类结构如下:

其中AutomaticBrightnessController中的功能进一步紧收,只进行环境光强的监听后的一些处理,将背光曲线的创建等工作,交给了BrightnessMappingStrategy,它将负责曲线的创建,自动背光值的计算等,当获取自动背光值时,AutomaticBrightnessController将调用BrightnessMappingStrategy的接口获取。

BrightnessMappingStrategy在创建曲线时,则需要从BrightnessConfigure类中读取两个数组源:config_autoBrightnessLevelsconfig_autoBrightnessDisplayValuesNits

现在我们进入流程的分析。

2.2.创建背光样条曲线

在9.0中,自动背光曲线的创建放在了BrightnessMappingStrategy中,当系统启动后,进入DisplayPowerController构造方法后,就会开始创建背光曲线。

public DisplayPowerController(Context context,DisplayPowerCallbacks callbacks, Handler handler,SensorManager sensorManager, DisplayBlanker blanker) {//获取映射Lux-Nits-Backlight值的对象mBrightnessMapper = BrightnessMappingStrategy.create(resources);
}

我们从BrightnessMappingStrategy.create(resources)进入,来查看曲线的绘制,create()方法如下,相关代码已进行注释:

@Nullable
public static BrightnessMappingStrategy create(Resources resources) {//Lux值的数组,getLuxLevels()中会将Lux[0] = 0.float[] luxLevels = getLuxLevels(resources.getIntArray(com.android.internal.R.array.config_autoBrightnessLevels));//Lux值对应的背光值,9.0中将不会使用他int[] brightnessLevelsBacklight = resources.getIntArray(com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);//描述和Lux值对应的屏幕亮度的Nits值数组,长度比Lux值数组大1。如果配置了该值,则:// ---config_screenBrightnessNits必须配置// ---config_screenBrightnessBacklight必须配置float[] brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));//用户可调整的最大Gama值float autoBrightnessAdjustmentMaxGamma = resources.getFraction(com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,1, 1);//描述屏幕亮度的nits值数组float[] nitsRange = getFloatArray(resources.obtainTypedArray(com.android.internal.R.array.config_screenBrightnessNits));//描述与nitsRange 数组中的亮度值(单位为Nits)相对应的屏幕背光值int[] backlightRange = resources.getIntArray(com.android.internal.R.array.config_screenBrightnessBacklight);//判断是否是有效映射:1.非空;2.长度相同;3.元素>=0;4.nitsRange/luxLevels必须递增,backlightRange/brightnessLevelsNits必须非递减if (isValidMapping(nitsRange, backlightRange)&& isValidMapping(luxLevels, brightnessLevelsNits)) {//最小背光值6int minimumBacklight = resources.getInteger(com.android.internal.R.integer.config_screenBrightnessSettingMinimum);//最大背光值255int maximumBacklight = resources.getInteger(com.android.internal.R.integer.config_screenBrightnessSettingMaximum);//获取BrightnessConfiguration.Builder实例BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();//将读取的Lux值和nits值保存在builder对象中builder.setCurve(luxLevels, brightnessLevelsNits);//映射Lux值和Nits值,而非Lux值和直接显示的背光值,物理映射return new PhysicalMappingStrategy(builder.build(), nitsRange, backlightRange,autoBrightnessAdjustmentMaxGamma);} else if (isValidMapping(luxLevels, brightnessLevelsBacklight)) {//直接映射Lux值和背光值,简单映射return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight,autoBrightnessAdjustmentMaxGamma);} else {return null;}
}

create()方法中,首先读取config.xml文件中的配置值,然后根据这个配置值决定映射方式。
在9.0之前,自动背光只需配置Lux值和对应的Backlight值来创建简单的映射,在9.0中,摒弃了这种方式,额外增加了三个配置值,并根据这些配置值决定是使用物理映射还是简单映射,涉及到的配置值如下:

<!-- Lux值数组-->
<integer-array name="config_autoBrightnessLevels">
</integer-array>
<!-- Lux值对应的背光值数组 -->
<integer-array name="config_autoBrightnessLevels">
</integer-array>
<!-- Lux值对应的Nits值数组 -->
<array name="config_autoBrightnessDisplayValuesNits">
</array>
<!-- 描述屏幕发光强度的Nits值数组 -->
<array name="config_screenBrightnessNits">
</array>
<!-- 和发光强度Nits值对应的背光值数组 -->
<integer-array name="config_screenBrightnessBacklight">
</integer-array>

在以上四个配置值中,后3组是9.0新添加,如果没有配置这三组,则系统将使用前两组配置值创建简单映射关系。因此,9.0中必须配置后三个值,以使用物理映射关系,当配置这些值后,config_autoBrightnessLevels将不再使用。

读取完配置值后,将Lux值数组和Lux值对应的Nits值数组通过setCurve()方法赋值给了builder对象,最终会作为BrightnessConfiguration对象的全局变量。
BrightnessConfiguration表示亮度的配置类,其中保存了Lux值数组和Lux值对应的Nits值数组:

private BrightnessConfiguration(float[] lux, float[] nits, String description) {mLux = lux;mNits = nits;mDescription = description;
}

同时,提供了一个getCurve()接口,用于提供它的mLux和mNits。

接下来进入到物理映射关系对象PhysicalMappingStrategy的创建,看其构造方法:

/*** @param config BrightnessConfiguration对象,携带有用于创建曲线的Lux数组和对应的Nits数组* @param nits 描述屏幕发光强度的nits值数组* @param backlight 描述与nits值数组对应的背光值* @param maxGamma 用户可调整最大Gama值*/
public PhysicalMappingStrategy(BrightnessConfiguration config, float[] nits,int[] backlight, float maxGamma) {mMaxGamma = maxGamma;//自动亮度调节值mAutoBrightnessAdjustment = 0; //在自动背光开启的情况下,用户手动调节亮度时的当前Lux值mUserLux = -1;//在自动背光开启的情况下,用户手动调节设置的亮度mUserBrightness = -1;// Setup the backlight splinefinal int N = nits.length;float[] normalizedBacklight = new float[N];//将背光值/255后,存储在normalizedBacklight数组中for (int i = 0; i < N; i++) {normalizedBacklight[i] = normalizeAbsoluteBrightness(backlight[i]);}//创建Nits-Backlight样条曲线mNitsToBacklightSpline = Spline.createSpline(nits, normalizedBacklight);//创建Backlight-Nits样条曲线mBacklightToNitsSpline = Spline.createSpline(normalizedBacklight, nits);mDefaultConfig = config;mConfig = config;//将根据不同的场景,创建Lux-Nits样条曲线computeSpline();
}

PhysicalMappingStrategy的构造方法中,首先根据config_screenBrightnessNits数组和config_screenBrightnessBacklight数组,创建了两条映射曲线,然后调用computeSpline()方法。
computeSpline()是很重要的一个方法,这个方法中除了创建另外一条Lux-Nits曲线外,还会根据用户当前对亮度的调整,插入用户调整后的值,并调整Lux-Nits曲线,该方法如下:

private void computeSpline() {//得到BrightnessConfiguration中的Lux数组和Lux值对应的Nits数组,并放入Pair对象中Pair<float[], float[]> defaultCurve = mConfig.getCurve();//Lux数组float[] defaultLux = defaultCurve.first;//和Lux数组映射的Nits数组float[] defaultNits = defaultCurve.second;//创建一个和defaultNits数组等长的数组,用来存放对应的背光值,从Nits-backlights曲线中获取//根据Lux-Nit值,从NitsToBacklight曲线中获取背光值//即根据config_autoBrightnessDisplayValuesNits值从config_screenBrightnessNits与config_screenBrightnessBacklight的曲线中获取默认的背光值float[] defaultBacklight = new float[defaultNits.length];for (int i = 0; i < defaultBacklight.length; i++) {defaultBacklight[i] = mNitsToBacklightSpline.interpolate(defaultNits[i]);}//对得到的默认背光值进一步加工,如果用户设置过亮度,需要将用户设置的亮度值添加进曲线,得到//调整后的Lux值数组和backlight值数组Pair<float[], float[]> curve = getAdjustedCurve(defaultLux, defaultBacklight, mUserLux,mUserBrightness, mAutoBrightnessAdjustment, mMaxGamma);//最终的Lux值和背光值float[] lux = curve.first;float[] backlight = curve.second;float[] nits = new float[backlight.length];//根据背光值,从config_screenBrightnessNits和onfig_screenBrightnessBacklight构建的mBacklightToNitsSpline曲线中获取Nit值for (int i = 0; i < nits.length; i++) {nits[i] = mBacklightToNitsSpline.interpolate(backlight[i]);}//Lux-Nits曲线,最终的背光值从此曲线+mNitsToBacklightSpline曲线获取mBrightnessSpline = Spline.createSpline(lux, nits);
}

在这个方法中,首先调用mConfig.getCurve()方法,获取了mConfig对象中的mLux和mNit的拷贝,这两个值就是在创建mConfig时传入的config_autoBrightnessLevels数组和config_autoBrightnessDisplayValuesNits数组。
然后利用得到的nits值从曲线mNitsToBacklightSpline中得到背光值数组defaultBacklight;

接下来,调用getAdjustedCurve()方法对defaultBacklight[]做进一步加工,如果在自动背光打开的情况下,用户没有通过亮度条调节背光,则将返回原数据。此处暂且认为没有操作过亮度条,对getAdjustedCurve()先不做分析。

最后,利用defaultBacklight数组从曲线mBacklightToNitsSpline中得到Nits值,然后,创建表示Lux值和对应Nits值的曲线mBrightnessSpline,这也是创建的最后一条全局样条曲线(在某些方法中会创建一些临时曲线)。

到这里为止,对自动背光样条曲线的创建就分析完成了,整体来看,共创建了三条样条曲线,对Lux-Nit-Backlight进行映射。而且和8.1不同的是,并非直接由Lux和Baclight映射,而是将Nit作为Lux和Backlight的中间介质。这样做相比之前版本中,有什么好处呢?

这里简单引用一些国际单位制的定义:

光照度:从光源照射到单位面积上的光通量,以E表示,照度的单位为勒克斯(Lux,简称lx);

光亮度:指一个表面的明亮程度,以L表示,即从一个表面反射出来的光通量.不同物体对光有不同的反射系数或吸收系数.光的强度可用照在平面上的光的总量来度量,这叫入射光(inci-dentlight)或照度(illuminance).若用从平面反射到眼球中的光量来度量光的强度,这种光称为反射光或亮度.例如,一般白纸大约吸收入射光量的20%,反射光量为80%;黑纸只反射入射光量的3%.所以,白纸和黑纸在亮度上差异很大。

光照度和光亮度的关系可以用如下公式表示:
L=R×E,式中L为亮度,R为反射系数,E为照度.

因此,从光学角度而言,我们感知的亮度是指从屏幕反射到眼球中的光的强度,而且这个强度跟光亮度(Nit)有一定关系,光亮度又跟光照度(Lux)有一定关系,因此,如果严格考虑光照度、光亮度、入射光、反射光等调节,相比通过Lux值决定背光值而言,通过Lux值决定Nit值,再由Nit值决定背光值,无疑是最精准的。

下图表示了四个曲线的创建过程:

创建样条曲线的时序图如下:

了解了曲线的创建后,下面我们开始分析自动背光的调节过程。

还是从DisplayPowerController中开始,对光照强度的采集、获取自动背光都在AutomaticBrightnessController中进行,我们从它的创建和配置分别对它进行分析。

2.3.AutomaticBrightnessController的初始化

这里对AutomaticBrightnessController的创建就不进行细致的分析,和8.1相比,多添加了3个成员,其余内容变化不大,请看8.1中的分析。
其中第一个成员是BrightnessMappingStretagy实例,由构造方法传入,用来创建曲线、获取自动背光值:

//DisplayPowerController.updatePowerState()中//获取映射Lux-Nits-Backlight值的对象
mBrightnessMapper = BrightnessMappingStrategy.create(resources);
//初始化AutomaticBrightnessController
if (mBrightnessMapper != null) {//实例化自动背光控制器mAutomaticBrightnessController = new AutomaticBrightnessController(this,handler.getLooper(), sensorManager, mBrightnessMapper,lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels);
} else {mUseSoftwareAutoBrightnessConfig = false;
}

剩余两个成员为mShortTermModelValidmShortTermModelAnchor:

private boolean mShortTermModelValid;
private float mShortTermModelAnchor;

这两个值大概意思是"短期模型是否有效?"什么是短期模型呢?就是用户设置的背光控制点。当短期模型无效后,并不会立即重置数据,而是等待环境光发生较大变化后,会清除用户设置数据,具体内容会在下面分析。

2.4.AutomaticBrightnessController的配置

在DisplayPowerController中,每一次调用updatePowerState()更新状态时,都会对AutomaticBrightnessController进行配置:

boolean hadUserBrightnessPoint = false;
// Configure auto-brightness.
if (mAutomaticBrightnessController != null) {//曲线中是否有用户设置的短期点hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();//配置mAutomaticBrightnessControllermAutomaticBrightnessController.configure(autoBrightnessEnabled,mBrightnessConfiguration,mLastUserSetScreenBrightness / (float) PowerManager.BRIGHTNESS_ON,userSetBrightnessChanged, autoBrightnessAdjustment,autoBrightnessAdjustmentChanged, mPowerRequest.policy);
}

在以上逻辑中,hadUserBrightnessPoint表示是否在自动背光打开的情况下拖动亮度条调节过亮度,判断依据是BrightnessMappingStrategy中的mUserLux成员,它表示用户在开启自动背光后手动设置亮度时的Lux值:

@Override
public boolean hasUserDataPoints() {return mUserLux != -1;
}

然后开始调用configure()方法进行配置,先来看看这些参数:

Configure()方法如下:

  • autoBrightnessEnabled:表示自动背光是否可用,由以下值决定:
  • //打开了自动亮度调节&&(亮屏或Doze)&&局部变量brightness为0&&BrightnessMappingStrategy不为空
    final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)&& brightness < 0&& mAutomaticBrightnessController != null;
  • mBrightnessConfiguration:BrightnessConfiguration对象,携带有用于创建曲线的Lux值数组和对应的Nit值数组,每一个用户可对应一个BrightnessConfiguration,由DisplayManagerService负责设置。
  • brightness:当前亮度值/255的结果,区间为(0,1.0].
  • userChangedBrightness:表示用户是否手动通过拖动亮度条设置过亮度。
  • userChangedAutoBrightnessAdjustment:表示自动背光调整值adjustment是否发生变化。
  • displayPolicy:当前请求的屏幕状态。
    Configure()方法如下:

    /*** @param enable 自动背光功能是否可用* @param configuration BrightnessConfiguration对象* @param brightness 当前背光值/255的形式* @param userChangedBrightness  用户是否改变过背光值* @param adjustment 自动背光调节值* @param userChangedAutoBrightnessAdjustment 用户是否改变过自动背光调节值* @param displayPolicy PMS中要请求的Diplay状态值*/
    public void configure(boolean enable, @Nullable BrightnessConfiguration configuration,float brightness, boolean userChangedBrightness, float adjustment,boolean userChangedAutoBrightnessAdjustment, int displayPolicy) {//是否屏幕要进入Doze状态boolean dozing = (displayPolicy == DisplayPowerRequest.POLICY_DOZE);//设置BrightnessConfigure对象,若BrightnessConfigure发生改变,返回trueboolean changed = setBrightnessConfiguration(configuration);//设置Display状态,若发生改变,返回truechanged |= setDisplayPolicy(displayPolicy);//如果用户改变自动背光调节值,设置自动背光调节值if (userChangedAutoBrightnessAdjustment) {changed |= setAutoBrightnessAdjustment(adjustment);}//如果在自动亮度开启的情况下调节了亮度,需要将当前的Lux值和用户设置的亮度添加到曲线中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);}final boolean userInitiatedChange =userChangedBrightness || userChangedAutoBrightnessAdjustment;if (userInitiatedChange && enable && !dozing) {//做旧值的记录prepareBrightnessAdjustmentSample();}//注册解除注册LSensorchanged |= setLightSensorEnabled(enable && !dozing);//如果changed为true,更新自动背光亮度值,但不会主动调用DPC更新背光if (changed) {updateAutoBrightness(false /*sendUpdate*/);}
    }

Frameworks Brightness相关推荐

  1. I.MX6 Android frameworks services 文件架构

    /******************************************************************************** I.MX6 Android fram ...

  2. ajax frameworks(转贴)

    Thinking in AJAX(三) -- AJAX框架汇总 引 此文原出于AJAX Patterns网站的一篇<Ajax Frameworks>的wiki文章,很早前我就注意到,后来在 ...

  3. TensorFlow Estimators: Managing Simplicity vs. Flexibility in High-Level Machine Learning Frameworks

    TensorFlow Estimators: Managing Simplicity vs. Flexibility in High-Level Machine Learning Frameworks ...

  4. 转载:IDEA出现URI is not registered (Settings | Languages Frameworks | Schemas and DTDs)

    在IDEA的xml资源文件中出现URI is not registered错误 中文意思就是统一资源标识符没有注册,解决方法就是将这个标识符手动添加到IDEA中,首先复制报红色的那串代码(只要红色的部 ...

  5. Making Your Own iPhone Frameworks. In Xcode

    Back in April Oliver wrote an excellent article entitled "Making Your Own iPhone Frameworks&quo ...

  6. .Net Core 中的包、元包与框架(Packages, Metapackages and Frameworks)

    包,元包与框架 本文翻译自 Packages, Metapackages and Frameworks. .Net Core 是一种由 NuGet 包组成的平台.一些产品体验受益于代码包的细粒度定义, ...

  7. Android 11 Frameworks中引用aar包

    MTK vendor(vendor/mediatek/proprietary/frameworks/base/custom)  想在 framework 使用, 在Android.bp mediate ...

  8. OpenCV C++ 04 - Change Brightness

    如果你想提升一幅图像的亮度,可以给每个像素的值都加上一个正的常数 \[ new\_image (i, j) = image(i, j) + c \] 如果你想降低一幅图像的亮度,可以给每个像素的值都减 ...

  9. 从Zygote孵化frameworks进程,分析StartActivity流程中intent传递数据的最大值。

    Pangu-Immortal (Pangu-Immortal) · GitHub 当我们用Intent传输大数据时,有可能会出现错误: val intent = Intent(this@MainAct ...

最新文章

  1. Design Pattern Strategy C
  2. HDU 1853 HDU 3488【有向环最小权值覆盖问题 】带权二分图匹配 KM算法
  3. fileUpload 文件上传
  4. 15.Linux 高性能服务器编程 --- 进程池和线程池
  5. stm32固件库文件
  6. 软件工程和数据库中必考的ER图
  7. 测试显卡矿卡用什么软件,3分钟看懂:AMD二手矿卡简明鉴别、检测教程,从此脱坑不求人...
  8. 24.UART串口通讯框图、波特率计算方法
  9. 信创操作系统--麒麟Kylin桌面操作系统(项目九 实用工具软件:截图、字体、扫描、打印机)
  10. 财务分析就是财务报表分析吗?
  11. MTK平台Camera图片的Exif信息
  12. 用文字总结出计算机组装步骤,项目教学法在《计算机组装与维护》中的运用与反思(杜燕)...
  13. blast java_使用python实现BLAST
  14. 微信小程序 跳转公众号
  15. C语言大学期末考试重点,快点码住,再也不用担心挂科啦
  16. PDF标签文件用哪款条码标签打印软件制作?
  17. 括号匹配算法问题 JS
  18. 【72】编辑距离问题
  19. 用python制作贺卡_使用Python创作自己的圣诞节动图贺卡,制作简单即刻生成
  20. 大学排行榜 : qs全球中国区大学排行榜

热门文章

  1. 行业研究报告-全球与中国电脑机箱风扇市场现状及未来发展趋势
  2. Excel 单元格中插入附件
  3. jq、js 添加/删除class
  4. 编写高质量的代码—从命名入手(命名…
  5. python学习——如何求最大公约数
  6. SMIL 2.0 基础教程
  7. 简单脚本测试--对谈式脚本@read
  8. 卡塔兰数用于求解不同形态的二叉树的数目,题目选自CS61A2021 LAB9 Q3: Number of Trees
  9. 09-word不显示段落标记(去掉回车符号)取消拼写错误
  10. 实践练习2:手动部署 OceanBase 集群