赞
踩
1、手动设置背光API
- // 修改当前Activity界面的窗口亮度
- private void setScreenLight(int brightness) {
- WindowManager.LayoutParams lp = getWindow().getAttributes();
- lp.screenBrightness = Float.valueOf(brightness) * (1f / 255f);
- getWindow().setAttributes(lp);
- }
-
- // 修改系统的亮度值
- public void setScreenLight(int brightness) {
- Uri uri = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
- ContentResolver contentResolver = getContentResolver();
- Settings.System.putInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
- contentResolver.notifyChange(uri, null);
- }
2、设置系统背光默认亮度值
- #frameworks/base/core/res/res/values/config.xml
-
- <integer name="config_screenBrightnessSettingMinimum">2</integer>
- <integer name="config_screenBrightnessDim">2</integer>
系统背光节点路径:/sys/class/leds/lcd-backlight/brightness
3、自动背光配置设置
自动背光涉及光感值与亮度值对应,需要根据项目进行设置光感和背光值数组,一一对应。
- # frameworks/base/core/res/res/values/config.xml
-
- <integer-array name="config_autoBrightnessLevels">
- ... 填写亮度值数组 ...
- </integer-array>
-
- <integer-array name="config_autoBrightnessLcdBacklightValues">
- ... 填写光感值数组 ...
- </integer-array>
系统手动设置,待机休眠等都是通过 PowerManagerService.java 统一管理,自动背光则是由 AutomaticBrightnessController.java 管理。最后统一调用 DisplayPowerController.java 进行处理。
1、frameworks/base/services/core/java/com/android/server/display/AutomaticBrightnessController.java 主要相关操作:
通过监听L-sersor 值变化发送 handleLightSensorEvent 走到 updateAutoBrightness 函数,最终调用到 DisplayPowerController.java updateBrightness函数。
- // 内部创建一个光感监听
- private final SensorEventListener mLightSensorListener = new SensorEventListener() {
- @Override
- public void onSensorChanged(SensorEvent event) {
- if (mLightSensorEnabled) {
- final long time = SystemClock.uptimeMillis();
- final float lux = event.values[0];
- handleLightSensorEvent(time, lux);
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- // Not used.
- }
- };
-
- // 通知update背光
- private void updateAutoBrightness(boolean sendUpdate) {
- if (!mAmbientLuxValid) {
- return;
- }
-
- // 根据光感值计算对应背光值
- float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
- float gamma = 1.0f;
-
- if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
- && mScreenAutoBrightnessAdjustment != 0.0f) {
- final float adjGamma = MathUtils.pow(mScreenAutoBrightnessAdjustmentMaxGamma,
- Math.min(1.0f, Math.max(-1.0f, -mScreenAutoBrightnessAdjustment)));
- gamma *= adjGamma;
- if (DEBUG) {
- Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
- }
- }
-
- if (gamma != 1.0f) {
- final float in = value;
- value = MathUtils.pow(value, gamma);
- if (DEBUG) {
- Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
- + ", in=" + in + ", out=" + value);
- }
- }
-
- int newScreenAutoBrightness =
- clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
- if (mScreenAutoBrightness != newScreenAutoBrightness) {
- if (DEBUG) {
- Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
- + mScreenAutoBrightness + ", newScreenAutoBrightness="
- + newScreenAutoBrightness);
- }
-
- mScreenAutoBrightness = newScreenAutoBrightness;
- mLastScreenAutoBrightnessGamma = gamma;
- if (sendUpdate) {
- // 通知mCallbacks背光改变,mCallbacks 即是 DisplayPowerController 类对象
- mCallbacks.updateBrightness();
- }
- }
- }
-
- // mCallbacks中调用获取当前的自动背光值,后续进行设置
- public int getAutomaticScreenBrightness() {
- if (!mAmbientLuxValid) {
- return -1;
- }
- if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) {
- return (int) (mScreenAutoBrightness * mDozeScaleFactor);
- }
- return mScreenAutoBrightness;
- }
-
-
-
2、frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java 主要操作:
上层背光相关操作最终都是走到 PowerManagerService ,统一处理,这里只看设置 SCREEN_BRIGHTNESS 值的流程。通过 SettingsObserver 监听值变化,最终调用到 DisplayPowerController.java requestPowerState 函数。
- // 系统启动时进行初始化操作
- public void systemReady(IAppOpsService appOps) {
- ... ...
-
- // 绑定监听
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.SCREEN_BRIGHTNESS),
- false, mSettingsObserver, UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.SCREEN_BRIGHTNESS_MODE),
- false, mSettingsObserver, UserHandle.USER_ALL);
- ... ...
- }
-
- // 监听变化发送 handleSettingsChangedLocked
- private final class SettingsObserver extends ContentObserver {
- public SettingsObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- synchronized (mLock) {
- handleSettingsChangedLocked();
- }
- }
- }
-
- //handleSettingsChangedLocked -> updatePowerStateLocked -> updateDisplayPowerStateLocked
- /**
- *异步更新显示电源状态。 更新完成后,mDisplayReady将设置为true。 显示控制器会发布一条消息,告诉
- *我们实际的显示电源状态何时已更新,因此我们回到这里进行仔细检查并完成。
- *每次该功能都会重新计算显示功率状态。
- *@return如果显示准备就绪,则为True。
- */
- private boolean updateDisplayPowerStateLocked(int dirty) {
- final boolean oldDisplayReady = mDisplayReady;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
- | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |
- DIRTY_QUIESCENT)) != 0) {
- mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
- ... ...
-
- // 修改更新 mDisplayPowerRequest 亮度值等属性
- mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
- mDisplayPowerRequest.useAutoBrightness = autoBrightness;
- mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
- mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
-
- updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
- ... ...
- // 最终调用 DisplayPowerController 处理
- mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,mRequestWaitForNegativeProximity);
- ... ...
- }
- return mDisplayReady && !oldDisplayReady;
- }
-
3、frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java 主要相关方法分析
通过 Settings.System.SCREEN_BRIGHTNESS 手动设置值,是从调用 requestPowerState 开始,最终调用 sendUpdatePowerStateLocked,如下
- // 通过设置settings值手动更新亮度调用
- public boolean requestPowerState(DisplayPowerRequest request,
- boolean waitForNegativeProximity) {
- if (DEBUG) {
- Slog.d(TAG, "requestPowerState: "
- + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
- }
-
- synchronized (mLock) {
- boolean changed = false;
-
- mRequestPowerStateChangedByUser = false;
-
- if (waitForNegativeProximity
- && !mPendingWaitForNegativeProximityLocked) {
- mPendingWaitForNegativeProximityLocked = true;
- changed = true;
- }
-
- if (mPendingRequestLocked == null) {
- mPendingRequestLocked = new DisplayPowerRequest(request);
- changed = true;
- } else if (!mPendingRequestLocked.equals(request)) {
- // 这里不同是手动设置的调用
- mPendingRequestLocked.copyFrom(request);
- changed = true;
- mRequestPowerStateChangedByUser = true;
- }
-
- if (changed) {
- mDisplayReadyLocked = false;
- }
-
- if (changed && !mPendingRequestChangedLocked) {
- mPendingRequestChangedLocked = true;
- // 通知更新亮度
- sendUpdatePowerStateLocked();
- }
-
- return mDisplayReadyLocked;
- }
- }
自动背光调节的流程调用是从 updateBrightness() 开始,最终也是调用 sendUpdatePowerStateLocked,如下
- @Override
- public void updateBrightness() {
- sendUpdatePowerState();
- }
-
- private void sendUpdatePowerState() {
- synchronized (mLock) {
- sendUpdatePowerStateLocked();
- }
- }
sendUpdatePowerStateLocked 这个函数就是手动、自动亮度调节最终统一的地方。它里面只是简单的通过handler 发送调用 updatePowerState();updatePowerState() 里面才是真正进行操作的地方。
- private void updatePowerState() {
- // Update the power state request.
- ... ...
-
- // P-Sensor的靠近操作
- if (mProximitySensor != null) {
- ... ...
- } else {
- mWaitingForNegativeProximity = false;
- }
- if (mScreenOffBecauseOfProximity) {
- state = Display.STATE_OFF;
- }
-
- // 配置自动亮度值
- boolean slowChange = false;
- if (brightness < 0) {
- if (autoBrightnessEnabled) {
- // 这里就是获取 AutomaticBrightnessController 保存的自动亮度值
- brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
- }
- if (brightness >= 0) {
- // 这里就是保证 brightness 在系统最小最大设置值 10 ~ 255 之间
- // 具体看 frameworks/base/core/res/res/values/config.xml 中 config_screenBrightnessSettingMinimum config_screenBrightnessSettingMaximum 值
- brightness = clampScreenBrightness(brightness);
- if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
- slowChange = true; // slowly adapt to auto-brightness
- }
- mAppliedAutoBrightness = true;
- } else {
- mAppliedAutoBrightness = false;
- }
- } else {
- mAppliedAutoBrightness = false;
- }
-
- // Use default brightness when dozing unless overridden.
- if (brightness < 0 && (state == Display.STATE_DOZE
- || state == Display.STATE_DOZE_SUSPEND)) {
- brightness = mScreenBrightnessDozeConfig;
- }
-
- // 这里是我自己添加判断,过滤重复设置亮度
- // 保存自动亮度值 mRequestPowerStateAutoBrightness。
- // 如果 mRequestPowerStateChangedByUser 手动操作为false,且mRequestPowerStateAutoBrightness也没有变化,就直接return
- if (mRequestPowerStateAutoBrightness != brightness) {
- mRequestPowerStateAutoBrightness = brightness;
- } else if (!mRequestPowerStateChangedByUser) {
- Slog.d(TAG, "Brightness no changed");
- return;
- }
-
- // 这里使用手动亮度值
- Slog.d(TAG, "Apply manual brightness " + brightness + " " + mRequestPowerStateAutoBrightness);
- if (brightness < 0 || mRequestPowerStateChangedByUser) {
- int clampBrightness = clampScreenBrightness(mPowerRequest.screenBrightness);
- if (brightness == clampBrightness) {
- Slog.d(TAG, "RequestPowerStateChangedByUser Brightness no changed");
- return;
- }
- brightness = clampBrightness;
- }
-
- // 这里就是系统自动休眠前,先变暗一会
- if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
- if (brightness > mScreenBrightnessRangeMinimum) {
- brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
- mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
- }
- if (!mAppliedDimming) {
- slowChange = false;
- }
- mAppliedDimming = true;
- } else if (mAppliedDimming) {
- slowChange = false;
- mAppliedDimming = false;
- }
- ... ...
-
- // 判断屏幕是否是off
- if (!mPendingScreenOff) {
- ... ...
-
- // 通过判断确定背光响应变化速度
- // mBrightnessRampRateSlow 原生是60,是1s调整60亮度
- // mBrightnessRampRateFast 原生是180,是1s调整180亮度
- boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
- if (!mRequestPowerStateChangedByUser && (state == Display.STATE_ON
- && mSkipRampState == RAMP_STATE_SKIP_NONE
- || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
- && !wasOrWillBeInVr) {
- // 一般自动亮度变化是会渐变调整的
- animateScreenBrightness(brightness,
- slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
- } else {
- // 手动一般是立即变化的,无需动画渐变调整的
- animateScreenBrightness(brightness, 0);
- }
- Slog.d(TAG, "putInt brightness " + brightness);
- }
- ... ...
-
- }
animateScreenBrightness 内部逻辑是在 frameworks/base/services/core/java/com/android/server/display/RampAnimator.java 中 animateTo 处理。
animateTo 中调用 postAnimationCallback ,在 mAnimationCallback 中一直设置值渐变。
- private void postAnimationCallback() {
- mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);
- }
-
- private void cancelAnimationCallback() {
- mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);
- }
-
- private final Runnable mAnimationCallback = new Runnable() {
- @Override // Choreographer callback
- public void run() {
- final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
- final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)
- * 0.000000001f;
- mLastFrameTimeNanos = frameTimeNanos;
-
- // Advance the animated value towards the target at the specified rate
- // and clamp to the target. This gives us the new current value but
- // we keep the animated value around to allow for fractional increments
- // towards the target.
- final float scale = ValueAnimator.getDurationScale();
- if (scale == 0) {
- // Animation off.
- mAnimatedValue = mTargetValue;
- } else {
- final float amount = timeDelta * mRate / scale;
- if (mTargetValue > mCurrentValue) {
- mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue);
- } else {
- mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue);
- }
- }
- final int oldCurrentValue = mCurrentValue;
- mCurrentValue = Math.round(mAnimatedValue);
-
- if (oldCurrentValue != mCurrentValue) {
- mProperty.setValue(mObject, mCurrentValue);
- }
-
- // mCurrentValue 当前值
- // mTargetValue 目标值
- if (mTargetValue != mCurrentValue) {
- postAnimationCallback();
- } else {
- mAnimating = false;
- if (mListener != null) {
- // 通知变化完成
- mListener.onAnimationEnd();
- }
- }
- }
- };
mProperty.setValue(mObject, mCurrentValue);
这个方法就是实际操作写入背光值的地方,往下就是通过 native 调用处理。到这里背光设置就完成了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。