PowerManagerService之自動(dòng)滅屏流程解析
前言
PowerManagerService之亮屏流程分析 歸納了亮屏/滅屏的通用流程,PowerManagerService之手動(dòng)滅屏 對(duì)手動(dòng)滅屏流程進(jìn)行了整體的分析。 本文以前兩篇文章為基礎(chǔ),來分析自動(dòng)滅屏,請(qǐng)讀者務(wù)必仔細(xì)閱讀前兩篇文章。
自動(dòng)滅屏
要想分析自動(dòng)滅屏,需得回顧下 PowerManagerService之亮屏流程分析 的亮屏邏輯的一些細(xì)節(jié)。
在亮屏的時(shí)候,會(huì)保存亮屏的時(shí)間,以及用戶行為的時(shí)間,這兩個(gè)時(shí)間用于決定用戶行為,如下
// PowerManagerService.java private void updateUserActivitySummaryLocked(long now, int dirty) { // ... for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { int groupUserActivitySummary = 0; long groupNextTimeout = 0; if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != WAKEFULNESS_ASLEEP) { final long lastUserActivityTime = mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId); final long lastUserActivityTimeNoChangeLights = mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked( groupId); // mLastWakeTime 表示上次亮屏的時(shí)間 // lastUserActivityTime 表示上次用戶行為的時(shí)間 if (lastUserActivityTime >= mLastWakeTime) { // 計(jì)算使屏幕變暗的超時(shí)時(shí)間 groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else { // ... } } // ... } // ... }
此時(shí)得到的用戶行為是 USER_ACTIVITY_SCREEN_BRIGHT,表明用戶行為是要點(diǎn)亮屏幕。
之后會(huì)向 DisplayManagerService 發(fā)起請(qǐng)求,而最終決定屏幕狀態(tài)(亮、滅、暗,等等)的請(qǐng)求策略,它的更新過程如下
int getDesiredScreenPolicyLocked(int groupId) { final int wakefulness = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId); final int wakeLockSummary = mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId); if (wakefulness == WAKEFULNESS_ASLEEP || sQuiescent) { // ... } else if (wakefulness == WAKEFULNESS_DOZING) { // ... } if (mIsVrModeEnabled) { // ... } if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0 || !mBootCompleted || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId) & USER_ACTIVITY_SCREEN_BRIGHT) != 0 || mScreenBrightnessBoostInProgress) { return DisplayPowerRequest.POLICY_BRIGHT; } // ... }
由于用戶行為是 USER_ACTIVITY_SCREEN_BRIGHT,因此策略為 DisplayPowerRequest.POLICY_BRIGHT,它最終導(dǎo)致屏幕變亮。
那么亮屏后,是如何自動(dòng)滅屏呢?
// PowerManagerService.java private void updateUserActivitySummaryLocked(long now, int dirty) { // ... for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { int groupUserActivitySummary = 0; long groupNextTimeout = 0; if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != WAKEFULNESS_ASLEEP) { final long lastUserActivityTime = mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId); final long lastUserActivityTimeNoChangeLights = mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked( groupId); if (lastUserActivityTime >= mLastWakeTime) { // 使屏幕變暗的超時(shí)時(shí)間 groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else { // ... } } // ... } // 使用屏幕變暗的超時(shí)時(shí)間,發(fā)送一個(gè)定時(shí)消息來更新用戶行為 if (hasUserActivitySummary && nextTimeout >= 0) { scheduleUserInactivityTimeout(nextTimeout); } } private void scheduleUserInactivityTimeout(long timeMs) { final Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT); msg.setAsynchronous(true); // 利用超時(shí)時(shí)間,發(fā)送一個(gè)定時(shí)消息,更新用戶行為 // 最終調(diào)用 handleUserActivityTimeout mHandler.sendMessageAtTime(msg, timeMs); } private void handleUserActivityTimeout() { // runs on handler thread synchronized (mLock) { // 標(biāo)記用戶行為需要更新 mDirty |= DIRTY_USER_ACTIVITY; // 重新更新電源狀態(tài),其實(shí)就是為了更新用戶行為 updatePowerStateLocked(); } }
從上面的代碼邏輯可以看出,當(dāng) Power 鍵亮屏后,會(huì)計(jì)算出使屏幕變暗的超時(shí)時(shí)間,然后利用這個(gè)超時(shí)時(shí)間,發(fā)送了一個(gè)定時(shí)消息,當(dāng)屏幕變暗的超時(shí)時(shí)間到了,就會(huì)再次更新用戶行為,如下
// PowerManagerService.java private void updateUserActivitySummaryLocked(long now, int dirty) { // ... for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { int groupUserActivitySummary = 0; long groupNextTimeout = 0; if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != WAKEFULNESS_ASLEEP) { final long lastUserActivityTime = mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId); final long lastUserActivityTimeNoChangeLights = mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked( groupId); if (lastUserActivityTime >= mLastWakeTime) { groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < groupNextTimeout) { // ... } else { // 計(jì)算滅屏的超時(shí)時(shí)間 groupNextTimeout = lastUserActivityTime + screenOffTimeout; if (now < groupNextTimeout) { // 進(jìn)入 DIM 時(shí)間段 // 更新用戶行為 groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; } } } // ... } // ... // 使用滅屏的超時(shí)時(shí)間,發(fā)送一個(gè)定時(shí)消息來更新用戶行為 if (hasUserActivitySummary && nextTimeout >= 0) { scheduleUserInactivityTimeout(nextTimeout); } }
此次用戶行為的更新,計(jì)算的是滅屏的超時(shí)時(shí)間,然后用戶行為更新為 USER_ACTIVITY_SCREEN_DIM,表示用戶行為要使屏幕變暗。最后利用滅屏的超時(shí)時(shí)間,發(fā)送了一個(gè)定時(shí)消息來再次更新用戶行為。
現(xiàn)在用戶行為是使屏幕變暗,再看看請(qǐng)求策略是如何更新的
int getDesiredScreenPolicyLocked(int groupId) { final int wakefulness = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId); final int wakeLockSummary = mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId); if (wakefulness == WAKEFULNESS_ASLEEP || sQuiescent) { // ... } else if (wakefulness == WAKEFULNESS_DOZING) { // ... } if (mIsVrModeEnabled) { // ... } if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0 || !mBootCompleted || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId) & USER_ACTIVITY_SCREEN_BRIGHT) != 0 || mScreenBrightnessBoostInProgress) { // ... } return DisplayPowerRequest.POLICY_DIM; }
請(qǐng)求策略更新為 DisplayPowerRequest.POLICY_DIM,最終它會(huì)使屏幕變暗。
當(dāng)滅屏的超時(shí)時(shí)間到了,我們看下再次更新用戶行為時(shí),會(huì)發(fā)生什么
// PowerManagerService.java private void updateUserActivitySummaryLocked(long now, int dirty) { // ... for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { int groupUserActivitySummary = 0; long groupNextTimeout = 0; if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != WAKEFULNESS_ASLEEP) { final long lastUserActivityTime = mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId); final long lastUserActivityTimeNoChangeLights = mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked( groupId); if (lastUserActivityTime >= mLastWakeTime) { groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else { groupNextTimeout = lastUserActivityTime + screenOffTimeout; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; } } } // 滅屏超時(shí)前,帶有 PowerManager.ON_AFTER_RELEASE 這個(gè)flag的喚醒鎖釋放,延長屏幕的亮/暗的時(shí)間 if (groupUserActivitySummary == 0 && lastUserActivityTimeNoChangeLights >= mLastWakeTime) { // ... } // 滅屏超時(shí),允許進(jìn)入屏保 if (groupUserActivitySummary == 0) { // ... } // 按鍵 KeyEvent.KEYCODE_SOFT_SLEEP 進(jìn)入屏保 if (groupUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) { // ... } // 用 AttentionDetector 重新計(jì)算超時(shí)時(shí)間,目前不分析 if ((groupUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0 && (mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId) & WAKE_LOCK_STAY_AWAKE) == 0) { // ... } // 確定是否有用戶行為 hasUserActivitySummary |= groupUserActivitySummary != 0; // 保存超時(shí)時(shí)間 if (nextTimeout == -1) { nextTimeout = groupNextTimeout; } else if (groupNextTimeout != -1) { nextTimeout = Math.min(nextTimeout, groupNextTimeout); } } // DisplayGroupPowerStateMapper 保存用戶行為 mDisplayGroupPowerStateMapper.setUserActivitySummaryLocked(groupId, groupUserActivitySummary); } final long nextProfileTimeout = getNextProfileTimeoutLocked(now); if (nextProfileTimeout > 0) { nextTimeout = Math.min(nextTimeout, nextProfileTimeout); } // 利用超時(shí)時(shí)間,發(fā)送一個(gè)定時(shí)消息 if (hasUserActivitySummary && nextTimeout >= 0) { scheduleUserInactivityTimeout(nextTimeout); } }
可以看到滅屏超時(shí)時(shí)間到了時(shí),有很多因素會(huì)再次影響用戶行為和超時(shí)時(shí)間,我們忽略這些因素,因此超時(shí)時(shí)間和用戶行為都為0。 既然沒有了用戶行為和超時(shí)時(shí)間,那么自然不會(huì)發(fā)送定時(shí)消息來更新用戶行為了,因?yàn)轳R上就要滅屏的嘛,就沒必要去定時(shí)更新用戶行為了。
此時(shí),我要提醒大家,從亮屏到自動(dòng)滅屏的過程中,此時(shí) wakefulness 還是 WAKEFULNESS_AWAKE,現(xiàn)在馬上要滅屏了,因此需要再次更新 wakefulness,這就是更新電源狀態(tài)過程中,updateWakefulnessLocked() 做的
// PowerManagerService.java private boolean updateWakefulnessLocked(int dirty) { boolean changed = false; if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE | DIRTY_DOCK_STATE | DIRTY_ATTENTIVE | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) { final long time = mClock.uptimeMillis(); for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(id) == WAKEFULNESS_AWAKE && isItBedTimeYetLocked(id)) { if (isAttentiveTimeoutExpired(id, time)) { // ... 不考慮 attentive timeout,大部分項(xiàng)目不支持 ... } else if (shouldNapAtBedTimeLocked()) { // ... 如果開啟了屏保,屏幕超時(shí)也會(huì)進(jìn)入屏保 ... } else { // 更新 wakefulness 為 WAKEFULNESS_DOZING changed = sleepDisplayGroupNoUpdateLocked(id, time, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); } } } } return changed; } private boolean isItBedTimeYetLocked(int groupId) { if (!mBootCompleted) { return false; } long now = mClock.uptimeMillis(); // 不考慮 attentive timeout,大部分項(xiàng)目不支持 if (isAttentiveTimeoutExpired(groupId, now)) { return !isBeingKeptFromInattentiveSleepLocked(groupId); } else { return !isBeingKeptAwakeLocked(groupId); } } private boolean isBeingKeptAwakeLocked(int groupId) { return mStayOn // 開發(fā)者模式中是否打開"充電常亮"功能 || mProximityPositive // 是否距離傳感器保持亮屏 || (mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId) & WAKE_LOCK_STAY_AWAKE) != 0 // 是否有喚醒鎖保持亮屏 || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId) & ( USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0 // 是否有亮屏的用戶行為 || mScreenBrightnessBoostInProgress; // 屏幕是否在亮度增強(qiáng)的過程中 }
現(xiàn)在要進(jìn)入滅屏,只要沒有因素保持屏幕長亮,那么就會(huì)更新 wakefulness 為 WAKEFULNESS_DOZING。
現(xiàn)在設(shè)備進(jìn)入了打盹狀態(tài),打盹狀態(tài)的流程不就是 PowerManagerService之手動(dòng)滅屏 分析過了嗎? 如果設(shè)備進(jìn)入打盹狀態(tài),并且能成功啟動(dòng) doze dream,就會(huì)真正進(jìn)入打盹狀態(tài),否則進(jìn)入休眠狀態(tài)。無論是設(shè)備進(jìn)入打盹狀態(tài),還是休眠狀態(tài),屏幕最終會(huì)滅。
自動(dòng)滅屏小結(jié)
自動(dòng)滅屏的原理就是利用計(jì)算出的超時(shí)時(shí)間,發(fā)送一個(gè)定時(shí)消息來更新用戶行為,必要時(shí)更新 wakefulness,也就是更新系統(tǒng)狀態(tài),從而改變請(qǐng)求的策略,最終改變了屏幕的狀態(tài)(亮、滅、暗,等等)。
延長亮屏?xí)r間
現(xiàn)在我們討論一個(gè)與自動(dòng)滅屏有關(guān)的話題,那就是延長亮屏?xí)r間
private void updateUserActivitySummaryLocked(long now, int dirty) { // ... for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { int groupUserActivitySummary = 0; long groupNextTimeout = 0; if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != WAKEFULNESS_ASLEEP) { final long lastUserActivityTime = mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId); final long lastUserActivityTimeNoChangeLights = mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked( groupId); // 1. 自動(dòng)滅屏前,用戶觸摸TP,會(huì)導(dǎo)致用戶行為時(shí)間更新,從而延長亮屏?xí)r間 if (lastUserActivityTime >= mLastWakeTime) { groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else { groupNextTimeout = lastUserActivityTime + screenOffTimeout; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; } } } // 2. 如果有更新用戶行為時(shí)帶有 PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,那么也會(huì)延長亮屏 if (groupUserActivitySummary == 0 && lastUserActivityTimeNoChangeLights >= mLastWakeTime) { // 根據(jù) lastUserActivityTimeNoChangeLights 時(shí)間點(diǎn)重新計(jì)算滅屏?xí)r間 groupNextTimeout = lastUserActivityTimeNoChangeLights + screenOffTimeout; if (now < groupNextTimeout) { final DisplayPowerRequest displayPowerRequest = mDisplayGroupPowerStateMapper.getPowerRequestLocked(groupId); if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT || displayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) { // 理論上講,屏幕超時(shí),屏幕會(huì)先變暗,然而這里處理的為何是亮屏的請(qǐng)求策略 // 這是因?yàn)?,假如沒有暗屏的時(shí)間呢? groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; } } } } mDisplayGroupPowerStateMapper.setUserActivitySummaryLocked(groupId, groupUserActivitySummary); } // ... if (hasUserActivitySummary && nextTimeout >= 0) { scheduleUserInactivityTimeout(nextTimeout); } }
可以看到,有兩種情況可以延長亮屏的時(shí)間
- 屏幕處于亮/暗時(shí),如果用戶觸摸TP,那么會(huì)更新更新用戶行為時(shí)間,從而導(dǎo)致延長亮屏的時(shí)間。特別地,如果屏幕處于暗屏狀態(tài),那么點(diǎn)擊觸摸屏,會(huì)導(dǎo)致屏幕變亮。
- 如果有更新用戶行為時(shí)帶有 PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,那么也會(huì)延長亮屏。
本文分析用戶觸摸TP導(dǎo)致的延長亮屏過程,另外一個(gè)請(qǐng)讀者自行分析。
當(dāng)用戶觸摸TP時(shí),底層Input系統(tǒng)會(huì)通過JNI調(diào)用 PowerManagerService#userActivityFromNative()
// frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) { android_server_PowerManagerService_userActivity(eventTime, eventType); } // frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) { if (gPowerManagerServiceObj) { // 調(diào)用 Java 層的 PowerManagerService#userActivityFromNative() env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.userActivityFromNative, nanoseconds_to_milliseconds(eventTime), eventType, 0); } }
// PowerManagerService.java private void userActivityFromNative(long eventTime, int event, int displayId, int flags) { userActivityInternal(displayId, eventTime, event, flags, Process.SYSTEM_UID); } private void userActivityInternal(int displayId, long eventTime, int event, int flags, int uid) { synchronized (mLock) { // ... // 更新用戶活動(dòng)時(shí)間 if (userActivityNoUpdateLocked(groupId, eventTime, event, flags, uid)) { // 更新電源狀態(tài) updatePowerStateLocked(); } } }
原來用戶觸摸TP,會(huì)更新用戶行為的時(shí)間,那么用戶行為也會(huì)發(fā)生改變
private void updateUserActivitySummaryLocked(long now, int dirty) { // ... // 先移除更新用戶行為的定時(shí)消息 mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT); // ... for (int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { int groupUserActivitySummary = 0; long groupNextTimeout = 0; if (mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != WAKEFULNESS_ASLEEP) { final long lastUserActivityTime = mDisplayGroupPowerStateMapper.getLastUserActivityTimeLocked(groupId); final long lastUserActivityTimeNoChangeLights = mDisplayGroupPowerStateMapper.getLastUserActivityTimeNoChangeLightsLocked( groupId); // 用戶觸摸TP,更新了用戶行為時(shí)間 lastUserActivityTime,因此這里重新計(jì)算超時(shí)時(shí)間 // 也就是說,延長了亮屏的時(shí)間 if (lastUserActivityTime >= mLastWakeTime) { // 重新計(jì)算暗屏的超時(shí)時(shí)間 groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < groupNextTimeout) { // 用戶行為是亮屏 groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else { // ... } } } // ... // 再次發(fā)送定時(shí)消息,更新用戶行為 if (hasUserActivitySummary && nextTimeout >= 0) { scheduleUserInactivityTimeout(nextTimeout); } }
由于用戶行為時(shí)間的更新,導(dǎo)致重新計(jì)算了暗屏的超時(shí)時(shí)間,并且用戶行為會(huì)更新為 USER_ACTIVITY_SCREEN_BRIGHT。
用戶行為的更新,也導(dǎo)致了請(qǐng)求策略的更新,如下
int getDesiredScreenPolicyLocked(int groupId) { final int wakefulness = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId); final int wakeLockSummary = mDisplayGroupPowerStateMapper.getWakeLockSummaryLocked(groupId); if (wakefulness == WAKEFULNESS_ASLEEP || sQuiescent) { // ... } else if (wakefulness == WAKEFULNESS_DOZING) { // ... } if (mIsVrModeEnabled) { // ... } if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0 || !mBootCompleted || (mDisplayGroupPowerStateMapper.getUserActivitySummaryLocked(groupId) & USER_ACTIVITY_SCREEN_BRIGHT) != 0 || mScreenBrightnessBoostInProgress) { return DisplayPowerRequest.POLICY_BRIGHT; } // ... }
可以看到,如果屏幕處于亮/暗狀態(tài),用戶觸摸TP,請(qǐng)求策略更新為 DisplayPowerRequest.POLICY_BRIGHT, 最終導(dǎo)致屏幕為亮屏狀態(tài)。
另外,重新計(jì)算出的暗屏超時(shí)時(shí)間,會(huì)被用來發(fā)送定時(shí)消息來更新用戶行為,因此就相當(dāng)于重置了屏幕超時(shí)時(shí)間。
因此,觸摸TP導(dǎo)致屏幕處于亮屏狀態(tài),并且重置了屏幕超時(shí)時(shí)間,那么就相當(dāng)于延長了亮屏的時(shí)間。
結(jié)束
如果明白了亮屏與滅屏的過程,自動(dòng)滅屏的原理就沒有那么復(fù)雜,如果讀者在閱讀本文時(shí),發(fā)現(xiàn)很多東西講的很簡(jiǎn)單,那是因?yàn)榍懊娴奈恼乱呀?jīng)分析過,所以讀者務(wù)必仔細(xì)閱讀前面兩篇文章。
以目前的三篇文章為根基,下一篇文章,我們將討論 PowerManagerService 的最后一個(gè)話題,喚醒鎖。
以上就是PowerManagerService之自動(dòng)滅屏流程解析的詳細(xì)內(nèi)容,更多關(guān)于PowerManagerService 自動(dòng)滅屏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android應(yīng)用自動(dòng)跳轉(zhuǎn)到應(yīng)用市場(chǎng)詳情頁面的方法
最近在工作中遇到一個(gè)需求,推廣部門要求實(shí)現(xiàn)應(yīng)用自動(dòng)跳轉(zhuǎn)到應(yīng)用市場(chǎng)詳情頁面,通過查找一些資料,實(shí)現(xiàn)出來了,覺得有必要整理下方便以后或者有需要的朋友們參考借鑒,下面來一起詳細(xì)看看Android應(yīng)用自動(dòng)跳轉(zhuǎn)到應(yīng)用市場(chǎng)詳情頁面的方法吧。2016-12-12flutter日期選擇器 flutter時(shí)間選擇器
這篇文章主要為大家詳細(xì)介紹了flutter日期選擇器,flutter時(shí)間選擇器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Android中App字體大小不隨系統(tǒng)改變而改變
這篇文章主要介紹了Android中App字體大小不隨系統(tǒng)改變而改變,需要的朋友可以參考下2017-04-04Android實(shí)現(xiàn)QQ新用戶注冊(cè)界面遇到問題及解決方法
這篇文章主要介紹了Android實(shí)現(xiàn)QQ新用戶注冊(cè)界面遇到問題及解決方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09Android UI控件RatingBar實(shí)現(xiàn)自定義星星評(píng)分效果
這篇文章主要為大家詳細(xì)介紹了Android UI控件RatingBar實(shí)現(xiàn)自定義星星評(píng)分效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android?內(nèi)存優(yōu)化知識(shí)點(diǎn)梳理總結(jié)
這篇文章主要介紹了Android?內(nèi)存優(yōu)化知識(shí)點(diǎn)梳理總結(jié),Android?操作系統(tǒng)給每個(gè)進(jìn)程都會(huì)分配指定額度的內(nèi)存空間,App?使用內(nèi)存來進(jìn)行快速的文件訪問交互,長時(shí)間如此便需要優(yōu)化策略,文章分享優(yōu)化知識(shí)點(diǎn)總結(jié),需要的朋友可以參考一下2022-06-06Android RenderScript實(shí)現(xiàn)高斯模糊
這篇文章主要為大家詳細(xì)介紹了Android RenderScript實(shí)現(xiàn)高斯模糊的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12