PowerManagerService之亮屏流程示例分析_第1頁
PowerManagerService之亮屏流程示例分析_第2頁
PowerManagerService之亮屏流程示例分析_第3頁
PowerManagerService之亮屏流程示例分析_第4頁
PowerManagerService之亮屏流程示例分析_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第PowerManagerService之亮屏流程示例分析目錄前言Power鍵亮屏1.更新wakefulness1.1更新PMS的wakefulness1.2保存用戶行為時(shí)間1.3更新wakefulness小結(jié)2.更新電源狀態(tài)2.1更新用戶行為2.2更新顯示屏的電源狀態(tài)2.3處理屏幕狀態(tài)的更新2.4小結(jié)總結(jié)

前言

亮屏的方式有很多,其中最常用的是Power鍵亮屏,這個(gè)流程比較簡(jiǎn)單,本文希望通過分析這個(gè)流程,從而理清操作屏幕的能用流程,為后面的文章打下基礎(chǔ)。

Power鍵亮屏

本文以Power鍵亮屏為例進(jìn)行分析,它會(huì)調(diào)用PowerManagerService#wakeUp()

//PowerManagerService.java

@Override//Bindercall

publicvoidwakeUp(longeventTime,@WakeReasonintreason,Stringdetails,

StringopPackageName){

//...

try{

//只能喚醒defaultdisplaygroup下的顯示屏

wakeDisplayGroup(Display.DEFAULT_DISPLAY_GROUP,eventTime,reason,details,uid,

opPackageName,uid);

}finally{

Binder.restoreCallingIdentity(ident);

privatevoidwakeDisplayGroup(intgroupId,longeventTime,@WakeReasonintreason,

Stringdetails,intuid,StringopPackageName,intopUid){

synchronized(mLock){

//1.更新wakefulness為WAKEFULNESS_AWAKE

//包括更新PowerManagerService和DisplayGroupPowerStateMapper的wakefulness

if(wakeDisplayGroupNoUpdateLocked(groupId,eventTime,reason,details,uid,

opPackageName,opUid)){

//2.更新電源狀態(tài)

updatePowerStateLocked();

注意,PowerManagerService#wakeUp()只能操作默認(rèn)分組下的屏幕。

Android不知何時(shí)起,對(duì)多屏幕添加了一個(gè)分組功能,手機(jī)通常只有一個(gè)屏幕,它屬于默認(rèn)分組。

亮屏的過程有兩步

更新wakefulness為WAKEFULNESS_AWAKE。主要是更新PowerManagerService和DisplayGroupPowerStateMapper的wakefulness。更新電源狀態(tài)。亮屏的過程就是在這里處理的。

1.更新wakefulness

privatebooleanwakeDisplayGroupNoUpdateLocked(intgroupId,longeventTime,

@WakeReasonintreason,Stringdetails,intuid,StringopPackageName,intopUid){

//...

try{

//...

//設(shè)置wakefulness為WAKEFULNESS_AWAKE

setWakefulnessLocked(groupId,WAKEFULNESS_AWAKE,eventTime,uid,reason,opUid,

opPackageName,details);

//更新分組顯示屏的信息

mDisplayGroupPowerStateMapper.setLastPowerOnTimeLocked(groupId,eventTime);

mDisplayGroupPowerStateMapper.setPoweringOnLocked(groupId,true);

returntrue;

voidsetWakefulnessLocked(intgroupId,intwakefulness,longeventTime,intuid,intreason,

intopUid,StringopPackageName,Stringdetails){

//1.更新DisplayGroupPowerStateMapper的wakefulness

if(mDisplayGroupPowerStateMapper.setWakefulnessLocked(groupId,wakefulness)){

//displaygroupwakefulness改變了

mDirty|=DIRTY_DISPLAY_GROUP_WAKEFULNESS;

//2.更新PMS的wakefulness

//注意第一個(gè)參數(shù)取所有displaygroup的最大的wakefulness,優(yōu)先級(jí)如下

//PowerManagerInternal#WAKEFULNESS_AWAKE

//PowerManagerInternal#WAKEFULNESS_DREAMING

//PowerManagerInternal#WAKEFULNESS_DOZING

//PowerManagerInternal#WAKEFULNESS_ASLEEP

//TODO:為何PMS的wakefulness要設(shè)置為所有displaygroup的最大的wakefulness

setGlobalWakefulnessLocked(mDisplayGroupPowerStateMapper.getGlobalWakefulnessLocked(),

eventTime,reason,uid,opUid,opPackageName,details);

if(wakefulness==WAKEFULNESS_AWAKE){

//Kickuseractivitytopreventnewlyawakegroupfromtimingoutinstantly.

//3.保存用戶行為的時(shí)間

userActivityNoUpdateLocked(

groupId,eventTime,PowerManager.USER_ACTIVITY_EVENT_OTHER,0,uid);

更新wakefulness為WAKEFULNESS_AWAKE過程如下

更新DisplayGroupPowerStateMapper的wakefulness為WAKEFULNESS_AWAKE。更新PMS的wakefulness為WAKEFULNESS_AWAKE。這里還會(huì)通知其它系統(tǒng)組件,wakefulness/交互狀態(tài)改變了。詳見【1.1更新PMS的wakefulness】保存用戶行為的時(shí)間。這個(gè)時(shí)間用來決定自動(dòng)滅屏的時(shí)間。詳見【1.2保存用戶行為時(shí)間】

1.1更新PMS的wakefulness

//PowerManagerService.java

privatevoidsetGlobalWakefulnessLocked(intwakefulness,longeventTime,intreason,intuid,

intopUid,StringopPackageName,Stringdetails){

if(getWakefulnessLocked()==wakefulness){

return;

//Phase1:Handlepre-wakefulnesschangebookkeeping.

finalStringtraceMethodName;

switch(wakefulness){

//...

caseWAKEFULNESS_AWAKE:

//保存喚醒設(shè)備的時(shí)間

//這個(gè)時(shí)間,后面在更新用戶行為的時(shí)候會(huì)用到

mLastWakeTime=eventTime;

mLastWakeReason=reason;

break;

//...

try{

//Phase2:Handlewakefulnesschangeandbookkeeping.

//Underlock,invalidatebeforesetensurescacheswon'treturnstalevalues.

mInjector.invalidateIsInteractiveCaches();

//更新PMS的wakefulness相關(guān)變量

mWakefulnessRaw=wakefulness;

mWakefulnessChanging=true;

//mDirty設(shè)置DIRTY_WAKEFULNESS,表示PMS的wakefulness改變了

mDirty|=DIRTY_WAKEFULNESS;

mDozeStartInProgress=(getWakefulnessLocked()==WAKEFULNESS_DOZING);

//通知其它組件,wakefulness改變或者交互狀態(tài)改變

if(mNotifier!=null){

mNotifier.onWakefulnessChangeStarted(wakefulness,reason,eventTime);

mAttentionDetector.onWakefulnessChangeStarted(wakefulness);

//Phase3:Handlepost-wakefulnesschangebookkeeping.

switch(wakefulness){

caseWAKEFULNESS_AWAKE:

//記錄并檢測(cè)是否有權(quán)限

mNotifier.onWakeUp(reason,details,uid,opPackageName,opUid);

if(sQuiescent){

mDirty|=DIRTY_QUIESCENT;

break;

//...

}finally{

Trace.traceEnd(Trace.TRACE_TAG_POWER);

根據(jù)英文注釋,更新PMS的wakefulness過程分為三個(gè)階段,最主要的是在第二個(gè)階段,更新wakefulness相關(guān)變量,然后Notifier通知其它組件并發(fā)送亮屏通知,過程如下,大家看一下就行,這不是重點(diǎn)。

//Notifier.java

publicvoidonWakefulnessChangeStarted(finalintwakefulness,intreason,longeventTime){

//判斷新的wakefulness是否是交互狀態(tài)

//WAKEFULNESS_AWAKE是可交互狀態(tài)

finalbooleaninteractive=PowerManagerInternal.isInteractive(wakefulness);

//1.通知AMSwakefulness改變了

mHandler.post(newRunnable(){

@Override

publicvoidrun(){

mActivityManagerInternal.onWakefulnessChanged(wakefulness);

//2.處理交互狀態(tài)改變

//Handleanyearlyinteractivestatechanges.

//Finishpendingincompleteonesfromapreviouscycle.

//處理早期交互狀態(tài)改變

if(mInteractive!=interactive){

//Finishuplatebehaviorsifneeded.

//mInteractiveChanging為true,表示上一次的處理流程還沒有執(zhí)行完

//這里會(huì)先執(zhí)行上一次的流程

if(mInteractiveChanging){

handleLateInteractiveChange();

//2.1更新系統(tǒng)組件的交互狀態(tài)

//Startinputassoonaswestartwakinguporgoingtosleep.

mInputManagerInternal.setInteractive(interactive);

mInputMethodManagerInternal.setInteractive(interactive);

//...

//Handleearlybehaviors.

//2.2更新關(guān)于交互狀態(tài)的變量

mInteractive=interactive;

mInteractiveChangeReason=reason;

mInteractiveChangeStartTime=eventTime;

//交互狀態(tài)正在改變

mInteractiveChanging=true;

//2.3處理早期的交互狀態(tài)改變?nèi)蝿?wù)

handleEarlyInteractiveChange();

privatevoidhandleEarlyInteractiveChange(){

synchronized(mLock){

if(mInteractive){

//通知PhoneWindowManager,PhoneWindowManager再通知SystemUIkeyguard

mHandler.post(()-mPolicy.startedWakingUp(mInteractiveChangeReason));

//發(fā)送亮屏廣播

mPendingInteractiveState=INTERACTIVE_STATE_AWAKE;

mPendingWakeUpBroadcast=true;

updatePendingBroadcastLocked();

}else{

//...

1.2保存用戶行為時(shí)間

//PowerManagerService.java

privatebooleanuserActivityNoUpdateLocked(intgroupId,longeventTime,intevent,intflags,

intuid){

if(eventTimemLastSleepTime||eventTimemLastWakeTime||!mSystemReady){

returnfalse;

Trace.traceBegin(Trace.TRACE_TAG_POWER,"userActivity");

try{

if(eventTimemLastInteractivePowerHintTime){

setPowerBoostInternal(Boost.INTERACTION,0);

mLastInteractivePowerHintTime=eventTime;

//1.通知系統(tǒng)組件,有用戶行為發(fā)生

mNotifier.onUserActivity(event,uid);

mAttentionDetector.onUserActivity(eventTime,event);

if(mUserInactiveOverrideFromWindowManager){

mUserInactiveOverrideFromWindowManager=false;

mOverriddenTimeout=-1;

finalintwakefulness=mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);

if(wakefulness==WAKEFULNESS_ASLEEP

||wakefulness==WAKEFULNESS_DOZING

||(flagsPowerManager.USER_ACTIVITY_FLAG_INDIRECT)!=0){

returnfalse;

maybeUpdateForegroundProfileLastActivityLocked(eventTime);

if((flagsPowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS)!=0){

//這里處理延長(zhǎng)亮屏的時(shí)間的邏輯...

}else{

if(eventTimemDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(

groupId)){

//2.保存用戶活動(dòng)時(shí)間

mDisplayGroupPowerStateMapper.setLastUserActivityTimeLocked(groupId,eventTime);

//3.mDirty設(shè)置DIRTY_USER_ACTIVITY標(biāo)志位,

//表示用戶活動(dòng)有更新

mDirty|=DIRTY_USER_ACTIVITY;

if(event==PowerManager.USER_ACTIVITY_EVENT_BUTTON){

mDirty|=DIRTY_QUIESCENT;

returntrue;

}finally{

Trace.traceEnd(Trace.TRACE_TAG_POWER);

returnfalse;

PMS更新用戶行為的過程

通過Notifier通知其它組件有用戶行為。DisplayGroupPowerStateMapper保存用戶行為的時(shí)間。這個(gè)時(shí)間會(huì)用于決定自動(dòng)滅屏的時(shí)間。mDirty設(shè)置DIRTY_USER_ACTIVITY標(biāo)志位,表示用戶活動(dòng)有更新,后面更新電源狀態(tài)會(huì)用到。

簡(jiǎn)單看下第一步的過程,如下

privatevoidsendUserActivity(intevent){

synchronized(mLock){

if(!mUserActivityPending){

return;

mUserActivityPending=false;

//這里暫時(shí)不知道做了什么

TelephonyManagertm=mContext.getSystemService(TelephonyManager.class);

tm.notifyUserActivity();

//PhoneWindowManger會(huì)通知SystemUI

mPolicy.userActivity();

//如果FaceDownDetector正在執(zhí)行翻轉(zhuǎn)滅屏任務(wù),此時(shí)有用戶行為,取消這個(gè)任務(wù)

mFaceDownDetector.userActivity(event);

1.3更新wakefulness小結(jié)

通過上面的分析,我們應(yīng)該看到一個(gè)本質(zhì),更新wakefulness流程大致如下

更新DisplayGroupPowerStateMapper的wakefulness,mDirty設(shè)置標(biāo)志位DIRTY_DISPLAY_GROUP_WAKEFULNESS。更新PowerManagerService的wakefulness,mDirty設(shè)置標(biāo)志位DIRTY_WAKEFULNESS.Notifier通知其它組件wakefulness/交互狀態(tài)改變了,并發(fā)送亮屏/滅屏的廣播。

2.更新電源狀態(tài)

//PowerManagerService.java

privatevoidupdatePowerStateLocked(){

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

return;

//注意這里的技術(shù),線程可以判斷是否獲取了某個(gè)鎖

if(!Thread.holdsLock(mLock)){

Slog.wtf(TAG,"PowermanagerlockwasnotheldwhencallingupdatePowerStateLocked");

Trace.traceBegin(Trace.TRACE_TAG_POWER,"updatePowerState");

try{

//Phase0:Basicstateupdates.

//省電模式功能

updateIsPoweredLocked(mDirty);

//設(shè)置中"充電常亮功能"

updateStayOnLocked(mDirty);

//亮度增加功能

updateScreenBrightnessBoostLocked(mDirty);

//Phase1:Updatewakefulness.

//Loopbecausethewakelockanduseractivitycomputationsareinfluenced

//bychangesinwakefulness.

finallongnow=mClock.uptimeMillis();

intdirtyPhase2=0;

for(;;){

intdirtyPhase1=mDirty;

dirtyPhase2|=dirtyPhase1;

mDirty=0;

//把所有的喚醒鎖歸納到mWakeLockSummary

updateWakeLockSummaryLocked(dirtyPhase1);

//1.更新用戶行為

updateUserActivitySummaryLocked(now,dirtyPhase1);

updateAttentiveStateLocked(now,dirtyPhase1);

//決定是否進(jìn)入休眠/dream/doze狀態(tài)

//如果進(jìn)入某一種狀態(tài),會(huì)更新wakefulness,因此這里要通過循環(huán)再來更新上面的東西

if(!updateWakefulnessLocked(dirtyPhase1)){

break;

//Phase2:Lockprofilesthatbecameinactive/notkeptawake.

updateProfilesLocked(now);

//Phase3:Updatedisplaypowerstate.

//2.更新顯示屏的電源狀態(tài)

finalbooleandisplayBecameReady=updateDisplayPowerStateLocked(dirtyPhase2);

//Phase4:Updatedreamstate(dependsondisplayreadysignal).

updateDreamLocked(dirtyPhase2,displayBecameReady);

//Phase5:Sendnotifications,ifneeded.

finishWakefulnessChangeIfNeededLocked();

//Phase6:Updatesuspendblocker.

//Becausewemightreleasethelastsuspendblockerhere,weneedtomakesure

//wefinishedeverythingelsefirst!

updateSuspendBlockerLocked();

}finally{

Trace.traceEnd(Trace.TRACE_TAG_POWER);

PowerManagerService的所有功能都集中在這個(gè)函數(shù)中,但是與亮屏相關(guān)的主要有兩步

updateUserActivitySummaryLocked()更新用戶行為。這個(gè)用戶行為會(huì)決定屏幕的最終亮度。詳見【2.1更新用戶行為】updateDisplayPowerStateLocked()更新顯示屏的電源狀態(tài),它會(huì)對(duì)DisplayManagerService發(fā)起電源請(qǐng)求,從而決定屏幕屏的亮度。詳見【2.2更新顯示屏的電源狀態(tài)】

2.1更新用戶行為

//PowerManagerService.java

privatevoidupdateUserActivitySummaryLocked(longnow,intdirty){

//Updatethestatusoftheuseractivitytimeouttimer.

if((dirty(DIRTY_DISPLAY_GROUP_WAKEFULNESS|DIRTY_WAKE_LOCKS

|DIRTY_USER_ACTIVITY|DIRTY_WAKEFULNESS|DIRTY_SETTINGS))==0){

return;

mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);

//默認(rèn)為-1

finallongattentiveTimeout=getAttentiveTimeoutLocked();

//休眠超時(shí)時(shí)間,默認(rèn)為-1

finallongsleepTimeout=getSleepTimeoutLocked(attentiveTimeout);

//屏幕超時(shí)時(shí)間

longscreenOffTimeout=getScreenOffTimeoutLocked(sleepTimeout,

attentiveTimeout);

//dimduration=20%screenofftimeout

finallongscreenDimDuration=getScreenDimDurationLocked(screenOffTimeout);

screenOffTimeout=

getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout,screenDimDuration);

finalbooleanuserInactiveOverride=mUserInactiveOverrideFromWindowManager;

longnextTimeout=-1;

booleanhasUserActivitySummary=false;

//遍歷displaygroupid

for(intgroupId:mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()){

intgroupUserActivitySummary=0;

longgroupNextTimeout=0;

//注意,休眠狀態(tài)是無法決定用戶行為的

if(mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId)!=WAKEFULNESS_ASLEEP){

finallonglastUserActivityTime=

mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId);

finallonglastUserActivityTimeNoChangeLights=

mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked(

groupId);

//1.獲取用戶行為與超時(shí)時(shí)間

//上一次用戶行為的時(shí)間=上一次喚醒屏幕的時(shí)間

if(lastUserActivityTime=mLastWakeTime){

groupNextTimeout=lastUserActivityTime+screenOffTimeout-screenDimDuration;

if(nowgroupNextTimeout){//沒有到dim時(shí)間

groupUserActivitySummary=USER_ACTIVITY_SCREEN_BRIGHT;

}else{

groupNextTimeout=lastUserActivityTime+screenOffTimeout;

if(nowgroupNextTimeout){//處于dim時(shí)間段

groupUserActivitySummary=USER_ACTIVITY_SCREEN_DIM;

//超時(shí)了,但是由于釋放了某一個(gè)鎖,需要延長(zhǎng)亮屏?xí)r間

if(groupUserActivitySummary==0

lastUserActivityTimeNoChangeLights=mLastWakeTime){

//...

//一般的超時(shí)情況,

if(groupUserActivitySummary==0){

//...

//PhoneWindowManager處理KeyEvent.KEYCODE_SOFT_SLEEP時(shí),userInactiveOverride為true

//KeyEvent.KEYCODE_SOFT_SLEEP這個(gè)軟件的休眠按鍵?

if(groupUserActivitySummary!=USER_ACTIVITY_SCREEN_DREAM

userInactiveOverride){

//...

//用戶行為是點(diǎn)亮屏幕,并且WakeLock沒有保持屏幕常亮,用AttentionDetector再次計(jì)算屏幕超時(shí)時(shí)間

if((groupUserActivitySummaryUSER_ACTIVITY_SCREEN_BRIGHT)!=0

(mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId)

WAKE_LOCK_STAY_AWAKE)==0){

//...

hasUserActivitySummary|=groupUserActivitySummary!=0;

if(nextTimeout==-1){

nextTimeout=groupNextTimeout;

}elseif(groupNextTimeout!=-1){

//這里表示nextTimeout!=-1的情況,也說明有多個(gè)displaygroup的情況

//從這里可以看出,多個(gè)displaygroup的超時(shí)時(shí)間是相同的

nextTimeout=Math.min(nextTimeout,groupNextTimeout);

//2.DisplayGroupPowerStateMapper保存用戶行為

mDisplayGroupPowerStateMapper.setUserActivitySummaryLocked(groupId,

groupUserActivitySummary);

}//遍歷displaygroupid結(jié)束

finallongnextProfileTimeout=getNextProfileTimeoutLocked(now);

if(nextProfileTimeout0){

nextTimeout=Math.min(nextTimeout,nextProfileTimeout);

//3.定時(shí)更新電源狀態(tài)

//這一步?jīng)Q定自動(dòng)滅屏

if(hasUserActivitySummarynextTimeout=0){

scheduleUserInactivityTimeout(nextTimeout);

這個(gè)函數(shù)不單單是用于更新用戶行為,還更新了屏幕超時(shí)時(shí)間,并且以這個(gè)時(shí)間來定時(shí)更新電源狀態(tài),以實(shí)現(xiàn)自動(dòng)滅屏的功能。

更新用戶行為在第1步,前面分析更新wakefulness時(shí),PMS保存了喚醒的時(shí)間mLastWakeTime,以及DisplayGroupPowerStateMapper保存了用戶行為時(shí)間。因此,對(duì)于從滅屏狀態(tài)到亮屏狀態(tài)這一過程來說,用戶行為的值現(xiàn)在是USER_ACTIVITY_SCREEN_BRIGHT,表示用戶行為是亮屏。

2.2更新顯示屏的電源狀態(tài)

//PowerManagerService.java

privatebooleanupdateDisplayPowerStateLocked(intdirty){

finalbooleanoldDisplayReady=mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked();

if((dirty(DIRTY_WAKE_LOCKS|DIRTY_USER_ACTIVITY|DIRTY_WAKEFULNESS

|DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED|DIRTY_BOOT_COMPLETED

|DIRTY_SETTINGS|DIRTY_SCREEN_BRIGHTNESS_BOOST|DIRTY_VR_MODE_CHANGED|

DIRTY_QUIESCENT|DIRTY_DISPLAY_GROUP_WAKEFULNESS))!=0){

if((dirtyDIRTY_QUIESCENT)!=0){

//...

//遍歷displaygroup

for(finalintgroupId:mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()){

//1.獲取displaygroup的請(qǐng)求

finalDisplayPowerRequestdisplayPowerRequest=

mDisplayGroupPowerStateMapper.getPowerRequestLocked(groupId);

//2.更新請(qǐng)求的各種參數(shù)

//更新請(qǐng)求的策略參數(shù),所謂的策略,就是亮屏,還是滅屏,或者使屏幕變暗,等等

displayPowerRequest.policy=getDesiredScreenPolicyLocked(groupId);

//...省略更新其它請(qǐng)求參數(shù)的過程...

//3.向DisplayManagerService發(fā)起請(qǐng)求

//如果此次請(qǐng)求與上一次的請(qǐng)求不同,那么這個(gè)請(qǐng)求的處理是一個(gè)異步處理過程,此時(shí)返回false。

//否則,不用處理,直接返回true。

finalbooleanready=mDisplayManagerInternal.requestPowerState(groupId,

displayPowerRequest,mRequestWaitForNegativeProximity);

//更新DisplayGroupPowerStateMapper的ready狀態(tài)

finalbooleandisplayReadyStateChanged=

mDisplayGroupPowerStateMapper.setDisplayGroupReadyLocked(groupId,ready);

//如果異步請(qǐng)求處理完畢,DMS會(huì)回調(diào)通知PMS,PMS再更新狀態(tài)走到這里

//如果點(diǎn)亮屏幕時(shí)間過長(zhǎng),那么用log記錄下來

finalbooleanpoweringOn=

mDisplayGroupPowerStateMapper.isPoweringOnLocked(groupId);

if(readydisplayReadyStateChangedpoweringOn

mDisplayGroupPowerStateMapper.getWakefulnessLocked(

groupId)==WAKEFULNESS_AWAKE){

mDisplayGroupPowerStateMapper.setPoweringOnLocked(groupId,false);

Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER,TRACE_SCREEN_ON,groupId);

finalintlatencyMs=(int)(mClock.uptimeMillis()

-mDisplayGroupPowerStateMapper.getLastPowerOnTimeLocked(groupId));

if(latencyMs=SCREEN_ON_LATENCY_WARNING_MS){

Slog.w(TAG,"Screenontook"+latencyMs+"ms");

mRequestWaitForNegativeProximity=false;

//返回值表示是否從非ready狀態(tài)變?yōu)閞eady狀態(tài)

returnmDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked()!oldDisplayReady;

更新屏幕電源狀態(tài)的很清晰,如下

首先獲取請(qǐng)求,并更新請(qǐng)求參數(shù)。請(qǐng)求參數(shù)中,主要關(guān)心的是策略參數(shù),它決定了屏幕的狀態(tài),也就是到底是亮屏還是滅屏。向DisplayManagerService發(fā)起請(qǐng)求。注意,如果當(dāng)前的請(qǐng)求與上一次請(qǐng)求不同,那么處理過程是異步的,并且返回的ready狀態(tài)為false。否則,處理過程是同步的,返回的ready為true。

我們來看下如何更新請(qǐng)求的策略

//PowerManagerService.java

intgetDesiredScreenPolicyLocked(intgroupId){

finalintwakefulness=mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);

finalintwakeLockSummary=mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId);

if(wakefulness==WAKEFULNESS_ASLEEP||sQuiescent){

returnDisplayPowerRequest.POLICY_OFF;

}elseif(wakefulness==WAKEFULNESS_DOZING){

//...

if(mIsVrModeEnabled){

returnDisplayPowerRequest.POLICY_VR;

//由于此時(shí)的UserActivity為USER_ACTIVITY_SCREEN_BRIGHT,因此策略為DisplayPowerRequest.POLICY_BRIGHT

if((wakeLockSummaryWAKE_LOCK_SCREEN_BRIGHT)!=0

||!mBootCompleted

||(mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId)

USER_ACTIVITY_SCREEN_BRIGHT)!=0

||mScreenBrightnessBoostInProgress){

returnDisplayPowerRequest.POLICY_BRIGHT;

returnDisplayPowerRequest.POLICY_DIM;

我們剛才分析的用戶行為是USER_ACTIVITY_SCREEN_BRIGHT,因此策略最終為DisplayPowerRequest.POLICY_BRIGHT。當(dāng)向DisplayManagerService發(fā)起請(qǐng)求時(shí),最終會(huì)導(dǎo)致屏幕點(diǎn)亮。

2.3處理屏幕狀態(tài)的更新

前面我們剛提到過,處理屏幕請(qǐng)求的過程可能是一個(gè)異步,也可能是一個(gè)同步。如果從滅屏到亮屏,這個(gè)過程一定是一個(gè)異步的,那么PowerManagerService是如何得知DisplayManagerService已經(jīng)處理完成了呢?其實(shí)PowerManagerService向DisplayManagerService注冊(cè)過回調(diào)

//Po

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論