Android6.0 亮屏灭屏流程(DisplayPowerControler、WMS)(二)亮度设置
更新时间:2023-12-03 04:24:01 阅读量: 教育文库 文档下载
Android6.0 亮屏灭屏流程(DisplayPowerControler、WMS)(二)
亮度设置
在setScreenState中先是调用了DisplayPowerState的setScreenState函数。上篇博客我们没有分析,主要分析下亮度的设置流程。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 public void setScreenState(int state) { if (mScreenState != state) { if (DEBUG) {
Slog.d(TAG, \ }
mScreenState = state; mScreenReady = false; scheduleScreenUpdate(); } }
scheduleScreenUpdate主要通过消息方式,最后调用到下面函数。当我们屏幕刚要点亮,这个时候mScreenBrightness为0,所以这个时候调用mPhotonicModulator.setState设置state是点亮,但是brightness是0的。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private final Runnable mScreenUpdateRunnable = new Runnable() { @Override
public void run() {
mScreenUpdatePending = false;
int brightness = mScreenState != Display.STATE_OFF
&& mColorFadeLevel > 0f ? mScreenBrightness : 0; if (mPhotonicModulator.setState(mScreenState, brightness)) { if (DEBUG) {
Slog.d(TAG, \ }
mScreenReady = true;
invokeCleanListenerIfNeeded(); } else {
if (DEBUG) {
Slog.d(TAG, \ } } }
};
DisplayPowerState的设置亮度状态逻辑分析
mPhotonicModulator.setState应该要PhotonicModulator的run函数结合一起看。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 public boolean setState(int state, int backlight) { synchronized (mLock) {
boolean stateChanged = state != mPendingState;
boolean backlightChanged = backlight != mPendingBacklight; if (stateChanged || backlightChanged) { if (DEBUG) {
Slog.d(TAG, \
+ Display.stateToString(state) + \ }
mPendingState = state;
mPendingBacklight = backlight;
boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
mStateChangeInProgress = stateChanged;
mBacklightChangeInProgress = backlightChanged;
if (!changeInProgress) {
Slog.d(TAG,\ mLock.notifyAll(); } }
return !mStateChangeInProgress; } }
两者结合看先setState设置了状态,只有状态改变时,我们才能重新设置状态(设置到mpendingState和mPendingBacklight)。而在run函数中,当设置的状态mPendingState、mPendingBacklight和mActualState、mActualBacklight(真正设置到背光的状态、亮度)不一样时,才会调用mBlanker.requestDisplayState设置亮度。否则状态没有改变,就会把mStateChangeInProgress 和mBacklightChangeInProgress 设置为false,然后线程就wait住。 而此时setState重新设置下来的话,这个时候把亮度和状态设置到mPendingState 和mPendingBacklight 。然后这时mStateChangeInProgress 和 mBacklightChangeInProgress都是false。这样就可以调用mLock的notifyAll函数重新唤醒线程,这样就把把前面setState设置下来的mPendingState和mPendingBacklight再通过mBlanker.requestDisplayState设置到背光设备中去。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 @Override
public void run() {
for (;;) {
// Get pending change. final int state;
final boolean stateChanged; final int backlight;
final boolean backlightChanged; synchronized (mLock) { state = mPendingState;
stateChanged = (state != mActualState); backlight = mPendingBacklight;
backlightChanged = (backlight != mActualBacklight); if (!stateChanged) {
// State changed applied, notify outer class. postScreenUpdateThreadSafe(); mStateChangeInProgress = false; }
if (!backlightChanged) {
mBacklightChangeInProgress = false; }
if (!stateChanged && !backlightChanged) { try {
mLock.wait();
} catch (InterruptedException ex) { } continue; }
mActualState = state;
mActualBacklight = backlight; }
// Apply pending change. if (true) {
Slog.d(TAG, \
+ Display.stateToString(state) + \ }
mBlanker.requestDisplayState(state, backlight);
Slog.d(TAG, \ } }
设置亮度、状态到背光设备
DisplayBlanker的requestDisplayState如下,主要调用requestGlobalDisplayStateInternal函数。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 DisplayBlanker blanker = new DisplayBlanker() { @Override
public void requestDisplayState(int state, int brightness) { // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness); }
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness); } } };
requestGlobalDisplayStateInternal函数先是对state和brightness的处理,然后把这个两个变量放在mGlobalDisplayState 和mGlobalDisplayBrightness成员变量中。紧接着调用applyGlobalDisplayStateLocked函数mTempDisplayStateWorkQueue作为参数。最后再调用mTempDisplayStateWorkQueue各个成员的run函数(这里返回的是Runnable接口,这里就会设置状态和亮度到设备中去)。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
private void requestGlobalDisplayStateInternal(int state, int brightness) { if (state == Display.STATE_UNKNOWN) { state = Display.STATE_ON; }
if (state == Display.STATE_OFF) {
brightness = PowerManager.BRIGHTNESS_OFF; } else if (brightness < 0) {
brightness = PowerManager.BRIGHTNESS_DEFAULT; } else if (brightness > PowerManager.BRIGHTNESS_ON) { brightness = PowerManager.BRIGHTNESS_ON; }
synchronized (mTempDisplayStateWorkQueue) { try {
synchronized (mSyncRoot) {
if (mGlobalDisplayState == state
&& mGlobalDisplayBrightness == brightness) { return; // no change }
mGlobalDisplayState = state;
mGlobalDisplayBrightness = brightness;
applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); }
// Setting the display power state can take hundreds of milliseconds // to complete so we defer the most expensive part of the work until // after we have exited the critical section to avoid blocking other // threads for a long time.
for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
mTempDisplayStateWorkQueue.get(i).run();//设置亮度、状态到设备 } } finally {
mTempDisplayStateWorkQueue.clear(); } } }
applyGlobalDisplayStateLocked函数会遍历各个显示设备(多显示),然后调用updateDisplayStateLocked函数返回一个Runnable,最后把这个Runnable放入之前传入的mTempDisplayStateWorkQueue队列中。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
private void applyGlobalDisplayStateLocked(List
DisplayDevice device = mDisplayDevices.get(i);
Runnable runnable = updateDisplayStateLocked(device); if (runnable != null) {
workQueue.add(runnable); } } }
那下面我们看下updateDisplayStateLocked函数,主要是调用了DisplayDevice的requestDisplayStateLocked函数,当然mGlobalDisplayState和mGlobalDisplayBrightness作为参数。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private Runnable updateDisplayStateLocked(DisplayDevice device) {
// Blank or unblank the display immediately to match the state requested // by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); }
return null; }
这里的DisplayDevice的requestDisplayStateLocked函数,是在LocalDisplayAdapter中实现的,这里吧state和brightness保存在mState和mBrightness中,然后返回Runnable接口,最后在Runnable接口中设置亮度和状态。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
public Runnable requestDisplayStateLocked(final int state, final int brightness) { // Assume that the brightness is off if the display is being turned off.
assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;
final boolean stateChanged = (mState != state);
final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null; if (stateChanged || brightnessChanged) { final int displayId = mBuiltInDisplayId;
final IBinder token = getDisplayTokenLocked(); final int oldState = mState;
if (stateChanged) {
mState = state;//保存state updateDeviceInfoLocked(); }
if (brightnessChanged) {
mBrightness = brightness;//保存brightness }
// Defer actually setting the display state until after we have exited // the critical section since it can take hundreds of milliseconds // to complete.
return new Runnable() {//返回Runnable @Override
public void run() {
// Exit a suspended state before making any changes. int currentState = oldState;
if (Display.isSuspendedState(oldState)
|| oldState == Display.STATE_UNKNOWN) { if (!Display.isSuspendedState(state)) { setDisplayState(state); currentState = state;
} else if (state == Display.STATE_DOZE_SUSPEND
|| oldState == Display.STATE_DOZE_SUSPEND) { setDisplayState(Display.STATE_DOZE); currentState = Display.STATE_DOZE; } else {
return; // old state and new state is off } }
// Apply brightness changes given that we are in a non-suspended state. if (brightnessChanged) {
Slog.d(TAG, \setDisplayBrightnessbrightness1=\+ brightness);
setDisplayBrightness(brightness); Slog.d(TAG, \setDisplayBrightnessbrightness2=\+ brightness);
}
// Enter the final desired state, possibly suspended. if (state != currentState) { setDisplayState(state); } }
private void setDisplayState(int state) { if (DEBUG) {
Slog.d(TAG, \ + \
+ \ } try {
final int mode = getPowerModeForState(state);
SurfaceControl.setDisplayPowerMode(token, mode);//到SurfaceControl设置状态
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER); } }
private void setDisplayBrightness(int brightness) { try {
mBacklight.setBrightness(brightness);//设置亮度 } finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER); } } }; }
return null; }
DisplayPowerControl设置亮度逻辑(根据VSync信号将亮度慢慢变亮)
上面在DisplayPowerState中仅仅是设置状态,比如刚点亮屏幕这个时候其实设置的brightness为0,我们继续分析DisplayPowerState的updatePowerState函数。在updatePowerState函数中,当设置亮度时会调用如下代码:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 if (!mPendingScreenOff) {
if (state == Display.STATE_ON || state == Display.STATE_DOZE) { animateScreenBrightness(brightness, slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); } else {
animateScreenBrightness(brightness, 0); } }
我们注意到这里有一个BRIGHTNESS_RAMP_RATE_SLOW 和BRIGHTNESS_RAMP_RATE_FAST(这里涉及到亮度显示原理我们后面分析),先看animateScreenBrightness函数。这里函数主要调用了mScreenBrightnessRampAnimator.animateTo函数。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private void animateScreenBrightness(int target, int rate) {
if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { try {
mBatteryStats.noteScreenBrightness(target); } catch (RemoteException ex) { // same process } } }
我们再来看mScreenBrightnessRampAnimator 对象的创建
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
mScreenBrightnessRampAnimator = new RampAnimator
我们注意一个参数是DisplayPowerState对象mPowerState,另一个参数是DisplayPowerState.SCREEN_BRIGHTNESS
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
public static final IntProperty
public void setValue(DisplayPowerState object, int value) { object.setScreenBrightness(value); }
@Override
public Integer get(DisplayPowerState object) { return object.getScreenBrightness(); } };
RampAnimator的构造函数。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 public RampAnimator(T object, IntProperty
mChoreographer = Choreographer.getInstance(); }
我们结合RampAnimator的构造函数,再来分析RampAnimator的animateTo函数。
1. 当rate<=0时,这个时候,我们直接调用mProperty.setValue。就是调用DisplayPowerState的setScreenBrightness函数。这个setScreenBrightness函数我们后面分析。
2. 当rate>0时,这个时候会调用postAnimationCallback函数(这个函数根据VSync信号过来,把亮度慢慢上升的一个过程),而且mAnimating置为true。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 public boolean animateTo(int target, int rate) {
// Immediately jump to the target the first time. if (mFirstTime || rate <= 0) {
if (mFirstTime || target != mCurrentValue) { mFirstTime = false; mRate = 0;
mTargetValue = target; mCurrentValue = target;
mProperty.setValue(mObject, target);//设置值 if (mAnimating) {
mAnimating = false;
cancelAnimationCallback(); }
if (mListener != null) {
mListener.onAnimationEnd(); }
return true; }
return false; }
// Adjust the rate based on the closest target.
// If a faster rate is specified, then use the new rate so that we converge // more rapidly based on the nwww.sm136.comew request.
// If a slower rate is specified, then use the new rate only if the current // value is somewhere in between the new and the old target meaning that // we will be ramping in a different direction to get there. // Otherwise, continue at the previous rate. if (!mAnimating
|| rate > mRate
|| (target <= mCurrentValue && mCurrentValue <= mTargetValue) || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) {
mRate = rate; }
final boolean changed = (mTargetValue != target); mTargetValue = target;
// Start animating.
if (!mAnimating && target != mCurrentValue) { mAnimating = true;
mAnimatedValue = mCurrentValue;
mLastFrameTimeNanos = System.nanoTime(); postAnimationCallback(); }
return changed; }
下面我们先分析postAnimationCallback函数,这个和之前分析WMS的VSync信号类似,当VSync信号过来时,会调用mAnimationCallback函数。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private void postAnimationCallback() {
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); }
那我们继续看mAnimationCallback 的run函数,这个函数当当前值和上一次值不一样,我们就调用DisplayPowerState的setScreenBrightness来设置亮度。而且当前值不是目标值,我们就继续调用postAnimationCallback函数,来设置VSync回调。最后当亮度变成目标值后,将mAnimating 置为false,代表亮度变化的动画结束了。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private final Runnable mAnimationCallback = new Runnable() { @Override // Choreographer callback public void ruwww.tt951.comn() {
final long frameTimeNanos = mChoreographer.getFrameTimeNanos(); final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos) * 0.000000001f;
mLastFrameTimeNanos = frameTimeNanos;
final float scale = ValueAnimator.getDurationScale(); if (scale == 0) {
// Animanc630.comtion 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);//设置到DisplayPowerState的setScreenBrightness函数中 }
if (mTargetValue != mCurrentValue) {//当前值还不是目标值,继续设置VSync回调 postAnimationCallback(); } else {
mAnimating = false;//否则动画标志置为false if (mListener != null) {
mListener.onAnimationEnd(); } } } }
最后我们再看下DisplayPowerState的SetScreenBrightness函数,将亮度设置到mScreenBrightness 中,当屏幕状态不为off时,调用scheduleScreenUpdate函数(所以肯定先要调用setScreenState来设置屏幕状态为on,这样才能设置屏幕亮度)。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 public void setScreenBrightness(int brightness) { if (mScreenBrightness != brightness) { mScreenBrightness = brightness;
if (mScreenState != Display.STATE_OFF) { mScreenReady = false; scheduleScreenUpdate(); } } }
scheduleScreenUpdate最后通过发消息会调用如下代码,这里状态已经是ON了,就会把刚刚设置的mScreenBrightness作为参数设置到mPhotonicModulator.setState中。流程和设置state一样了,只是一开始亮屏时,设置state时,亮度为0而已。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private final Runnable mScreenUpdateRunnable = new Runnable() { @Override
public void run() {
mScreenUpdatePending = false;
int brightness = mScreenState != Display.STATE_OFF
&& mColorFadeLevel > 0f ? mScreenBrightness : 0; if (mPhotonicModulator.setState(mScreenState, brightness)) { if (DEBUG) {
Slog.d(TAG, \ }
mScreenReady = true;
invokeCleanListenerIfNeeded(); } else {
if (DEBUG) {
Slog.d(TAG, \ } } } };
正在阅读:
Android6.0 亮屏灭屏流程(DisplayPowerControler、WMS)(二)亮度设置12-03
09行政管理1班团支部“活力在基层,成才在莞工”主题团日活动01-26
新标准高职公共英语实用综合教程(第二版)unit309-05
水利水电工程高压配电装置设计规范06-11
Arcteryx始祖鸟CeriumLTJacket男款羽绒夹克04-08
不能以战术上的勤奋,掩盖战略上的懒惰07-22
中国古代文学史(一)题库(1)11-26
最新高考化学全课时总复习资料(全高中 共302页 附答案)03-08
2014-2015学年度班主任工作总结-武威三中-邵志光05-23
全套管全回转钻机施工案例 - 图文10-30
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- DisplayPowerCont
- 亮度
- 流程
- Android
- 设置
- roler
- 6.0
- WMS
- 2014年全国各地中考语文试题分类整理:古诗词鉴赏
- 安全生产措施方案
- 岩土工程勘察试题附答案
- EAS扩展脚本编写指南
- 第二章 原核微生物习题及答案
- 航海英语听力与会话第三版问答题参考答案
- 化学教学测育与评价 第十章作业
- 2012年潍坊市初中学业水平考试
- 八年级英语第6周周清试题
- 洪家渡水电站面板堆石坝垫层料生产及质量控制
- 大理市第二人民医院护理质量持续改进检查反馈表(三月份)
- 高炉煤气干法布袋除尘技术在大型高炉上的应用 doc
- 主题班会团结友爱
- 2014年春季三年级科学下册教学计划下 2
- 杨培志 构建和谐校园之我见
- 利益二重性视角下的社会监督问题及其对策
- 现代管理学作业3
- 7.5(2)日日清 -
- 某公司工程实体质量实测实量作业指引 - 图文
- 数控铣床刀具半径补偿G40.G41.G42