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

http://blog.csdn.net/kc58236582/article/details/54612777

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


DisplayPowerControl

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

updatePowerState会根据PowerManagerService传过来的显示状态,然后调用animateScreenStateChange函数。

  1. animateScreenStateChange(state, performScreenOffTransition);  

下面我们先来看animateScreenStateChange函数:

  1. private void animateScreenStateChange(int target, boolean performScreenOffTransition) {  
  2.     // If there is already an animation in progress, don't interfere with it.  
  3.     if (mColorFadeOnAnimator.isStarted()  
  4.             || mColorFadeOffAnimator.isStarted()) {  
  5.         return;  
  6.     }  
  7.   
  8.     // If we were in the process of turning off the screen but didn't quite  
  9.     // finish.  Then finish up now to prevent a jarring transition back  
  10.     // to screen on if we skipped blocking screen on as usual.  
  11.     if (mPendingScreenOff && target != Display.STATE_OFF) {  
  12.         setScreenState(Display.STATE_OFF);  
  13.         mPendingScreenOff = false;  
  14.         mPowerState.dismissColorFadeResources();  
  15.     }  
  16.   
  17.     if (target == Display.STATE_ON) {//亮屏处理  
  18.         // Want screen on.  The contents of the screen may not yet  
  19.         // be visible if the color fade has not been dismissed because  
  20.         // its last frame of animation is solid black.  
  21.         if (!setScreenState(Display.STATE_ON)) {  
  22.             return// screen on blocked  
  23.         }  
  24.         if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {//亮屏动画  
  25.             // Perform screen on animation.  
  26.             if (mPowerState.getColorFadeLevel() == 1.0f) {  
  27.                 mPowerState.dismissColorFade();  
  28.             } else if (mPowerState.prepareColorFade(mContext,  
  29.                     mColorFadeFadesConfig ?  
  30.                             ColorFade.MODE_FADE :  
  31.                                     ColorFade.MODE_WARM_UP)) {  
  32.                 mColorFadeOnAnimator.start();  
  33.             } else {  
  34.                 mColorFadeOnAnimator.end();  
  35.             }  
  36.         } else {//跳过亮屏动画  
  37.             // Skip screen on animation.  
  38.             mPowerState.setColorFadeLevel(1.0f);  
  39.             mPowerState.dismissColorFade();  
  40.         }  
  41.     } else if (target == Display.STATE_DOZE) {  
  42.         // Want screen dozing.  
  43.         // Wait for brightness animation to complete beforehand when entering doze  
  44.         // from screen on to prevent a perceptible jump because brightness may operate  
  45.         // differently when the display is configured for dozing.  
  46.  ......  
  47.     } else if (target == Display.STATE_DOZE_SUSPEND) {  
  48.         // Want screen dozing and suspended.  
  49.         // Wait for brightness animation to complete beforehand unless already  
  50.         // suspended because we may not be able to change it after suspension.  
  51.  ......  
  52.     } else {//灭屏处理  
  53.         // Want screen off.  
  54.         mPendingScreenOff = true;  
  55.         if (mPowerState.getColorFadeLevel() == 0.0f) {//灭屏动画结束  
  56.             // Turn the screen off.  
  57.             // A black surface is already hiding the contents of the screen.  
  58.             setScreenState(Display.STATE_OFF);  
  59.             mPendingScreenOff = false;  
  60.             mPowerState.dismissColorFadeResources();  
  61.         } else if (performScreenOffTransition  
  62.                 && mPowerState.prepareColorFade(mContext,  
  63.                         mColorFadeFadesConfig ?  
  64.                                 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)  
  65.                 && mPowerState.getScreenState() != Display.STATE_OFF) {  
  66.             // Perform the screen off animation.  
  67.             mColorFadeOffAnimator.start();//开启灭屏动画  
  68.         } else {  
  69.             // Skip the screen off animation and add a black surface to hide the  
  70.             // contents of the screen.  
  71.             mColorFadeOffAnimator.end();//关闭灭屏动画  
  72.         }  
  73.     }  
  74. }  

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

我们再来看看setScreenState函数

  1. private boolean setScreenState(int state) {  
  2.     if (mPowerState.getScreenState() != state) {  
  3.         final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);  
  4.         mPowerState.setScreenState(state);  
  5.  ......  
  6.     }  
  7.   
  8.     // Tell the window manager policy when the screen is turned off or on unless it's due  
  9.     // to the proximity sensor.  We temporarily block turning the screen on until the  
  10.     // window manager is ready by leaving a black surface covering the screen.  
  11.     // This surface is essentially the final state of the color fade animation and  
  12.     // it is only removed once the window manager tells us that the activity has  
  13.     // finished drawing underneath.  
  14.     final boolean isOff = (state == Display.STATE_OFF);  
  15.     if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF  
  16.             && !mScreenOffBecauseOfProximity) {  
  17.         mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;  
  18.         unblockScreenOn();  
  19.         mWindowManagerPolicy.screenTurnedOff();//调用PhoneWindowManager的screenTurnedOff  
  20.     } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {  
  21.         mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;  
  22.         if (mPowerState.getColorFadeLevel() == 0.0f) {  
  23.             blockScreenOn();  
  24.         } else {  
  25.             unblockScreenOn();  
  26.         }  
  27.         mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);//调用PhoneWindowManager的screenTurningOn函数  
  28.     }  
  29.   
  30.     // Return true if the screen isn't blocked.  
  31.     return mPendingScreenOnUnblocker == null;  
  32. }  

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


PhoneWindowManager的screenTurnedOff和screenTurningOn函数

PhoneWindowManager的screenTurnedOff函数主要是通知kerguard,屏幕灭屏了。

  1. @Override  
  2. public void screenTurnedOff() {  
  3.     if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");  
  4.   
  5.     updateScreenOffSleepToken(true);  
  6.     synchronized (mLock) {  
  7.         mScreenOnEarly = false;  
  8.         mScreenOnFully = false;  
  9.         mKeyguardDrawComplete = false;  
  10.         mWindowManagerDrawComplete = false;  
  11.         mScreenOnListener = null;  
  12.         updateOrientationListenerLp();  
  13.   
  14.         if (mKeyguardDelegate != null) {  
  15.             mKeyguardDelegate.onScreenTurnedOff();  
  16.         }  
  17.     }  
  18. }  

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

  1. @Override  
  2. public void screenTurningOn(final ScreenOnListener screenOnListener) {  
  3.     if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");  
  4.   
  5.     updateScreenOffSleepToken(false);  
  6.     synchronized (mLock) {  
  7.         mScreenOnEarly = true;  
  8.         mScreenOnFully = false;  
  9.         mKeyguardDrawComplete = false;  
  10.         mWindowManagerDrawComplete = false;  
  11.         mScreenOnListener = screenOnListener;//屏幕点亮后的回调  
  12.   
  13.         if (mKeyguardDelegate != null) {  
  14.             if (DEBUG_WAKEUP) Slog.d(TAG,  
  15.                     "send delay message MSG_KEYGUARD_DRAWN_TIMEOUT");  
  16.             mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);  
  17.             mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);  
  18.             mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);  
  19.         } else {  
  20.             if (DEBUG_WAKEUP) Slog.d(TAG,  
  21.                     "null mKeyguardDelegate: setting mKeyguardDrawComplete.");  
  22.             finishKeyguardDrawn();  
  23.         }  
  24.     }  
  25. }  

我们先看下mKeyguardDrawnCallback 回调,就是发送MSG_KEYGUARD_DRAWN_COMPLETE(keyguard绘制完的消息)

  1. final DrawnListener mKeyguardDrawnCallback = new DrawnListener() {  
  2.     @Override  
  3.     public void onDrawn() {  
  4.         if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn.");  
  5.         mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);  
  6.     }  
  7. };  

我们再来看看MSG_KEYGUARD_DRAWN_COMPLETE以及MSG_KEYGUARD_DRAWN_TIMEOUT信号的处理,都会调用finishKeyguardDrawn函数。

  1. case MSG_KEYGUARD_DRAWN_COMPLETE:  
  2.     if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");  
  3.     finishKeyguardDrawn();  
  4.     break;  
  5. case MSG_KEYGUARD_DRAWN_TIMEOUT:  
  6.     Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");  
  7.     finishKeyguardDrawn();  
  8.     break;  
我们再来看看finishKeyguardDrawn函数,会先去除队列中的MSG_KEYGUARD_DRAWN_TIMEOUT消息(因为之前发的MSG_KEYGUARD_DRAWN_TIMEOUT消息,可能keyguard结束发送MSG_KEYGUARD_DRAWN_COMPLETE消息调用的finishKeyguardDrawn就要把MSG_KEYGUARD_DRAWN_TIMEOUT去除了)。然后会调用
  1. private void finishKeyguardDrawn() {  
  2.     synchronized (mLock) {  
  3.         if (!mScreenOnEarly || mKeyguardDrawComplete) {  
  4.             return// We are not awake yet or we have already informed of this event.  
  5.         }  
  6.   
  7.         mKeyguardDrawComplete = true;  
  8.         if (mKeyguardDelegate != null) {  
  9.             mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);  
  10.         }  
  11.         mWindowManagerDrawComplete = false;  
  12.     }  
  13.   
  14.     // ... eventually calls finishWindowsDrawn which will finalize our screen turn on  
  15.     // as well as enabling the orientation change logic/sensor.  
  16.     mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,  
  17.             WAITING_FOR_DRAWN_TIMEOUT);  
  18. }  

最后我们再看看WMS的waitForAllWindowsDrawn函数,以及两个参数mWindowManagerDrawCallback和一个WAITING_FOR_DRAWN_TIMEOUT(1秒)。


WMS的waitForAllWindowsDrawn函数

我们先来看看WMS的waitForAllWindowsDrawn函数,会把传进来的回调保存在mWaitingForDrawnCallback 。然后遍历所有的windows,把需要显示或者已经显示的窗口全部加入到mWaitingForDrawn,然后调用requestTraversalLocked这个函数我们之前分析过,就是发送一个消息,重新刷新UI布局。然后我们继续分析这个函数,如果mWaitingForDrawn为空,代表没啥显示的直接调用回调函数,如果mWaitingForDrawn有要显示的窗口,就要会先发送一个WAITING_FOR_DRAWN_TIMEOUT,这个timeout之前传进来的是1秒。然后调用checkDrawnWindowsLocked函数。

  1. @Override  
  2. public void waitForAllWindowsDrawn(Runnable callback, long timeout) {  
  3.     synchronized (mWindowMap) {  
  4.         mWaitingForDrawnCallback = callback;//回调保存在mWaitingForDrawnCallback   
  5.         final WindowList windows = getDefaultWindowListLocked();  
  6.         for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {  
  7.             final WindowState win = windows.get(winNdx);  
  8.             final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs);  
  9.             Slog.i(TAG,"In the function waitForAllWindowsDrawn");  
  10.             if (win.isVisibleLw()  
  11.                     && (win.mAppToken != null || isForceHiding)) {  
  12.                 Slog.i(TAG,"In the function win.isVisibleLw()");  
  13.                 win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;  
  14.                 // Force add to mResizingWindows.  
  15.                 win.mLastContentInsets.set(-1, -1, -1, -1);  
  16.                 mWaitingForDrawn.add(win);  
  17.   
  18.                 // No need to wait for the windows below Keyguard.  
  19.                 if (isForceHiding) {  
  20.                     break;  
  21.                 }  
  22.             }  
  23.         }  
  24.         requestTraversalLocked();  
  25.     }  
  26.     mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);  
  27.     if (mWaitingForDrawn.isEmpty()) {  
  28.         callback.run();  
  29.         Slog.i(TAG,"In the function mWaitingForDrawn.isEmpty()");  
  30.     } else {  
  31.         mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);  
  32.         checkDrawnWindowsLocked();  
  33.         Slog.i(TAG,"In the function checkDrawnWindowsLocked()");  
  34.     }  
  35. }  

我们先来看下checkDrawnWindowsLocked函数,这个函数。遍历之前加入的mWaitingForDrawn(要显示的窗口),这个时候我们把已经去除的,不需要显示的,没有surface的窗口从mWaitingForDrawn去除,还有已经绘制好的也去除。然后再当mWaitingForDrawn为空时,就发送ALL_WINDOWS_DRAWN消息。

  1. void checkDrawnWindowsLocked() {  
  2.     if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {  
  3.         return;  
  4.     }  
  5.     for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {  
  6.         WindowState win = mWaitingForDrawn.get(j);  
  7.         if (win.mRemoved || !win.mHasSurface || !win.mPolicyVisibility) {  
  8.             // Window has been removed or hidden; no draw will now happen, so stop waiting.  
  9.             if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win);  
  10.             mWaitingForDrawn.remove(win);  
  11.         } else if (win.hasDrawnLw()) {  
  12.             // Window is now drawn (and shown).  
  13.             if (DEBUG_SCREEN_ON) Slog.d(TAG, "Window drawn win=" + win);  
  14.             mWaitingForDrawn.remove(win);  
  15.         }  
  16.     }  
  17.     if (mWaitingForDrawn.isEmpty()) {  
  18.         if (DEBUG_SCREEN_ON) Slog.d(TAG, "All windows drawn!");  
  19.         mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);  
  20.         mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);  
  21.     }  
  22. }  

ALL_WINDOWS_DRAWN消息的处理就是清除mWaitingForDrawnCallback ,然后调用回调。

  1. case ALL_WINDOWS_DRAWN: {  
  2.     Runnable callback;  
  3.     synchronized (mWindowMap) {  
  4.         callback = mWaitingForDrawnCallback;  
  5.         mWaitingForDrawnCallback = null;  
  6.     }  
  7.     if (callback != null) {  
  8.         callback.run();  
  9.     }  
  10. }  

还有当我们调用waitForAllWindowsDrawn一般都是有需要显示的窗口,但是我们直接调用checkDrawnWindowsLocked函数,发现有的窗口还没绘制完成。那么我们就要等,会在刷新的核心函数中performLayoutAndPlaceSurfacesLockedInner有如下代码,这个时候如果之前还没绘制完成的窗口,绘制好了。会再调用checkDrawnWindowsLocked函数,如果mWaitingForDrawn中的窗口绘制好了,会在mWaitingForDrawn中去除这个窗口。然后mWaitingForDrawn为空了,之后会发送ALL_WINDOWS_DRAWN消息,还调用mWaitingForDrawnCallback回调函数。

  1. if (mWaitingForDrawnCallback != null ||  
  2.         (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&  
  3.                 !mInnerFields.mUpdateRotation)) {  
  4.     checkDrawnWindowsLocked();  
  5. }  

当然如果我们之前没有把mWaitingForDrawn中的窗口清空,最后在WAITING_FOR_DRAWN_TIMEOUT(这里是1秒)时间到了也会调用回调的。

  1. case WAITING_FOR_DRAWN_TIMEOUT: {  
  2.     Runnable callback = null;  
  3.     synchronized (mWindowMap) {  
  4.         Slog.w(TAG, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn);  
  5.         mWaitingForDrawn.clear();  
  6.         callback = mWaitingForDrawnCallback;  
  7.         mWaitingForDrawnCallback = null;  
  8.     }  
  9.     if (callback != null) {  
  10.         callback.run();  
  11.     }  
  12.     break;  
  13. }  



PhoneWindowManager窗口绘制完成的回调函数

那下面我们就要继续看PhoneWindowManager中窗口绘制完成之后的回调函数。代码如下就是发送了一个消息。

  1. final Runnable mWindowManagerDrawCallback = new Runnable() {  
  2.     @Override  
  3.     public void run() {  
  4.         if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");  
  5.         mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);  
  6.     }  
  7. };  

我们来看这个消息的处理

  1. case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:  
  2.     if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");  
  3.     finishWindowsDrawn();  
  4.     break;  

finishWindowsDrawn就是把mWindowManagerDrawComplete 置为true,然后调用finishScreenTurningOn函数。

  1. private void finishWindowsDrawn() {  
  2.     synchronized (mLock) {  
  3.         if (!mScreenOnEarly || mWindowManagerDrawComplete) {  
  4.             return// Screen is not turned on or we did already handle this case earlier.  
  5.         }  
  6.   
  7.         mWindowManagerDrawComplete = true;  
  8.     }  
  9.   
  10.     finishScreenTurningOn();  
  11. }  

finishScreenTurningOn函数调用了之前在DisplayPowerControl中调用screenTurningOn传入的回调,然后再调用WMS的enableScreenIfNeeded函数。

  1. private void finishScreenTurningOn() {  
  2.     synchronized (mLock) {  
  3.         updateOrientationListenerLp();  
  4.     }  
  5.     final ScreenOnListener listener;  
  6.     final boolean enableScreen;  
  7.     synchronized (mLock) {  
  8.   
  9.         if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete  
  10.                 || (mAwake && !mKeyguardDrawComplete)) {  
  11.             return// spurious or not ready yet  
  12.         }  
  13.   
  14.         listener = mScreenOnListener;  
  15.         mScreenOnListener = null;  
  16.         mScreenOnFully = true;  
  17.         ......  
  18.     }  
  19.   
  20.     if (listener != null) {  
  21.         listener.onScreenOn();  
  22.     }  
  23.   
  24.     if (enableScreen) {  
  25.         try {  
  26.             mWindowManager.enableScreenIfNeeded();  
  27.         } catch (RemoteException unhandled) {  
  28.         }  
  29.     }  
  30. }  

我们先分析下WMS的enableScreenIfNeeded函数,然后再看DisplayPowerControl的回调onScreenOn函数。



WMS的enableScreenIfNeeded函数

WMS的enableScreenIfNeeded函数就是调用了enableScreenIfNeededLocked函数

  1. @Override  
  2. public void enableScreenIfNeeded() {  
  3.     synchronized (mWindowMap) {  
  4.         enableScreenIfNeededLocked();  
  5.     }  
  6. }  

enableScreenIfNeededLocked这个函数仅仅是保证mDisplayEnabled为true,如果为true直接结束。

  1. void enableScreenIfNeededLocked() {  
  2.     if (mDisplayEnabled) {  
  3.         return;  
  4.     }  
  5.     if (!mSystemBooted && !mShowingBootMessages) {  
  6.         return;  
  7.     }  
  8.     mH.sendEmptyMessage(H.ENABLE_SCREEN);  
  9. }  

mDisplayEnabled不为true,发送ENABLE_SCREEN消息

  1. case ENABLE_SCREEN: {  
  2.     performEnableScreen();  
  3.     break;  

performEnableScreen函数会让SurfaceFlinger去停止开机动画等,也会把mDisplayEnabled置为true。当然performEnableScreen在开机的时候会AMS中调用WMS的enableScreenAfterBoot函数来调用performEnableScreen函数。这个我们在博客http://blog.csdn.net/kc58236582/article/details/52921978分析过了。

  1. public void performEnableScreen() {  
  2.     synchronized(mWindowMap) {  
  3.         if (mDisplayEnabled) {  
  4.             return;  
  5.         }  
  6.         if (!mSystemBooted && !mShowingBootMessages) {  
  7.             return;  
  8.         }  
  9.   
  10.         // Don't enable the screen until all existing windows have been drawn.  
  11.         if (!mForceDisplayEnabled && checkWaitingForWindowsLocked()) {  
  12.             return;  
  13.         }  
  14.   
  15.         if (!mBootAnimationStopped) {  
  16.             // Do this one time.  
  17.             try {//停止开机动画  
  18.                 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");  
  19.                 if (surfaceFlinger != null) {  
  20.                     //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");  
  21.                     Parcel data = Parcel.obtain();  
  22.                     data.writeInterfaceToken("android.ui.ISurfaceComposer");  
  23.                     surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED  
  24.                             data, null, 0);  
  25.                     data.recycle();  
  26.                 }  
  27.             } catch (RemoteException ex) {  
  28.                 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");  
  29.             }  
  30.             mBootAnimationStopped = true;  
  31.         }  
  32.   
  33.         if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {  
  34.             if (DEBUG_BOOT) Slog.i(TAG, "performEnableScreen: Waiting for anim complete");  
  35.             return;  
  36.         }  
  37.   
  38.         mDisplayEnabled = true;//置为true  
  39.         if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");  
  40.   
  41.         // Enable input dispatch.  
  42.         mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);  
  43.     }  
  44.   
  45.     try {  
  46.         mActivityManager.bootAnimationComplete();  
  47.     } catch (RemoteException e) {  
  48.     }  
  49.   
  50.     mPolicy.enableScreenAfterBoot();  
  51.   
  52.     // Make sure the last requested orientation has been applied.  
  53.     updateRotationUnchecked(falsefalse);  
  54. }  


窗口绘制完成后调用DisplayPowerControl中的回调

当WMS窗口绘制完成后,会在PhoneWindowManager中的finishScreenTurningOn函数调用DisplayPowerControl的回调函数。最后我们再来看看DisplayPowerControl中的回调的onScreenOn函数。只是发送了一个MSG_SCREEN_ON_UNBLOCKED消息。

  1. private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {  
  2.     @Override  
  3.     public void onScreenOn() {  
  4.         Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);  
  5.         msg.setAsynchronous(true);  
  6.         mHandler.sendMessage(msg);  
  7.     }  
  8. }  

MSG_SCREEN_ON_UNBLOCKED的处理先是调用了unblockScreenOn函数,然后再调用updatePowerState更新状态。

  1. case MSG_SCREEN_ON_UNBLOCKED:  
  2.     if (mPendingScreenOnUnblocker == msg.obj) {  
  3.         unblockScreenOn();  
  4.         updatePowerState();  
  5.     }  
  6.     break;  

unblockScreenOn函数,只是打印下从调用screenTurningOn开始,到窗口绘制完成在PhoneWindowManager中回调这个函数的时间差打印。

  1. private void unblockScreenOn() {  
  2.     if (mPendingScreenOnUnblocker != null) {  
  3.         mPendingScreenOnUnblocker = null;  
  4.         long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;  
  5.         Slog.i(TAG, "Unblocked screen on after " + delay + " ms");  
  6.         Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);  
  7.     }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值