Android7.1 Kyguard介面滅屏時間分析
概述
在Android系統中,當用戶沒有操作手機一段時間後,系統會自動滅屏進入休眠狀態,從而降低手機功耗。一般情況下系統滅屏的時間由使用者在手機設定中自己進行定義是10s,30s還是1min等等。但是如果現在系統當前顯示的是鎖屏介面,不論使用者在設定中定義的螢幕超時時間是多少,此時超時時間預設都是10s。而為何在鎖屏介面螢幕超時時間都是10s,又是如何設定的呢?就是本文需要分析的問題。
系統滅屏分析
在開始本文分析之前需要先將PowerManagerService自動滅屏流程大概的梳理一下,詳細的Power流程請參考之前分析的(Android7.0 PowerManagerService亮滅屏分析)系列文件
首先從PowerManagerService的核心函式updatePowerStateLocked入手,該函式用來更新全域性電源狀態。其實在PMS中很多函式都只是對一些必須的屬性進行賦值,大部分最終都會呼叫到updatePowerStateLocked函式中進行功能執行,其中更新電源狀態主要依據就是變數mDirty。mDirty就是用來記錄power state的變化的標記位,這樣的狀態變化在系統中一共定義了12個,每一個狀態對應一個固定的數字,都是2的倍數。這樣,若有多個狀態一塊變化,進行按位取或這樣結果既是唯一的,又能準確標記出各個狀態的變化。
在updatePowerStateLocked
使用下面圖例有助於快速理解,通過螢幕超時時間,上一次使用者事件以及dim時長與當前的時間進行對比,從而來計算此時螢幕的狀態,是高亮,DIM還是滅屏狀態。如果計算出下次螢幕的超時時間後,傳送一個Handler訊息,到了超時時間螢幕就會熄滅。
所以螢幕的超時時間就決定了何時滅屏,此時就要分析一下screenOffTimeout是如何獲得的。
獲取螢幕超時時間
獲取螢幕超時時間是在PowerManagerService中的getScreenOffTimeoutLocked函式中獲取的。
根據程式碼可以看出首先會將mScreenOffTimeoutSetting的值賦值給timeout。mScreenOffTimeoutSetting的值就是在systemReady完成後更新Setting資料庫,從資料庫中獲取到的,也就是使用者在setting中自定義的超時時間。
下面可能會有四種情況導致在設定中定義的螢幕超時時間不起作用。
1.管理員強制設定超時時間
2.WindowManager重新設定超時時間
3.sleepTimeout大於等於零
在resource中配置的config_minimumScreenOffTimeout比Setting中定義的值大。
當顯示鎖屏介面時就是採用的第二種情況WindowManager重新設定超時時間為mUserActivityTimeoutOverrideFromWindowManager。該值是呼叫Power介面setUserActivityTimeoutOverrideFromWindowManager設定的。
WMS呼叫Power設定超時間
在亮屏的時候需要對StatusBar進行繪製,繪製動作在ViewRootImpl的draw函式中,當繪製完成後通過Session.java呼叫到WMS中結束繪製,經過一系列函式呼叫在handleNotObscuredLocked函式中將StatusBar中的超時時間賦值給mUserActivityTimeout。
根據函式看出只有w.mHasSurface與canBeSeen都為true才可以繼續向下執行。canBeSeen的值是在WindowState中獲取的
所以只有windows繪製完成canBeSeen才可能是true,也就是StatusBar繪製完成後handleNotObscuredLocked函式才可以向下執行。並且StatusBar中的引數userActivityTimout的值大於等於0才可以賦值給mUserActivityTimeout。之後呼叫Power的setUserActivityTimeoutOverrideFromWindowManager介面講mUserActivityTimeout傳遞給PowerManagerService。
下面繼續分析的StatusBar中的userActivityTimout是如何設定的?設定的值又是多少?
StatusBar設定超時時間
當開機第一次顯示keyguard或者滅屏reset keyguard的時候StatusBarWindowManager會呼叫applyUserActivityTimeout函式進行設定userActivityTimout。
如果此時StatusBar狀態為keyguard,並且keyguard正在顯示沒有被阻塞,就會將AWAKE_INTERVAL_DEFAULT_MS賦值給userActivityTimout。
AWAKE_INTERVAL_DEFAULT_MS預設值為10s,也就是說在keyguard介面預設超時時間為10s,如果需要延長在keyguard介面滅屏時間,只需要修改這個值就可以了。