




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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 copyanimateScreenStateChange(state, performScreenOffTransition); 下面我们先来看animateScreenStateChange函数:cpp view plain copyprivate void animateScreenStateChange(int target, boolean performScreenOffTransition) / If there is already an animation in progress, dont interfere with it. if (mColorFadeOnAnimator.isStarted() | mColorFadeOffAnimator.isStarted() return; / If we were in the process of turning off the screen but didnt 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 copyprivate 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 its 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 isnt blocked. return mPendingScreenOnUnblocker = null; setScreenState函数,先是调用了DisplayPowerState的setScreenState函数,然后根据屏幕是灭屏还是亮屏调用PhoneWindowManager的相关函数。PhoneWindowManager的screenTurnedOff和screenTurningOn函数PhoneWindowManager的screenTurnedOff函数主要是通知kerguard,屏幕灭屏了。cpp view plain copyOverride public void screenTurnedOff() if (DEBUG_WAKEUP) Slog.i(TAG, Screen turned off.); 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, Screen turning on.); updateScreenOffSleepToken(false); synchronized (mLock) mScreenOnEarly = true; mScreenOnFully = false; mKeyguardDrawComplete = false; mWindowManagerDrawComplete = false; mScreenOnListener = screenOnListener;/屏幕点亮后的回调 if (mKeyguardDelegate != null) if (DEBUG_WAKEUP) Slog.d(TAG, send delay message MSG_KEYGUARD_DRAWN_TIMEOUT); mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000); mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); else if (DEBUG_WAKEUP) Slog.d(TAG, null mKeyguardDelegate: setting mKeyguardDrawComplete.); finishKeyguardDrawn(); 我们先看下mKeyguardDrawnCallback 回调,就是发送MSG_KEYGUARD_DRAWN_COMPLETE(keyguard绘制完的消息)cpp view plain copy 在CODE上查看代码片派生到我的代码片final DrawnListener mKeyguardDrawnCallback = new DrawnListener() Override public void onDrawn() if (DEBUG_WAKEUP) Slog.d(TAG, mKeyguardDelegate.ShowListener.onDrawn.); mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE); ; 我们再来看看MSG_KEYGUARD_DRAWN_COMPLETE以及MSG_KEYGUARD_DRAWN_TIMEOUT信号的处理,都会调用finishKeyguardDrawn函数。cpp view plain copy 在CODE上查看代码片派生到我的代码片case MSG_KEYGUARD_DRAWN_COMPLETE: if (DEBUG_WAKEUP) Slog.w(TAG, Setting mKeyguardDrawComplete); finishKeyguardDrawn(); break; case MSG_KEYGUARD_DRAWN_TIMEOUT: Slog.w(TAG, Keyguard drawn timeout. Setting mKeyguardDrawComplete); finishKeyguardDrawn(); break; 我们再来看看finishKeyguardDrawn函数,会先去除队列中的MSG_KEYGUARD_DRAWN_TIMEOUT消息(因为之前发的MSG_KEYGUARD_DRAWN_TIMEOUT消息,可能keyguard结束发送MSG_KEYGUARD_DRAWN_COMPLETE消息调用的finishKeyguardDrawn就要把MSG_KEYGUARD_DRAWN_TIMEOUT去除了)。然后会调用cpp view plain copy 在CODE上查看代码片派生到我的代码片private void finishKeyguardDrawn() synchronized (mLock) if (!mScreenOnEarly | mKeyguardDrawComplete) return; / We are not awake yet or we have already informed of this event. mKeyguardDrawComplete = true; if (mKeyguardDelegate != null) mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); mWindowManagerDrawComplete = false; / . eventually calls finishWindowsDrawn which will finalize our screen turn on / as well as enabling the orientation change logic/sensor. mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, WAITING_FOR_DRAWN_TIMEOUT); 最后我们再看看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函数。cpp view plain copy 在CODE上查看代码片派生到我的代码片Override public void waitForAllWindowsDrawn(Runnable callback, long timeout) synchronized (mWindowMap) mWaitingForDrawnCallback = callback;/回调保存在mWaitingForDrawnCallback final WindowList windows = getDefaultWindowListLocked(); for (int winNdx = windows.size() - 1; winNdx = 0; -winNdx) final WindowState win = windows.get(winNdx); final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs); Slog.i(TAG,In the function waitForAllWindowsDrawn); if (win.isVisibleLw() & (win.mAppToken != null | isForceHiding) Slog.i(TAG,In the function win.isVisibleLw(); win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING; / Force add to mResizingWindows. win.mLastContentInsets.set(-1, -1, -1, -1); mWaitingForDrawn.add(win); / No need to wait for the windows below Keyguard. if (isForceHiding) break; requestTraversalLocked(); mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT); if (mWaitingForDrawn.isEmpty() callback.run(); Slog.i(TAG,In the function mWaitingForDrawn.isEmpty(); else mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout); checkDrawnWindowsLocked(); Slog.i(TAG,In the function checkDrawnWindowsLocked(); 我们先来看下checkDrawnWindowsLocked函数,这个函数。遍历之前加入的mWaitingForDrawn(要显示的窗口),这个时候我们把已经去除的,不需要显示的,没有surface的窗口从mWaitingForDrawn去除,还有已经绘制好的也去除。然后再当mWaitingForDrawn为空时,就发送ALL_WINDOWS_DRAWN消息。cpp view plain copy 在CODE上查看代码片派生到我的代码片void checkDrawnWindowsLocked() if (mWaitingForDrawn.isEmpty() | mWaitingForDrawnCallback = null) return; for (int j = mWaitingForDrawn.size() - 1; j = 0; j-) WindowState win = mWaitingForDrawn.get(j); if (win.mRemoved | !win.mHasSurface | !win.mPolicyVisibility) / Window has been removed or hidden; no draw will now happen, so stop waiting. if (DEBUG_SCREEN_ON) Slog.w(TAG, Aborted waiting for drawn: + win); mWaitingForDrawn.remove(win); else if (win.hasDrawnLw() / Window is w drawn (and shown). if (DEBUG_SCREEN_ON) Slog.d(TAG, Window drawn win= + win); mWaitingForDrawn.remove(win); if (mWaitingForDrawn.isEmpty() if (DEBUG_SCREEN_ON) Slog.d(TAG, All windows drawn!); mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT); mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN); ALL_WINDOWS_DRAWN消息的处理就是清除mWaitingForDrawnCallback ,然后调用回调。cpp view plain copy 在CODE上查看代码片派生到我的代码片case ALL_WINDOWS_DRAWN: Runnable callback; synchronized (mWindowMap) callback = mWaitingForDrawnCallback; mWaitingForDrawnCallback = null; if (callback != null) callback.run(); 还有当我们调用waitForAllWindowsDrawn一般都是有需要显示的窗口,但是我们直接调用checkDrawnWindowsLocked函数,发现有的窗口还没绘制完成。那么我们就要等,会在刷新的核心函数中performLayoutAndPlaceSurfacesLockedInner有如下代码,这个时候如果之前还没绘制完成的窗口,绘制好了。会再调用checkDrawnWindowsLocked函数,如果mWaitingForDrawn中的窗口绘制好了,会在mWaitingForDrawn中去除这个窗口。然后mWaitingForDrawn为空了,之后会发送ALL_WINDOWS_DRAWN消息,还调用mWaitingForDrawnCallback回调函数。cpp view plain copy 在CODE上查看代码片派生到我的代码片if (mWaitingForDrawnCallback != null | (mInnerFields.mOrientationChangeComplete & !defaultDisplay.layoutNeeded & !mInnerFields.mUpdateRotation) checkDrawnWindowsLocked(); 当然如果我们之前没有把mWaitingForDrawn中的窗口清空,最后在WAITING_FOR_DRAWN_TIMEOUT(这里是1秒)时间到了也会调用回调的。cpp view plain copy 在CODE上查看代码片派生到我的代码片case WAITING_FOR_DRAWN_TIMEOUT: Runnable callback = null; synchronized (mWindowMap) Slog.w(TAG, Timeout waiting for drawn: undrawn= + mWaitingForDrawn); mWaitingForDrawn.clear(); callback = mWaitingForDrawnCallback; mWaitingForDrawnCallback = null; if (callback != null) callback.run(); break; PhoneWindowManager窗口绘制完成的回调函数那下面我们就要继续看PhoneWindowManager中窗口绘制完成之后的回调函数。代码如下就是发送了一个消息。cpp view plain copy 在CODE上查看代码片派生到我的代码片final Runnable mWindowManagerDrawCallback = new Runnable() Override public void run() if (DEBUG_WAKEUP) Slog.i(TAG, All windows ready for display!); mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE); ; 我们来看这个消息的处理cpp view plain copy 在CODE上查看代码片派生到我的代码片case MSG_WINDOW_MANAGER_DRAWN_COMPLETE: if (DEBUG_WAKEUP) Slog.w(TAG, Setting mWindowManagerDrawComplete); finishWindowsDrawn(); break; finishWindowsDrawn就是把mWindowManagerDrawComplete 置为true,然后调用finishScreenTurningOn函数。cpp view plain copy 在CODE上查看代码片派生到我的代码片private void finishWindowsDrawn() synchronized (mLock) if (!mScreenOnEarly | mWindowManagerDrawComplete) return; / Screen is not turned on or we did already handle this case earlier. mWindowManagerDrawComplete = true; finishScreenTurningOn(); finishScreenTurningOn函数调用了之前在DisplayPowerControl中调用screenTurningOn传入的回调,然后再调用WMS的enableScreenIfNeeded函数。cpp view plain copy 在CODE上查看代码片派生到我的代码片private void finishScreenTurningOn() ed (mLock) updateOrientationListenerLp(); final ScreenOnListener listener; final boolean enableScreen; synchronized (mLock) if (mScreenOnFully | !mScreenOnEarly | !mWindowManagerDrawComplete | (mAwake & !mKeyguardDrawComplete) return; / spurious or not ready yet listener = mScreenOnListener; mScreenOnListener = null; mScreenOnFully = true; . if (listener != null) listener.onScreenOn(); if (enableScreen) try mWindowManager.enableScreenIfNeeded(); catch (RemoteException unhandled) 我们先分析下WMS的enableScreenIfNeeded函数,然后再看DisplayPowerControl的回调onScreenOn函数。WMS的enableScreenIfNeeded函数WMS的enableScreenIfNeeded函数就是调用了enableScreenIfNeededLocked函数cpp view plain copy 在CODE上查看代码片派生到我的代码片Override public void enableScreenIfNeeded() synchronized (mWindowMap) enableScreenIfNeededLocked(); enableScreenIfNeededLocked这个函数仅仅是保证mDisplayEnabled为true,如果为true直接结束。cpp view plain copy 在CODE上查看代码片派生到我的代码片void enableScreenIfNeededLocked() if (mDisplayEnabled) return; if (!mSystemBooted & !mShowingBootMessages) return; mH.sendEmptyMessage
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年事业单位工勤技能-湖南-湖南房管员四级(中级工)历年参考题库典型考点含答案解析
- 2025年事业单位工勤技能-湖南-湖南医技工三级(高级工)历年参考题库含答案解析
- 2025年事业单位工勤技能-湖南-湖南保安员三级(高级工)历年参考题库典型考点含答案解析
- 数字化会员服务在2025年零售行业的应用与发展研究报告
- 2025-2030中国纺纱纸锥行业应用潜力与投资盈利预测报告
- 2025年事业单位工勤技能-海南-海南铸造工一级(高级技师)历年参考题库含答案解析
- 2025年储能电池在储能电站储能系统智能化监控中的应用研究报告
- 金融行业审计智能化路径探析:2025年人工智能算法应用报告
- 2025-2030中国笔制造行业发展前景与趋势预测分析报告
- 2025-2030中国立体蓝牙耳塞市场供需现状与销售渠道规划报告
- 2025年发展对象考试题库附含答案
- 2025年兵团基层两委正职定向考录公务员试题(附答案)
- 2025年新专长针灸考试题及答案
- 高三生物一轮复习课件微专题5电子传递链化学渗透假说及逆境胁迫
- DBJ50-T-306-2024 建设工程档案编制验收标准
- 2025四川雅安荥经县国润排水有限责任公司招聘5人笔试历年参考题库附带答案详解
- 2025中国银行新疆区分行社会招聘笔试备考试题及答案解析
- 污水采样培训课件
- 药品医疗器械试题及答案
- 子宫内膜类器官构建与临床转化专家共识解读 2
- 幼师培训:如何上好一节课
评论
0/150
提交评论