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

转载: https://blog.csdn.net/kc58236582/article/details/54612777

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


DisplayPowerControl

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

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

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

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

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. updateScreenOffSleepToken( true);
  5. synchronized (mLock) {
  6. mScreenOnEarly = false;
  7. mScreenOnFully = false;
  8. mKeyguardDrawComplete = false;
  9. mWindowManagerDrawComplete = false;
  10. mScreenOnListener = null;
  11. updateOrientationListenerLp();
  12. if (mKeyguardDelegate != null) {
  13. mKeyguardDelegate.onScreenTurnedOff();
  14. }
  15. }
  16. }

我们再来看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. updateScreenOffSleepToken( false);
  5. synchronized (mLock) {
  6. mScreenOnEarly = true;
  7. mScreenOnFully = false;
  8. mKeyguardDrawComplete = false;
  9. mWindowManagerDrawComplete = false;
  10. mScreenOnListener = screenOnListener; //屏幕点亮后的回调
  11. if (mKeyguardDelegate != null) {
  12. if (DEBUG_WAKEUP) Slog.d(TAG,
  13. "send delay message MSG_KEYGUARD_DRAWN_TIMEOUT");
  14. mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
  15. mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
  16. mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
  17. } else {
  18. if (DEBUG_WAKEUP) Slog.d(TAG,
  19. "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
  20. finishKeyguardDrawn();
  21. }
  22. }
  23. }

我们先看下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. mKeyguardDrawComplete = true;
  7. if (mKeyguardDelegate != null) {
  8. mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
  9. }
  10. mWindowManagerDrawComplete = false;
  11. }
  12. // ... eventually calls finishWindowsDrawn which will finalize our screen turn on
  13. // as well as enabling the orientation change logic/sensor.
  14. mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
  15. WAITING_FOR_DRAWN_TIMEOUT);
  16. }

最后我们再看看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. // No need to wait for the windows below Keyguard.
  18. if (isForceHiding) {
  19. break;
  20. }
  21. }
  22. }
  23. requestTraversalLocked();
  24. }
  25. mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
  26. if (mWaitingForDrawn.isEmpty()) {
  27. callback.run();
  28. Slog.i(TAG, "In the function mWaitingForDrawn.isEmpty()");
  29. } else {
  30. mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);
  31. checkDrawnWindowsLocked();
  32. Slog.i(TAG, "In the function checkDrawnWindowsLocked()");
  33. }
  34. }

我们先来看下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. mWindowManagerDrawComplete = true;
  7. }
  8. finishScreenTurningOn();
  9. }

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. if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete
  9. || (mAwake && !mKeyguardDrawComplete)) {
  10. return; // spurious or not ready yet
  11. }
  12. listener = mScreenOnListener;
  13. mScreenOnListener = null;
  14. mScreenOnFully = true;
  15. ......
  16. }
  17. if (listener != null) {
  18. listener.onScreenOn();
  19. }
  20. if (enableScreen) {
  21. try {
  22. mWindowManager.enableScreenIfNeeded();
  23. } catch (RemoteException unhandled) {
  24. }
  25. }
  26. }

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


窗口绘制完成后调用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. }
  8. }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值