(原创)Android6.0亮屏流程之Keyguard Window绘制

亮灭屏问题一直是Android模块最常见的问题之一。


       由于问题出现问题的地方涉及到公司代码,我这里仅仅只作原生代码模块的分析

       其实在看过另外一篇关于android亮屏流程的文章就会发现,影响亮屏快慢的因素大致有三种:1.设置背光流程出问题了,导致屏幕黑屏,2.window绘制时间过长,导致屏幕block时间过长;3.底层surfacecontroller准备时间过长。

而根据遇到的亮屏慢的问题,基本上都是由于window绘制时间过长,导致屏幕亮屏慢

最近处理的几个亮屏慢的问题,其中关键log信息基本都是:

10-28 09:02:59.002  1393  1462 I DisplayPowerController: Blocking screen on until initial contents have been drawn.

10-28 09:03:05.020  1393  1462 I DisplayPowerController: Unblocked screen on after 6018 ms

由于在android亮屏流程中大致描述的亮屏所走的流程点,但是仅仅只能作为一个粗略的点做参考,但是看到上面的两条信息,我们可以去追溯一下代码流程:

在每一次屏幕电源状态发生改变的都会调用的到DisplayPowerController中的updatePowerState方法,在该方法中如果屏幕状态发生改变的话,会去调用到animateScreenStateChange,在setScreenState方法里面去设置屏幕状态。那么就到了该问题的主要流程了。


在DisplayPowerController.java中的setScreenState()方法中,有代码:

[java]  view plain  copy
  1.     if (mPowerState.getColorFadeLevel() == 0.0f) {  
  2.         blockScreenOn();  
  3.     } else {  
  4.         unblockScreenOn();  
  5.     }  
  6.     mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);  
  7. }  
  8.   
  9. // Return true if the screen isn't blocked.  
  10. return mPendingScreenOnUnblocker == null;  

首先会调用到 blockScreenOn方法,先看看该方法以及后面要调用到的unblockScreenOn的方法

[java]  view plain  copy
  1. private void blockScreenOn() {  
  2.     if (mPendingScreenOnUnblocker == null) {  
  3.         Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);  
  4.         mPendingScreenOnUnblocker = new ScreenOnUnblocker();  
  5.         mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();  
  6.         Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");  
  7.     }  
  8. }  
  9.    
  10. private void unblockScreenOn() {  
  11.     if (mPendingScreenOnUnblocke != null) {  
  12.         mPendingScreenOnUnblocker = null;  
  13.         long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;  
  14.         Slog.i(TAG, "Unblocked screen on after " + delay + " ms");  
  15.         Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);  
  16.     }  
  17. }  

在blockScreenOn函数中其实就是创建了一个mPendingScreenOnUnblocker 对象,当该对象为空时,mPendingScreenOnUnblocker == null;返回值才为true。animateScreenStateChange才能继续往下执行下去。

 

亮屏过程中绘制window过程是通过mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); 调用到PhoneWindowManager中的screenTurningOn(),

[java]  view plain  copy
  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. }  
可以看到mPendingScreenOnUnblocker是继承了WindowManagerPolicy.ScreenOnListener这个接口,而该接口同样是作为一个callback到PhoneWindowManager那边去绘制window,当all window for drawn 完成之后,会回调到 mPendingScreenOnUnblocker的onScreenOn,会去unblock屏幕


这里用一个图来详细描述






可以看到 整个过程调用的点较为混乱,这里只能简单描述一下其调用过程当PowerManagerService发出的wakeup请求到DisplayPowerController这边,在DisplayPowerConrtoller中setScreenState方法中会调用到PhoneWindowManager模块的screenTurningOn方法去通过window绘制屏幕。

由于在灭屏之后亮屏首先现实的界面应该是锁屏界面,所以亮屏首先应该去绘制keyguard,并且keyguard经常会出现超时,当出现keyguard超时时会打印:

WindowManager:Keyguard drawn timeout. Setting mKeyguardDrawComplete

当出现上述打印,便可以确定时keyguard模块绘制锁屏超时,需要锁屏的人去确认超时原因。锁屏超时时间最长也只有2秒时间。因为

[java]  view plain  copy
  1. if (mKeyguardDelegate != null) {  
  2.     mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);  
  3.     mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);  
  4.     mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);  
  5. else {  

当mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);正常执行完成的情况下会调用到finishKeyguardDrawn,当未能正常执行,超过1秒还未完成便会发送消息MSG_KEYGUARD_DRAWN_TIMEOUT强制执行finishKeyguardDrawn,    

 在finishKeyguardDrawn完成后会检查所有的亮屏后所依赖的window是否都绘制完成,在mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,WAITING_FOR_DRAWN_TIMEOUT);//WAITING_FOR_DRAWN_TIMEOUT = 1000 中会去检查window绘制,如上,当超过1秒后,会自动release等待的window,然后正常亮屏。


原文地址:http://blog.csdn.net/u011311586/article/details/53174280

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值