日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 7.0 解锁亮屏,Android7.0亮屏流程分析

發布時間:2024/9/27 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 7.0 解锁亮屏,Android7.0亮屏流程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

亮屏的本質是改變屏幕的電源狀態,經過一系列的調用會來到PowerManagerService中的updatePowerStateLocked()

1.PowerManagerService到DisplayPowerController

private void updatePowerStateLocked() {

if (!mSystemReady || mDirty == 0) {

return;

}

if (!Thread.holdsLock(mLock)) {

Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");

}

try {

// Phase 0: Basic state updates.

updateIsPoweredLocked(mDirty);

updateStayOnLocked(mDirty);

updateScreenBrightnessBoostLocked(mDirty);

// Phase 1: Update wakefulness.

// Loop because the wake lock and user activity computations are influenced

// by changes in wakefulness.

final long now = SystemClock.uptimeMillis();

int dirtyPhase2 = 0;

for (;;) {

int dirtyPhase1 = mDirty;

dirtyPhase2 |= dirtyPhase1;

mDirty = 0;

updateWakeLockSummaryLocked(dirtyPhase1);

updateUserActivitySummaryLocked(now, dirtyPhase1);

if (!updateWakefulnessLocked(dirtyPhase1)) {

break;

}

}

// Phase 2: Update display power state.

boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);

// Phase 3: Update dream state (depends on display ready signal).

updateDreamLocked(dirtyPhase2, displayBecameReady);

// Phase 4: Send notifications, if needed.

finishWakefulnessChangeIfNeededLocked();

// Phase 5: Update suspend blocker.

// Because we might release the last suspend blocker here, we need to make sure

// we finished everything else first!

updateSuspendBlockerLocked();

} finally {}

}

然后經過函數updateDisplayPowerStateLocked來到DisplayPowerController的requestPowerState函數

public boolean requestPowerState(DisplayPowerRequest request,

boolean waitForNegativeProximity) {

synchronized (mLock) {

boolean changed = false;

if (waitForNegativeProximity

&& !mPendingWaitForNegativeProximityLocked) {

mPendingWaitForNegativeProximityLocked = true;

changed = true;

}

if (mPendingRequestLocked == null) {

mPendingRequestLocked = new DisplayPowerRequest(request);

changed = true;

} else if (!mPendingRequestLocked.equals(request)) {

mPendingRequestLocked.copyFrom(request);

changed = true;

}

if (changed) {

mDisplayReadyLocked = false;

}

if (changed && !mPendingRequestChangedLocked) {

mPendingRequestChangedLocked = true;

sendUpdatePowerStateLocked();

}

return mDisplayReadyLocked;

}

}

再次經過sendUpdatePowerStateLocked以及handler+meesage的消息,進入如下的switch結構

private final class DisplayControllerHandler extends Handler {

public DisplayControllerHandler(Looper looper) {

super(looper, null, true /*async*/);

}

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MSG_UPDATE_POWER_STATE:

updatePowerState();

break;

case MSG_PROXIMITY_SENSOR_DEBOUNCED:

debounceProximitySensor();

break;

case MSG_SCREEN_ON_UNBLOCKED:

if (mPendingScreenOnUnblocker == msg.obj) {

unblockScreenOn();

updatePowerState();

}

break;

}

}

}

2.DisplayPowerController中的block機制

block的機制的存在是為了保證在屏幕亮時所有工作都已經準備好(如屏幕完成上電以及所有窗口繪制完成),所以前后需要執行兩次的updatePowerState()才會使屏幕真正的亮起來,從PMS傳遞過來的消息會先走到MSG_UPDATE_POWER_STATE執行第一次updatePowerState(),其核心是走到animateScreenStateChange()

private void animateScreenStateChange(int target, boolean performScreenOffTransition) {

// If there is already an animation in progress, don't interfere with it.

if (mColorFadeOnAnimator.isStarted()

|| mColorFadeOffAnimator.isStarted()) {

if (target != Display.STATE_ON) {

return;

}

// If display state changed to on, proceed and stop the color fade and turn screen on.

mPendingScreenOff = false;

}

// If we were in the process of turning off the screen but didn't 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.

if (mScreenBrightnessRampAnimator.isAnimating()

&& mPowerState.getScreenState() == Display.STATE_ON) {

return;

}

// Set screen state.

if (!setScreenState(Display.STATE_DOZE)) {

return; // screen on blocked

}

// Dismiss the black surface without fanfare.

mPowerState.setColorFadeLevel(1.0f);

mPowerState.dismissColorFade();

} 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.

if (mScreenBrightnessRampAnimator.isAnimating()

&& mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {

return;

}

// If not already suspending, temporarily set the state to doze until the

// screen on is unblocked, then suspend.

if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {

if (!setScreenState(Display.STATE_DOZE)) {

return; // screen on blocked

}

setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block

}

// Dismiss the black surface without fanfare.

mPowerState.setColorFadeLevel(1.0f);

mPowerState.dismissColorFade();

} 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();

}

}

}

mColorFadeOnAnimator與亮屏動畫相關,默認是關閉的,這里不討論,對于亮屏來說target == Display.STATE_ON為true,接著看函數setScreenState

private boolean setScreenState(int state) {

if (mPowerState.getScreenState() != state) {

final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);

mPowerState.setScreenState(state);

// Tell battery stats about the transition.

try {

mBatteryStats.noteScreenState(state);

} catch (RemoteException ex) {

// same process

}

}

// Tell the window manager policy when the screen is turned off or on unless it's 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();

} 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);

}

// Return true if the screen isn't blocked.

return mPendingScreenOnUnblocker == null;

}

2.1blockScreenOn

其中,mPowerState.setScreenState(state)與屏幕上電有關,這個放在本篇后面講,對于第一次updatePowerState,屏幕還未上電,即mPowerState.getColorFadeLevel() == 0.0f結果為true,執行blockScreenOn()

private void blockScreenOn() {

if (mPendingScreenOnUnblocker == null) {

Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);

mPendingScreenOnUnblocker = new ScreenOnUnblocker();

mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();

Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");

}

}

blockscreenon的實質是new一個ScreenOnUnblocker對象,這個對象直到unblockscreen才會置為空,以此來實現block機制

2.2回調WMS

setScreenState在執行blockScreenOn之后會執行這一段話

mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);

WindowManagerPolicy的實現是PhoneWindowManager,所以繼續看相關代碼

@Override

public void screenTurningOn(final ScreenOnListener screenOnListener) {

updateScreenOffSleepToken(false);

synchronized (mLock) {

mScreenOnEarly = true;

mScreenOnFully = false;

mKeyguardDrawComplete = false;

mWindowManagerDrawComplete = false;

mScreenOnListener = screenOnListener;

if (mKeyguardDelegate != null) {

mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);

mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);

mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);

} else {

finishKeyguardDrawn();

}

}

}

其中,mKeyguardDelegate是用來向鎖屏傳遞消息的對象,如果鎖屏存在的話,會把mKeyguardDrawnCallback傳遞到鎖屏中去,鎖屏中進行相關判斷,滿足條件則運行callback中的方法,mKeyguardDrawnCallback中的方法最終依然是執行finishKeyguardDrawn(),所以直接看這個函數

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);

}

mKeyguardDrawComplete的存在是為了防止重復調用,不過多討論,finishKeyguardDrawn最后是走到了WindowManagerInternal里面,WindowManagerInternal的實現類是WindowManagerService

2.3窗口繪制檢查

public void waitForAllWindowsDrawn(Runnable callback, long timeout) {

boolean allWindowsDrawn = false;

synchronized (mWindowMap) {

mWaitingForDrawnCallback = callback;

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);

final boolean keyguard = mPolicy.isKeyguardHostWindow(win.mAttrs);

if (win.isVisibleLw()

&& (win.mAppToken != null || isForceHiding || keyguard)) {

win.mWinAnimator.mDrawState = 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;

}

}

}

mWindowPlacerLocked.requestTraversal();

mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);

if (mWaitingForDrawn.isEmpty()) {

allWindowsDrawn = true;

} else {

mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);

checkDrawnWindowsLocked();

}

}

if (allWindowsDrawn) {

callback.run();

}

}

這個函數會檢查所有的窗口是否都繪制完全,同時啟動窗口UI刷新流程,等待繪制的窗口放在mWaitingForDrawn里面,如果內容為空則表示窗口繪制完全,否則需要繼續等待,并且還會發送一個延時1秒的message,防止窗口繪制超時導致屏幕無法亮起。

如果窗口都繪制完成,則會進入傳過來的callback的run方法,具體看一下這個傳過來的callback

final Runnable mWindowManagerDrawCallback = new Runnable() {

@Override

public void run() {

mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);

}

};

來到如下函數

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();

}

繼續看

private void finishScreenTurningOn() {

synchronized (mLock) {

// We have just finished drawing screen content. Since the orientation listener

// gets only installed when all windows are drawn, we try to install it again.

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;

// Remember the first time we draw the keyguard so we know when we're done with

// the main part of booting and can enable the screen and hide boot messages.

if (!mKeyguardDrawnOnce && mAwake) {

mKeyguardDrawnOnce = true;

enableScreen = true;

if (mBootMessageNeedsHiding) {

mBootMessageNeedsHiding = false;

hideBootMessages();

}

} else {

enableScreen = false;

}

}

if (listener != null) {

listener.onScreenOn();

}

if (enableScreen) {

try {

mWindowManager.enableScreenIfNeeded();

} catch (RemoteException unhandled) {

}

}

}

注意這里的listener,這個listener是一個ScreenOnListener對象,ScreenOnListener類的實現在DisplayPowerController中,所以通過這個listener,phoneWindowManager把窗口繪制完成的消息由傳回了DisplayPowerController

private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {

@Override

public void onScreenOn() {

Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);

msg.setAsynchronous(true);

mHandler.sendMessage(msg);

}

}

2.4unblockScreenOn

ScreenOnUnblocker中的onScreenOn方法最終會走到unblockScreenOn方法

private void unblockScreenOn() {

if (mPendingScreenOnUnblocker != null) {

mPendingScreenOnUnblocker = null;

long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;

Slog.i(TAG, "Unblocked screen on after " + delay + " ms");

Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);

}

}

并且,unblockScreenOn之后會再一次updatePowerState(),調用DisplayPowerState中的相關方法設置亮度,屏幕最終亮起來

通過unblockScreenOn方法中的log也可以得到block的總時間,一般來說,只要blockscreen前后沒有過多的消息傳遞,可以認為block時間就是亮屏時間

3.屏幕上電

在屏幕亮起來之前需要改變屏幕的電源狀態,即給屏幕上電

前面說到,在DisplayPowerController設置電源狀態的方法開頭有這么一段

private boolean setScreenState(int state) {

if (mPowerState.getScreenState() != state) {

final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);

mPowerState.setScreenState(state);

...

mPowerState是一個DisplayPowerState對象,繼續看具體的實現

public void setScreenState(int state) {

if (mScreenState != state) {

mScreenState = state;

mScreenReady = false;

scheduleScreenUpdate();

}

}

mScreenState和mScreenReady會用于狀態檢查,然后通過scheduleScreenUpdate向底層發出給屏幕上電的命令,具體的流程比較長而且復雜,不一一說明,大致的調用流程是

DisplayPowerState

-DisplayManagerService

-LocalDisplayAdapter

-SurfaceControl

-HWComposer

屏幕的上電時間與硬件的時序相關,并且是影響亮屏總時間的一個非常重要的因素,

查看屏幕的上電時間可以通過搜索trace文件中的setPowerModeInternal查看或者搜索surfaceControl的log,setPowerMode

總結

以上是生活随笔為你收集整理的android 7.0 解锁亮屏,Android7.0亮屏流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。