Android6.0 亮屏灭屏流程(DisplayPowerController、WMS)(一)WMS绘制 联系客服

发布时间 : 星期一 文章Android6.0 亮屏灭屏流程(DisplayPowerController、WMS)(一)WMS绘制更新完毕开始阅读c58aba1917fc700abb68a98271fe910ef12dae9d

Android6.0 亮屏灭屏流程(DisplayPowerController、WMS)(一)

WMS绘制

亮屏、灭屏流程整个流程涉及的模块比较多,包括PowerManagerService、DisplayPowerControl、WMS、AMS。因此在分析完WMS之后,我们把这块也分析下。

DisplayPowerControl

我们知道灭屏流程的发起是在PowerManagerService中,会通过updatePowerState函数调用updateDisplayPowerStateLocked函数,再调用DisplayPowerControl的requestPowerState函数,到DisplayPowerControl中。DisplayPowerControl中后面会调用updatePowerState函数,我们也主要从这个函数开始分析:

updatePowerState会根据PowerManagerService传过来的显示状态,然后调用animateScreenStateChange函数。 [cpp] view plain copy

animateScreenStateChange(state, performScreenOffTransition); 下面我们先来看animateScreenStateChange函数: [cpp] view plain copy

private void animateScreenStateChange(int target, boolean performScreenOffTransition) { // If there is already an animation in progress, don't interfere with it. if (mColorFadeOnAnimator.isStarted()

|| mColorFadeOffAnimator.isStarted()) { return; }

// If we were in the process of turning off the screen but didn't quite // finish. Then finish up now to prevent a jarring transition back // to screen on if we skipped blocking screen on as usual. if (mPendingScreenOff && target != Display.STATE_OFF) { setScreenState(Display.STATE_OFF); mPendingScreenOff = false;

mPowerState.dismissColorFadeResources(); }

if (target == Display.STATE_ON) {//亮屏处理

// Want screen on. The contents of the screen may not yet // be visible if the color fade has not been dismissed because // its last frame of animation is solid black. if (!setScreenState(Display.STATE_ON)) { return; // screen on blocked }

if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {//

亮屏动画

// Perform screen on animation.

if (mPowerState.getColorFadeLevel() == 1.0f) { mPowerState.dismissColorFade();

} else if (mPowerState.prepareColorFade(mContext, mColorFadeFadesConfig ?

ColorFade.MODE_FADE :

ColorFade.MODE_WARM_UP)) { mColorFadeOnAnimator.start(); } else {

mColorFadeOnAnimator.end(); }

} else {//跳过亮屏动画

// Skip screen on animation.

mPowerState.setColorFadeLevel(1.0f); mPowerState.dismissColorFade(); }

} else if (target == Display.STATE_DOZE) { // Want screen dozing.

// Wait for brightness animation to complete beforehand when entering doze // from screen on to prevent a perceptible jump because brightness may operate // differently when the display is configured for dozing. ......

} else if (target == Display.STATE_DOZE_SUSPEND) { // Want screen dozing and suspended.

// Wait for brightness animation to complete beforehand unless already // suspended because we may not be able to change it after suspension. ......

} else {//灭屏处理 // Want screen off.

mPendingScreenOff = true;

if (mPowerState.getColorFadeLevel() == 0.0f) {//灭屏动画结束 // Turn the screen off.

// A black surface is already hiding the contents of the screen. setScreenState(Display.STATE_OFF); mPendingScreenOff = false;

mPowerState.dismissColorFadeResources(); } else if (performScreenOffTransition

&& mPowerState.prepareColorFade(mContext, mColorFadeFadesConfig ?

ColorFade.MODE_FADE ColorFade.MODE_COOL_DOWN)

&& mPowerState.getScreenState() != Display.STATE_OFF) { // Perform the screen off animation.

:

mColorFadeOffAnimator.start();//开启灭屏动画 } else {

// Skip the screen off animation and add a black surface to hide the // contents of the screen.

mColorFadeOffAnimator.end();//关闭灭屏动画 } } }

animateScreenStateChange在亮屏的处理的时候,先会调用setScreenState(Display.STATE_ON),然后根据USE_COLOR_FADE_ON_ANIMATION 判断是否要开启亮屏动画,这里我们是没有设置的。因此直接跳过亮屏动画。灭屏的处理的话,会有一个灭屏动画(也是注册一个VSync信号回调函数处理的,这里我们不分析了),当动画结束后,直接就调用setScreenState(Display.STATE_OFF)结束。 我们再来看看setScreenState函数 [cpp] view plain copy

private boolean setScreenState(int state) {

if (mPowerState.getScreenState() != state) {

final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF); mPowerState.setScreenState(state); ...... }

// Tell the window manager policy when the screen is turned off or on unless it's due // to the proximity sensor. We temporarily block turning the screen on until the // window manager is ready by leaving a black surface covering the screen. // This surface is essentially the final state of the color fade animation and // it is only removed once the window manager tells us that the activity has // finished drawing underneath.

final boolean isOff = (state == Display.STATE_OFF);

if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF && !mScreenOffBecauseOfProximity) {

mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF; unblockScreenOn();

mWindowManagerPolicy.screenTurnedOff();//调用PhoneWindowManager的screenTurnedOff } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) { mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON; if (mPowerState.getColorFadeLevel() == 0.0f) { blockScreenOn(); } else {

unblockScreenOn(); }

mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);//调用PhoneWindowManager的screenTurningOn函数 }

// Return true if the screen isn't blocked.

return mPendingScreenOnUnblocker == null; }

setScreenState函数,先是调用了DisplayPowerState的setScreenState函数,然后根据屏幕是灭屏还是亮屏调用PhoneWindowManager的相关函数。

PhoneWindowManager的screenTurnedOff和screenTurningOn函数

PhoneWindowManager的screenTurnedOff函数主要是通知kerguard,屏幕灭屏了。 [cpp] view plain copy @Override

public void screenTurnedOff() {

if (DEBUG_WAKEUP) Slog.i(TAG, \

updateScreenOffSleepToken(true); synchronized (mLock) {

mScreenOnEarly = false; mScreenOnFully = false;

mKeyguardDrawComplete = false;

mWindowManagerDrawComplete = false; mScreenOnListener = null; updateOrientationListenerLp();

if (mKeyguardDelegate != null) {

mKeyguardDelegate.onScreenTurnedOff(); } } }

我们再来看PhoneWindowManager的screenTurningOn函数。当有keyguard时,我们会先发一个延时的MSG_KEYGUARD_DRAWN_TIMEOUT信号,并且会调用keyguard的onScreenTurningOn函数,当完成会调用mKeyguardDrawnCallback回调函数。我们这里还要注意下有一个屏幕点亮后的回调。

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 @Override

public void screenTurningOn(final ScreenOnListener screenOnListener) { if (DEBUG_WAKEUP) Slog.i(TAG, \

updateScreenOffSleepToken(false); synchronized (mLock) { mScreenOnEarly = true; mScreenOnFully = false;