Android6.0 浜睆鐏睆娴佺▼(DisplayPowerController銆乄MS)(涓)WMS缁樺埗 - 鐧惧害鏂囧簱 联系客服

发布时间 : 星期三 文章Android6.0 浜睆鐏睆娴佺▼(DisplayPowerController銆乄MS)(涓)WMS缁樺埗 - 鐧惧害鏂囧簱更新完毕开始阅读c58aba1917fc700abb68a98271fe910ef12dae9d

mKeyguardDrawComplete = false;

mWindowManagerDrawComplete = false;

mScreenOnListener = screenOnListener;//屏幕点亮后的回调

if (mKeyguardDelegate != null) {

if (DEBUG_WAKEUP) Slog.d(TAG,

\ mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);

mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);

mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); } else {

if (DEBUG_WAKEUP) Slog.d(TAG,

\ 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, \ 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, \ finishKeyguardDrawn(); break;

case MSG_KEYGUARD_DRAWN_TIMEOUT:

Slog.w(TAG, \ 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,\ if (win.isVisibleLw()

&& (win.mAppToken != null || isForceHiding)) { Slog.i(TAG,\ 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,\ } else {

mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout); checkDrawnWindowsLocked();

Slog.i(TAG,\ } }

我们先来看下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, \ mWaitingForDrawn.remove(win); } else if (win.hasDrawnLw()) {

// Window is nowww.sm136.comw drawn (and shown).

if (DEBUG_SCREEN_ON) Slog.d(TAG, \ mWaitingForDrawn.remove(win); } }

if (mWaitingForDrawn.isEmpty()) {

if (DEBUG_SCREEN_ON) Slog.d(TAG, \ 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, \ mWaitingForDrawn.clear();

callback = mWaitingForDrawnCallback; mWaitingForDrawnCallback = null; }

if (callback != null) {