当前位置: 首页 > news >正文

万网虚拟主机两个网站权重域名做网站有用么

万网虚拟主机两个网站,权重域名做网站有用么,重庆市建设工程造价信息官网,linux搭建wordpress在android 9.0中#xff0c;相比android 8.1而言#xff0c;背光部分逻辑有较大的调整#xff0c;这里就对android P背光机制进行完整的分析。 1.手动调节亮度 1.1.在SystemUI、Settings中手动调节 在界面(SystemUI)和Settings中拖动进度条调节亮度时#xff0c;调节入口…在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 displays 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 isnt 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再进一步概括就是如果 mPendingScreenBrightnessSetting 和mTemporaryScreenBrightness 的值都大于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_autoBrightnessLevels 和 config_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 nameconfig_autoBrightnessLevels /integer-array !-- Lux值对应的背光值数组 -- integer-array nameconfig_autoBrightnessLevels /integer-array !-- Lux值对应的Nits值数组 -- array nameconfig_autoBrightnessDisplayValuesNits /array !-- 描述屏幕发光强度的Nits值数组 -- array nameconfig_screenBrightnessNits /array !-- 和发光强度Nits值对应的背光值数组 -- integer-array nameconfig_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对象中Pairfloat[], 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值数组Pairfloat[], 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%.所以,白纸和黑纸在亮度上差异很大。 光照度和光亮度的关系可以用如下公式表示LR×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; }剩余两个成员为mShortTermModelValid和mShortTermModelAnchor: 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()方法进行配置先来看看这些参数 autoBrightnessEnabled:表示自动背光是否可用由以下值决定 //打开了自动亮度调节(亮屏或Doze)局部变量brightness为0BrightnessMappingStrategy不为空 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. Its 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*/);} }在这个方法中囊括了所有的配置我们对这些配置进行拆分一个一个地分析它们。 回到configure()方法中首先看第一个配置: 1.setBrightnessConfiguration(): 这个方法负责配置当前自动背光的BrighnessConfiguration对象在前面也说了这个对象中带有Lux值和Nits值用来创建曲线和获取背光值。该方法如下 public boolean setBrightnessConfiguration(BrightnessConfiguration configuration) {if (mBrightnessMapper.setBrightnessConfiguration(configuration)) {//如果config对象发生改变重置用户设置的曲线点resetShortTermModel();return true;}return false; }这个方法中又调用进入了 mBrightnessMapper 中继续看看 Override public boolean setBrightnessConfiguration(Nullable BrightnessConfiguration config) {if (config null) {config mDefaultConfig;}if (config.equals(mConfig)) {return false;}if (DEBUG) {PLOG.start(brightness configuration);}//如果config对象发生改变则替换后调用computeSpline重新创建Lux-Nits曲线mConfig config;computeSpline();return true; }从以上方法中得知如果BrightnessConfiguration对象发生改变则会根据BrightnessConfiguration 中携带的Lux和Nit值数组重新创建曲线并清除之前用户的设置。 那么 BrightnessConfiguration 何时会改变呢答案是切换一个新用户后。 在android9.0中针对每个用户都会有一个 BrightnessConfiguration 和它映射所以当切换用户后设备的背光将可能发生改变。 当BrightnessConfiguration 发生改变且在 BrighnessMappingStragety 中设置完成后将会通过resetShortTermModel()清除原有用户的配置: public void resetShortTermModel() { //清除用户添加的曲线点mBrightnessMapper.clearUserDataPoints(); //表示短期模型仍旧有效mShortTermModelValid true;mShortTermModelAnchor -1; }clearUserDataPoint()方法如下 Override public void clearUserDataPoints() {if (mUserLux ! -1) {//回复自动背光调节值为0mAutoBrightnessAdjustment 0;mUserLux -1;//用户设置亮度时Lux值mUserBrightness -1;//用户设置亮度computeSpline();//重新创建曲线} }在这个方法中将全局自动背光调节值、用户设置亮度值和设置亮度时Lux值进行重置然后重新创建曲线。 2.setDisplayPolicy() 这个方法主要根据屏幕状态来设置 mShortTermModelValid 的值该方法如下 private boolean setDisplayPolicy(int policy) {if (mDisplayPolicy policy) {return false;}final int oldPolicy mDisplayPolicy;mDisplayPolicy policy;//如果Display状态值由交互变为不可交互状态if (!isInteractivePolicy(policy) isInteractivePolicy(oldPolicy)) {//发送一个30s的延迟消息30s后将mShortTermModelValid置为falsemHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_SHORT_TERM_MODEL,SHORT_TERM_MODEL_TIMEOUT_MILLIS);//如果Display状态值由不可交互变为交互状态移除延时消息的发送} else if (isInteractivePolicy(policy) !isInteractivePolicy(oldPolicy)) {mHandler.removeMessages(MSG_INVALIDATE_SHORT_TERM_MODEL);}return true; }从这个方法中可以看出当屏幕状态进入Doze或者Asleep后会发送一个定义Handler并在到达时间后将 mShortTermModelValid 值置为false该值的用处在下文说明。 3.setAutoBrightnessAdjustment() 这个方法用来设置自动背光调整值前提是自动背光调整值已经发生变化调用此方法后将调用到 BrightnessMappingStragety 中的同名方法中如下 Override public boolean setAutoBrightnessAdjustment(float adjustment) {//对adjust进行限制取值范围为[-1,1]adjustment MathUtils.constrain(adjustment, -1, 1);if (adjustment mAutoBrightnessAdjustment) {return false;}mAutoBrightnessAdjustment adjustment;//重新创建曲线computeSpline();return true; }在这个方法中如果mAutoBrightnessAdjustment发生变化也会重新创建曲线这里也可以看得出来曲线的创建和自动背光调整值有着莫大的关系在默认情况下这个值为0.那么何时这个值将发生变化以及如何变化呢答案留在下文。 4.setScreenBrightnessByUser() 这个方法用于将用户拖动亮度条设置的亮度和当时的Lux值添加到用于创建曲线的数组中并重新创建曲线 //添加用户设置亮度 private boolean setScreenBrightnessByUser(float brightness) {if (!mAmbientLuxValid) {// If we dont have a valid ambient lux then we dont have a valid brightness anyways,// and we cant use this data to add a new control point to the short-term model.return false;}//将当前的Lux值和用户设置的背光值添加到曲线中mBrightnessMapper.addUserDataPoint(mAmbientLux, brightness);//设置mShortTermModelAnchor为当前Lux值 mShortTermModelValid true;mShortTermModelAnchor mAmbientLux;return true; }关于addUserDataPoint()方法会在下文中进行分析。 5.prepareBrightnessAdjustmentSample() 这个方法主要是当配置元素发生改变后对旧值做一个记录并打印一些Log这里就不再分析直接略过。 6.setLightSensorEnabled() 这个方法负责LightSensor的注册和解除注册当设备处于亮屏状态且打开自动背光功能时将注册一个LightSensor以监听环境光的强度变化该方法如下 private boolean setLightSensorEnabled(boolean enable) {if (enable) {if (!mLightSensorEnabled) {//表示LSensor启用mLightSensorEnabled true;//LSensor开启的时间mLightSensorEnableTime SystemClock.uptimeMillis();//当前LSensor的事件速率mCurrentLightSensorRate mInitialLightSensorRate;//注册LSensormSensorManager.registerListener(mLightSensorListener, mLightSensor,mCurrentLightSensorRate * 1000, mHandler);return true;}} else if (mLightSensorEnabled) {mLightSensorEnabled false;mAmbientLuxValid !mResetAmbientLuxAfterWarmUpConfig;mRecentLightSamples 0;mAmbientLightRingBuffer.clear();mCurrentLightSensorRate -1;mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);mSensorManager.unregisterListener(mLightSensorListener);}return false; }这个方法比较简单当环境光强度发生变化后将回调mLightSensorListener接口的方法来更新 private final SensorEventListener mLightSensorListener new SensorEventListener() {Overridepublic void onSensorChanged(SensorEvent event) {if (mLightSensorEnabled) {final long time SystemClock.uptimeMillis();final float lux event.values[0]; //处理LSensor上报事件handleLightSensorEvent(time, lux);}}Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {// Not used.} };LSensor事件的处理先不分析来看下一个configure()中调用的方法. 7.updateAutoBrightness() 这个方法用来更新最终计算的自动亮度 private void updateAutoBrightness(boolean sendUpdate) {if (!mAmbientLuxValid) {return;}//根据Lux值从样条曲线中获取对应的背光值,区间为(0,1.0]的浮点数float value mBrightnessMapper.getBrightness(mAmbientLux);//得到最终的自动背光值int newScreenAutoBrightness clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));if (mScreenAutoBrightness ! newScreenAutoBrightness) {mScreenAutoBrightness newScreenAutoBrightness;//是否主动调用DPC中进行背光的更新if (sendUpdate) {mCallbacks.updateBrightness();}} }在这个方法中通过当前的Lux值从mBrightnessMapper中获取到了最终的背光值我们来看看是如何获取得到背光值的 Override public float getBrightness(float lux) { //先根据Lux值从mBrightnessSpline曲线中寻找对应的Nit值float nits mBrightnessSpline.interpolate(lux); //再根据Nit值从mNitsToBacklightSpline曲线中寻找读应的背光值float backlight mNitsToBacklightSpline.interpolate(nits);return backlight; }从这个方法可以得知读取自动背光值的原理:首先会根据当前的Lux值从mBrightnessSpline曲线中寻找对应的Nit值然后根据Nit值从曲线mNitsToBacklightSpline中获取到最终的背光值。在分析样条曲线的创建时已知道mBrightnessSpline曲线是由Lux值数组和它对应的Nit值数组创建mNitsToBacklightSpline是由配置文件中的config_screenBrightnessNits和config_screenBrightnessBacklight创建。具体的创建在computeSline()方法中。 经过以上的分析自动背光的获取及和配置数组值的关系可以用下图来表示 2.5.adjustment值的计算 在android 8.1中当用户在开启自动背光的场景下手动拖动亮度条调节时实际上是调用setScreenAutoBrightnessAdjustment()方法调整了自动背光调整值然后通过自动背光调整值计算得出新的自动背光值。 在9.0中则完全不同它会直接设置用户选择的亮度值作为设备新的背光值还会将此时的环境光强Lux值和设置的亮度值作为创建样条曲线的控制点添加到创建样条曲线的数组中并重新创建样条曲线我们可以通过Log来简单的查看在用户未设置亮度前系统根据配置值创建的曲线控制点如下(格式为(Luxbacklight)): BrightnessMappingStrategy: [PLOG 1544753613130] curve: unadjusted curve: [(0.0,0.11764706), (16.0,0.1579153), (32.0,0.19611156), (50.0,0.23574594), (100.0,0.27560648), (140.0,0.3135872), (180.0,0.39658308), (240.0,0.39658308), (300.0,0.39658308), (600.0,0.39658308), (800.0,0.39658308), (1000.0,0.7058824), (2000.0,0.783783), (3000.0,0.8235294), (4000.0,0.84214103), (5000.0,0.8603607), (6000.0,0.90202725), (8000.0,1.0), (10000.0,1.0),] 当用户将亮度设置为最大后将变成 BrightnessMappingStrategy: [PLOG 1544753876189] curve: smoothed curve: [(0.0,0.4899973), (16.0,0.54051536), (32.0,0.58098876), (50.0,0.6177528), (100.0,0.6507734), (140.0,0.67939043), (180.0,0.7347023), (240.0,0.7347023), (300.0,0.7347023), (600.0,0.7347023), (800.0,0.7347023), (1000.0,0.8903842), (1505.0,1.0), (2000.0,1.0), (3000.0,1.0), (4000.0,1.0), (5000.0,1.0), (6000.0,1.0), (8000.0,1.0), (10000.0,1.0),]其中(1505.0,1.0)这组值正是用户设置亮度时的Lux值和设置的背光值,其余的点也进行了对应的调整。 除此之外在android 9.0中自动背光的调整值将不再由用户主动设置(虽然在DMS中保留了setTemporaryAutoBrightnessAdjustment()用于调整adjustment值)而是根据用户的调整自动进行推断得出。下面就从代码中开始分析这些新机制的实现。 当通过亮度条调节亮度时将调用进入DisplayPowerController(以下简称DPC)的setTemporaryAutoBrightnessAdjustment()方法并执行手动亮度调节流程然后执行自动背光控制器的配置流程.由于用户对亮度的手动设置因此将有: mLastUserSetScreenBrightness发生改变由默认0变为用户设置的亮度值;userSetBrightnessChanged由false变为true。 此时这两个值已经发生改变但其他值还未发生变化。 那么结合AutomaticBrightnessController(以下简称ABC)的配置在调用configure()方法时将调用setScreenBrightnessByUser()方法这个方法在2.4中说过了用于将用户拖动亮度条设置的亮度和当时的Lux值添加到用于创建曲线的数组中具体是调用BrigtnessMappingStrategy对象的addUserDataPoint()方法实现而这个方法中将会通过计算得出新的adjustment值来该方法如下 addUserDataPoint() Override public void addUserDataPoint(float lux, float brightness) {//获取默认配置值创建的曲线中Lux值对应的背光值float unadjustedBrightness getUnadjustedBrightness(lux);//通过传入的三个值推段自动背光调整值float adjustment inferAutoBrightnessAdjustment(mMaxGamma,brightness /* desiredBrightness */,unadjustedBrightness /* currentBrightness */);//更新自动背光调整值mAutoBrightnessAdjustment adjustment;//表示用户在开启自动背光情况下拖动亮度条调节亮度时的当时Lux值mUserLux lux;//表示用户在开启自动背光情况下拖动亮度条调节亮度值mUserBrightness brightness;//重新创建曲线computeSpline(); }在这个方法中首先将从配置文件中的数组值创建的原始样条曲线中获取当前Lux的值使用getUnadjustedBrightness()方法 private float getUnadjustedBrightness(float lux) {//得到BrightnessConfiguration中的Lux-Nit映射Pairfloat[], float[] curve mConfig.getCurve();//创建一个Lux-Nit样条曲线Spline spline Spline.createSpline(curve.first, curve.second);//根据Lux值得到Nit值再根据Nit值从mNitsToBacklightSpline得到相对应的背光值return mNitsToBacklightSpline.interpolate(spline.interpolate(lux)); }然后将开始计算自动背光调整值调用inferAutoBrightnessAdjustment()方法并且将根据配置文件中的MaxGamma值、从原始样条曲线中获取的此Lux对应的背光值以及用户所希望要设置的背光值计算出adjustment inferAutoBrightnessAdjustment() //推断adjustment值private static float inferAutoBrightnessAdjustment(float maxGamma,float desiredBrightness, float currentBrightness) {float adjustment 0;float gamma Float.NaN;// 当前Lux值对应的默认配置亮度值 25.5 || 229.5if (currentBrightness 0.1f || currentBrightness 0.9f) {adjustment (desiredBrightness - currentBrightness);//亮度为0,最低只能是6貌似不可能} else if (desiredBrightness 0) {adjustment -1;//最大亮度255} else if (desiredBrightness 1) {adjustment 1;} else {// current^gamma desired gamma log[current](desired)//根据换底公式得到currentBrightness为底desiredBrightness的对数gamma MathUtils.log(desiredBrightness) / MathUtils.log(currentBrightness);// max^-adjustment gamma adjustment -log[max](gamma)//maxGamma为底gamma的对数adjustment -MathUtils.log(gamma) / MathUtils.log(maxGamma);}adjustment MathUtils.constrain(adjustment, -1, 1);return adjustment;}在这个方法中可以看出adjustment的计算由两个计算步骤得到大概解释一下就是current的gamma次方等于desired从而得出gamma而gamma又等于maxGamma的-adjustment次方从而得出adjustment。 到这里自动背光的调整值adjustment已经计算出了接下来再看看有了adjustment后如何调整背光样条曲线。 回到addUserDataPoint()方法中计算完毕adjustment后会将用户设置的Lux和Brightness分别赋给BrightnessMappingStrategy对象成员mUserLux和mUserBrightness并调用computeSpline()重新创建样条曲线这个方法在2.2中分析了但是对其中调用的getAdjustedCurve()没有分析此处正适合对它做一个了解该方法如下 getAdjustedCurve() /*** 得到调整弧度* param lux Lux值数组* param brightness 根据Lux值-Lux值对应的Nits值-Nits-Backlight曲线得到的最终背光值数组* param userLux 当前Lux值* param userBrightness 当前用户设置亮度值* param adjustment 自动背光调整值* param maxGamma 最大Gama值* return*/private static Pairfloat[], float[] getAdjustedCurve(float[] lux, float[] brightness,float userLux, float userBrightness, float adjustment, float maxGamma) {//初始化两个新数组分别存储Lux值和背光值float[] newLux lux;float[] newBrightness Arrays.copyOf(brightness, brightness.length);//限定adjustment为[-1,1]adjustment MathUtils.constrain(adjustment, -1, 1);//maxGamma 的 -adjustment次方得到gamma值float gamma MathUtils.pow(maxGamma, -adjustment);//gamma ! 1说明adjustment不为0if (gamma ! 1) {//重新设置亮度值新的亮度值为就亮度值的gamma次方for (int i 0; i newBrightness.length; i) {newBrightness[i] MathUtils.pow(newBrightness[i], gamma);}}//用户在BrightnessController拖动条上手动调节了亮度if (userLux ! -1) {//插入一对新的Lux和对应背光值Pairfloat[], float[] curve insertControlPoint(newLux, newBrightness, userLux,userBrightness);newLux curve.first;newBrightness curve.second;}return Pair.create(newLux, newBrightness);}在以上方法中通过adustment值获取gamma值再通过gamma值调整整个背光数组元素仔细一看其实在这里计算新的亮度值的算法就是inferAutoBrightnessAdjustment()中的反操作这里是通过adjustment得到gamma再由gamma得到新的背光值数组。 计算出新的背光值后调用insertControlPoint()将用户设置的点作为曲线控制点插入相关数组中 private static Pairfloat[], float[] insertControlPoint(float[] luxLevels, float[] brightnessLevels, float lux, float brightness) {//找到插入点索引以保持值的递增final int idx findInsertionPoint(luxLevels, lux);final float[] newLuxLevels;final float[] newBrightnessLevels;//如果插入索引等于数组长度则if (idx luxLevels.length) {//需要插入到末尾位置且新Lux数组长度比原来大1newLuxLevels Arrays.copyOf(luxLevels, luxLevels.length 1);newBrightnessLevels Arrays.copyOf(brightnessLevels, brightnessLevels.length 1);newLuxLevels[idx] lux;newBrightnessLevels[idx] brightness;//如果用户lux值已处于Lux值数组中则} else if (luxLevels[idx] lux) {//copy原数组即可newLuxLevels Arrays.copyOf(luxLevels, luxLevels.length);newBrightnessLevels Arrays.copyOf(brightnessLevels, brightnessLevels.length);newBrightnessLevels[idx] brightness;//否则} else {//初始化新Lux数组长度比原数组大1newLuxLevels Arrays.copyOf(luxLevels, luxLevels.length 1);//将原数组从idx位置起的元素向后移动1位将新的Lux值插入到idx位置System.arraycopy(newLuxLevels, idx, newLuxLevels, idx1, luxLevels.length - idx);newLuxLevels[idx] lux;//初始化新亮度值数组长度比原数组大1newBrightnessLevels Arrays.copyOf(brightnessLevels, brightnessLevels.length 1);//将原数组从idx位置起的元素向后移动1位将新的亮度值值插入到idx位置System.arraycopy(newBrightnessLevels, idx, newBrightnessLevels, idx1,brightnessLevels.length - idx);newBrightnessLevels[idx] brightness;}//平滑曲线newLuxLevels之后的Lux对应的亮度值将全部为newBrightnessLevelssmoothCurve(newLuxLevels, newBrightnessLevels, idx);return Pair.create(newLuxLevels, newBrightnessLevels);}该方法调用完毕后返回一个携带有Lux和背光值的Pair对象给getAdjustedCurve(),在getAdjustedCurve()中将返回该Pair对象给到computeSpline()中在computeSpline()将从返回的Pair对像中取出Lux数组值和背光数组值完成曲线的创建。 根据上面的分析可以发现getAdjustedCurve()中的局部变量和maxGamma、adjustment值有如下关系: 这些逻辑执行完毕后回到configure()方法接下来将由LSensor检测环境光强、调节亮度…这些流程就不再说明。 我们再回到DisplayPowerController中updatePowerState()中当configure()执行完毕后DPC中将拿到调整后的adjustment值并完成保存这部分代码如下 private void updatePowerState() {//......if (brightness 0) {float newAutoBrightnessAdjustment autoBrightnessAdjustment;if (autoBrightnessEnabled) {//获取自动背光亮度值brightness mAutomaticBrightnessController.getAutomaticScreenBrightness();//获取新的adjustment值newAutoBrightnessAdjustment mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();}if (brightness 0) {brightness clampScreenBrightness(brightness);if (mAppliedAutoBrightness !autoBrightnessAdjustmentChanged) {slowChange true; // slowly adapt to auto-brightness}putScreenBrightnessSetting(brightness);mAppliedAutoBrightness true;} else {mAppliedAutoBrightness false;}if (autoBrightnessAdjustment ! newAutoBrightnessAdjustment) {//将adjustment值保存到SettingsProvider中putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);}} else {mAppliedAutoBrightness false;}//......}在此处会将ABC中计算得出的adjustment保存在SettingsProvider中以确保Settings等其他进程对它的使用: private void putAutoBrightnessAdjustmentSetting(float adjustment) {mAutoBrightnessAdjustment adjustment;Settings.System.putFloatForUser(mContext.getContentResolver(),Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, UserHandle.USER_CURRENT);}从用户拖动亮度条调节自动背光开始到adjustment值计算完成并最终在SettingsProvider中完成保存整个过程时序图如下: 2.6.清除用户设置数据 使用ABC的resetShortTermModel()可以清除用户设置的亮度和对应Lux时,那么何时清除用户设置的背光值和对应Lux值呢有以下三种情况: 1.切换用户 相关代码如下 private void handleSettingsChange(boolean userSwitch) {if (userSwitch) {if (mAutomaticBrightnessController ! null) {mAutomaticBrightnessController.resetShortTermModel();}}}2.BrightnessConfigure对象发生变化 这种情况在2.4中了解 setBrightnessConfiguration() 时已分析过。 3.屏幕进入不可交互状态超过30s且再次进入交互状态后环境光强有一定范围变化 在分析setDisplayPolicy()时说到若屏幕由交互状态进入非交互状态时将会发送一个延时Handler消息并在到达时间后将mShortTermModelValid值设置为false那么如果当屏幕状态再进入交互状态时肯定会有设置Lux值的流程,而就在这个流程中mShortTermModelValid的含义将彰显出来 private void setAmbientLux(float lux) {mAmbientLux lux;mBrighteningLuxThreshold mHysteresisLevels.getBrighteningThreshold(lux);mDarkeningLuxThreshold mHysteresisLevels.getDarkeningThreshold(lux);// If the short term model was invalidated and the change is drastic enough, reset it.if (!mShortTermModelValid mShortTermModelAnchor ! -1) {//SHORT_TERM_MODEL_THRESHOLD_RATIO 0.6final float minAmbientLux mShortTermModelAnchor - mShortTermModelAnchor * SHORT_TERM_MODEL_THRESHOLD_RATIO;final float maxAmbientLux mShortTermModelAnchor mShortTermModelAnchor * SHORT_TERM_MODEL_THRESHOLD_RATIO;//如果环境光强介于这个值之间则不会reset否则resetif (minAmbientLux mAmbientLux mAmbientLux maxAmbientLux) {mShortTermModelValid true;} else {resetShortTermModel();}}}在这个方法中只有进入非交互状态时mShortTermModelValid才会为false表示将用户设置置为无效状态但不会立即置为无效状态只有环境光强发生较大变化时才会重置用户设置这个较大变化即是大于当前光强的0.6倍或者小于当前光强的0.6倍时。 关于android 9.0自动背光就先了解这么多。此外从代码结构来看还增加了BrightnessTracker等类这个类会对用户自动背光亮度进行一些记录就暂时不进行分析了。
http://www.zqtcl.cn/news/644658/

相关文章:

  • 做电商网站用什么软件企业网站建设方案范本
  • o2o商城网站搭建潍坊定制网站搭建
  • 网站建设费用说明青岛网站建设方案公司
  • 佛山市建设企业网站服务机构优化seo是什么
  • 仿70网站分类目录源码市场营销策划ppt免费模板
  • 广东圆心科技网站开发网站模板设计网页程序代码
  • 网站平台定制开发一级a做爰网站下载
  • 网站如何做流媒体wordpress导出软件
  • 电商网站流程图esp8266做网站
  • 细胞医疗 网站模版免费网址软件
  • app地推网企业seo解决方案
  • php网站转移网吧手机网站模版
  • 北京建设教育网站今天的国内新闻
  • 江苏省建设银行网站天心区网站建设公司
  • 网站分享设计网站备案收费么
  • 手机网站专题关于asp sql网站开发的书籍
  • 网站建设属于什么领域小米发布会在哪里看
  • 免费空间访客领取网站提高网站互动性
  • 湖北省市政工程建设网站汉中网站建设电话
  • 宁波大型网站推广服务丁香花在线电影小说观看
  • 合肥的网站建设公司哪家好百度旗下产品
  • 墨星写作网站阿里云购买网站登录
  • 做微网站公司知名网站设计
  • 宁波中科网站建设有限公司天津市建设 银行网站
  • 长沙建个网站一般需要多少钱化妆品网站建设方案项目书
  • 宁波外贸网站推广做网站如何选域名
  • 如何在百度上搜索到自己的网站提升关键词
  • asp net做网站建设英文网站的公司
  • 旅游英文网站 建设需求WordPress首页id
  • 南宁网站如何制作网站seo查询站长之家