今天閱讀Android Q WM代碼時(shí)發(fā)現(xiàn)了一個(gè)高級的玩法,看名字就知道是通過注入方式實(shí)現(xiàn)自動為鎖區(qū)域前后添加代碼的方法关面。發(fā)現(xiàn)過程如下:
一段莫名其妙的注釋
/* Global service lock used by the package the owns this service. */
final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
/**
* It is the same instance as {@link mGlobalLock}, just declared as a type that the
* locked-region-code-injection does't recognize it. It is used to skip wrapping priority
* booster for places that are already in the scope of another booster (e.g. computing oom-adj).
*
* @see WindowManagerThreadPriorityBooster
*/
final Object mGlobalLockWithoutBoost = mGlobalLock;
每個(gè)詞都能讀懂捂齐,但合起來就似是而非的不太明白缩抡。為什么相同的鎖對象要弄出兩個(gè)引用?什么叫跳過優(yōu)先級加速器的包圍压真。搜索這兩個(gè)鎖的用法似乎也沒有特別的差異榴都。還好有進(jìn)一步提示@see WindowManagerThreadPriorityBooster
沒有地方使用的靜態(tài)方法
WindowManagerThreadPriorityBooster本身代碼比較好懂漠其,就是根據(jù)情況調(diào)整線程優(yōu)先級達(dá)到加速效果和屎。關(guān)鍵是初始化和調(diào)用它的地方:
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-10.0.0_r3/services/core/java/com/android/server/wm/WindowManagerService.java#873
static void boostPriorityForLockedSection() {
sThreadPriorityBooster.boost();
}
static void resetPriorityAfterLockedSection() {
sThreadPriorityBooster.reset();
}
從函數(shù)名稱就能猜到肯定是在作用域前后調(diào)用這兩個(gè)函數(shù)達(dá)到boost和reset的效果,燃鵝套啤,搜索這個(gè)兩個(gè)函數(shù)的調(diào)用地方潜沦,竟然沒有唆鸡?T娌臁序目?猿涨!
抓住了你的小尾巴
多虧我習(xí)慣使用OpenGrok來做項(xiàng)目代碼搜索,馬上還是發(fā)現(xiàn)了端倪
- 編譯腳本里面做貓膩
- art-profile標(biāo)記函數(shù)避免java編譯時(shí)的空檢查
真相只有一個(gè)片效,這是用來直接注入到j(luò)ava生成的字節(jié)碼中的5硪隆召调!
證據(jù)確鑿驗(yàn)證猜想
直接去看lockedregioncodeinjection的源碼,果然是個(gè)讀取字節(jié)碼然后轉(zhuǎn)換輸出的工具只嚣。具體邏輯就不深究了:
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-10.0.0_r3/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java#80
又回到最初的起點(diǎn)
final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
final Object mGlobalLockWithoutBoost = mGlobalLock;
至此就能真正讀懂開頭那段注釋了艺沼,使用locked-region-code-injection做代碼注入的目標(biāo)是WindowManagerGlobalLock册舞,也就是只對mGlobalLock的鎖區(qū)域做加速和恢復(fù)。而如果使用mGlobalLockWithoutBoost鎖就表明:
- 這段區(qū)域可能已經(jīng)被包含在mGlobalLock以經(jīng)過加速
- 這段區(qū)域有其他帶有加速的區(qū)域障般,例如AMS调鲸,看Android.bp中l(wèi)ocked-region-code-injection的參數(shù)可知
- 這段區(qū)域不需要加速