frameworks/base/libs/ui/EventHub.cpp
按電源鍵後,系統把scanCode寫入對應的裝置接點,frameworks/base/libs/ui/EventHub.cpp去讀這個裝置結點,並把scanCode通過.kl檔案對應成keyCode發送到上層
framework/base/services/java/com/android/server/KeyInputQueue.java通過jni調用framework/base/services/jni/com_android_server_KeyInputQueue.cpp調用EventHub.cpp裡的檔案。
KeyInputQueue.java進入死迴圈先執行readEvent,調用EventHub.cpp中的getEvent等待輸入。
EventHub.cpp中的getEvent進入死迴圈,執行pollres = poll(mFDs, mFDCount, -1)等待裝置結點處有資料寫入(也就是有鍵按下),當有資料寫入時執行下面的for迴圈,找出是那個fd中有內容寫入,並讀出寫入的資料res = read(mFDs[i].fd, &iev, sizeof(iev))。這裡唯讀出了TYPE和Scancode(),而不會有Keycode,硬體層只能向裝置檔案寫入Scancode,而Keycode是上層要用的,由map得到。接下來接用err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags)map出Scancode對應的Keycode和Flags。mpa是在中實現的,是在m_keys中根據scanCode找到這兩個值。而m_keys是在KeyLayoutMap.cpp這個檔案中load時,讀取kl(一般在手機的/system/usr/keylayout檔案夾下)檔案,解析出所有的scanCode對應的keyCode和flag來並加到m_keys中得到的。kl檔案中的類似宏的字元如POWER是在frameworks/base/include/ui/KeycodeLabels.h中對應出來的。
WindowManagerService.java檔案,我們找 到WindowManagerService的建構函式,(至於WindowManagerService這個類在android整個系統中的作用將是我 接下來需要研究的內容,在這裡先不做研究)
private WindowManagerService(Context context, PowerManagerService pm,
boolean haveInputMethods) {
...........................
..........................
mQueue = new KeyQ();
mInputThread = new InputDispatcherThread();
........................................
.......................................
mInputThread.start();
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
}
發現在這個建構函式裡將新起一個線程。看取的名字就應該能猜出是用來擷取使用者輸入的。KeyQ我們可以看到是派生自KeyInputQueue類的,繼續 開啟KeyInputQueue查看,可以看到在建構函式中同樣起了一個線程,而且這個線程是一個死迴圈,它會在這麼一個迴圈中不停的調用 readEvent()這麼一個函數.