




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)出兌合同范例
- 1000元租房合同范例
- 醫(yī)療數(shù)據(jù)備份與恢復(fù)策略研究
- 醫(yī)務(wù)人員法律素養(yǎng)提升與職業(yè)道德建設(shè)
- 醫(yī)療行業(yè)的大數(shù)據(jù)技術(shù)發(fā)展趨勢(shì)
- 醫(yī)療信息化驅(qū)動(dòng)電子健康記錄系統(tǒng)的革新
- vi服務(wù)合同范例
- 以區(qū)塊為驅(qū)動(dòng)力加強(qiáng)跨行業(yè)的零售供能革新實(shí)踐
- 從智慧產(chǎn)權(quán)到創(chuàng)新發(fā)展探究區(qū)塊編鏈對(duì)新興領(lǐng)域的應(yīng)用和挑戰(zhàn)
- 2025-2030年音響鋁鐵底面殼項(xiàng)目投資價(jià)值分析報(bào)告
- 2025年北京市東城區(qū)九年級(jí)初三一模英語試卷(含答案)
- 2025-2030全球及中國(guó)游戲化行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 功夫茶泡茶技巧
- 2025年高中學(xué)業(yè)水平考試政治知識(shí)點(diǎn)歸納總結(jié)(復(fù)習(xí)必背)
- 中央2025年國(guó)家民委直屬事業(yè)單位招聘48人筆試歷年參考題庫附帶答案詳解
- 2025年全國(guó)國(guó)家版圖知識(shí)競(jìng)賽試題題庫
- 魔鏡洞察-數(shù)字解密 藥食同源生意下最香的成分與賽道終版
- 十一學(xué)校小升初入學(xué)測(cè)試數(shù)學(xué)真題及詳細(xì)解答
- 2025上半年廣西現(xiàn)代物流集團(tuán)社會(huì)招聘校園招聘149人筆試參考題庫附帶答案詳解
- 出售東西合同樣本
- 2024年四川省自然資源投資集團(tuán)有限責(zé)任公司招聘筆試參考題庫附帶答案詳解
評(píng)論
0/150
提交評(píng)論