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;