赞
踩
转自吴小龙公众号
下拉状态栏有个亮度的进度条,如果开启了亮度自动调节开关,会随着周围光线变化,这个进度条也会随着变化,接下来就是看看这个功能是如何实现的。
基于 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
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //省略部分代码
- mBrightnessController = new BrightnessController(this, icon, slider);
- }
2、这里进行了 BrightnessController 初始化,来看下:
- public BrightnessController(Context context, ImageView icon, ToggleSlider control) {
- //省略部分代码
- mBrightnessObserver = new BrightnessObserver(mHandler);
- //省略部分代码
- }
又进行了 BrightnessObserver 初始化:
- /** ContentObserver to watch brightness **/
- private class BrightnessObserver extends ContentObserver {
- //省略部分代码
- private final Uri BRIGHTNESS_FOR_VR_URI =
- Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR);
- //Add By WuXiaolong for AutomaticBrightness
- private final Uri BRIGHTNESS_ADJ_URI =
- Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ);
- public BrightnessObserver(Handler handler) {
- super(handler);
- }
- @Override
- public void onChange(boolean selfChange) {
- onChange(selfChange, null);
- }
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (selfChange) return;
- if (BRIGHTNESS_MODE_URI.equals(uri)) {
- mBackgroundHandler.post(mUpdateModeRunnable);
- mBackgroundHandler.post(mUpdateSliderRunnable);
- }
- //省略部分代码
- //Add By WuXiaolong for AutomaticBrightness
- else if (BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) {
- mBackgroundHandler.post(mUpdateSliderRunnable);
- } else {
- mBackgroundHandler.post(mUpdateModeRunnable);
- mBackgroundHandler.post(mUpdateSliderRunnable);
- }
- for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
- cb.onBrightnessLevelChanged();
- }
- }
- public void startObserving() {
- final ContentResolver 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);
- }
- public void stopObserving() {
- final ContentResolver cr = mContext.getContentResolver();
- cr.unregisterContentObserver(this);
- }
- }
其实我目前下载的源码,这块功能是不全的,我已经加上了,哪里进行 BrightnessObserver 的 ContentObserver 注册呢?
3、回到 BrightnessDialog#onStart:
- @Override
- protected void onStart() {
- super.onStart();
- mBrightnessController.registerCallbacks();
- MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);
- }
4、调用mBrightnessController.registerCallbacks();
最终走到 mStartListeningRunnable:
- private final Runnable mStartListeningRunnable = new Runnable() {
- @Override
- public void run() {
- //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,最终走到:
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- mExternalChange = true;
- try {
- switch (msg.what) {
- //省略部分代码
- case MSG_UPDATE_SLIDER:
- updateSlider(msg.arg1, msg.arg2 != 0);
- break;
- //省略部分代码
- default:
- super.handleMessage(msg);
- }
- } finally {
- mExternalChange = false;
- }
- }
- };
走 updateSlider方法,到 :
- private void animateSliderTo(int target) {
- 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
- public void setValue(int value) {
- //这里正是修改进度条
- mSlider.setProgress(value);
- if (mMirror != null) {
- mMirror.setValue(value);
- }
- }
接下来就是看看亮度自动调节主要的两个类 DisplayPowerController 和 AutomaticBrightnessController。DisplayPowerController 属于 Display 模块,其控制设备屏幕亮灭、背光、与Power关系密切,这里主要看下屏幕亮度的控制这方面的逻辑。
6、首先,在 DisplayManagerService 中初始化 DisplayPowerController,如下:
- private final class LocalService extends DisplayManagerInternal {
- @Override
- public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
- SensorManager sensorManager) {
- synchronized (mSyncRoot) {
- //省略部分代码
- mDisplayPowerController = new DisplayPowerController(
- mContext, callbacks, handler, sensorManager, blanker);
- }
- mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
- }
7、接着看下 DisplayPowerController 构造方法,如下:
- public DisplayPowerController(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 = new AutomaticBrightnessController(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():
- private void updatePowerState() {
- // Update the power state request.
- //省略部分代码
-
- final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
- if (autoBrightnessAdjustmentChanged) {
- mTemporaryAutoBrightnessAdjustment = Float.NaN;
- }
- // Use the autobrightness adjustment override if set.
- final float autoBrightnessAdjustment;
- if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
- autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
- mAppliedTemporaryAutoBrightnessAdjustment = true;
- } else {
- autoBrightnessAdjustment = mAutoBrightnessAdjustment;
- mAppliedTemporaryAutoBrightnessAdjustment = false;
- }
-
- boolean hadUserBrightnessPoint = 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.
- boolean slowChange = false;
- if (brightness < 0) {
- float newAutoBrightnessAdjustment = 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():
- private float getAutoBrightnessAdjustmentSetting() {
- final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
- Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
- return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);
- }
继续看下 clampAutoBrightnessAdjustment:
- private static float clampAutoBrightnessAdjustment(float value) {
- return MathUtils.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
- public boolean setAutoBrightnessAdjustment(float adjustment) {
- adjustment = MathUtils.constrain(adjustment, -1, 1);
- if (adjustment == mAutoBrightnessAdjustment) {
- return false;
- }
- if (DEBUG) {
- Slog.d(TAG, "setAutoBrightnessAdjustment: " + mAutoBrightnessAdjustment + " => " +
- adjustment);
- PLOG.start("auto-brightness adjustment");
- }
- mAutoBrightnessAdjustment = adjustment;
- computeSpline();
- return true;
- }
9、BrightnessMapper#setAutoBrightnessAdjustment 这个方法调用又回到了 AutomaticBrightnessController#setAutoBrightnessAdjustment:
- private boolean setAutoBrightnessAdjustment(float adjustment) {
- return mBrightnessMapper.setAutoBrightnessAdjustment(adjustment);
- }
AutomaticBrightnessController#setAutoBrightnessAdjustment
调用是来到AutomaticBrightnessController#configure()
方法:
- public void configure(boolean enable, @Nullable BrightnessConfiguration configuration,
- float brightness, boolean userChangedBrightness, float adjustment,
- boolean userChangedAutoBrightnessAdjustment, int displayPolicy) {
- // 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.
- boolean dozing = (displayPolicy == DisplayPowerRequest.POLICY_DOZE);
- boolean changed = 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);
- }
- final boolean userInitiatedChange =
- userChangedBrightness || userChangedAutoBrightnessAdjustment;
- if (userInitiatedChange && enable && !dozing) {
- prepareBrightnessAdjustmentSample();
- }
- changed |= setLightSensorEnabled(enable && !dozing);
- if (changed) {
- updateAutoBrightness(false /*sendUpdate*/);
- }
- }
AutomaticBrightnessController#configure()
调用来到了 DisplayPowerController #updatePowerState()
。
这样也知道了 newAutoBrightnessAdjustment,继续 putAutoBrightnessAdjustmentSetting:
- private void putAutoBrightnessAdjustmentSetting(float adjustment) {
- mAutoBrightnessAdjustment = adjustment;
- Settings.System.putFloatForUser(mContext.getContentResolver(),
- Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, UserHandle.USER_CURRENT);
- }
就调到第 4 步 BrightnessObserver#onChange,进度条随之变化,Over
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。