事件處理流程
1)InputManager負責讀取事件並把事件送到frameworks的java層
2)WindowManagerService裡會有一個InputMonitor類來監聽事件變化並做相應的分發處理。
3)在WindowManagerService會有一個WindowManagerPolicy來做消息攔截處理。
4)WindowManagerService會把消息發給最上面運行的窗口接收
源碼分析WindowManagerService.java主要向Android為窗口系統提供服務,把KeyEvent分發給最上層的窗口;
WindowManagerService通過InputManager提供的native接口開啟了兩個線程驅動做KeyEvent讀取和分發給WindowManagerService管理的客戶端。
mInputManager = new InputManager(context, this);
mInputManager.start();
InputManager是WindowManagerService的成員變量,主要實現了讀取RawEvent,分發事件給WindowManagerService;
InputManager.java的native代碼InputManager.cpp實現了讀取和事件分發,他初始化兩個線程
void InputManager::initialize() {
mReaderThread = new InputReaderThread(mReader);//不斷地從/dev/input/目錄下面的設備文件讀取事件
mDispatcherThread = new InputDispatcherThread(mDispatcher);//事件分發
}
InputManager通過InputManager.Callbacks類響應回調,在回調裡再調用WindowManagerService.InputMonitor來接收事件。並在WindowManagerService.InputMonitor.interceptKeyBeforeQueueing()和 interceptKeyBeforeDispatching()進行消息攔截處理。處理的代碼如下:
WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
/* Provides an opportunity for the window manager policy to intercept early key
* processing as soon as the key has been read from the device. */
public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
int policyFlags, boolean isScreenOn) {
return mPolicy.interceptKeyBeforeQueueing(whenNanos,
keyCode, down, policyFlags, isScreenOn);
}
攔截處理的執行代碼就在PhoneWindowManager.interceptKeyBeforeQueueing()方法中。詳細的請參看源碼
EventHub.cpp主要用來讀取設備文件中的RawEvent,而InputReader.cpp和InputDispatcher.cpp算是它們之間的對接層。InputReader從設備文件中讀取的是RawEvent,在交給InputDispatcher進行分發之前,它需要先把RawEvent進行轉化分類,拆分成KeyEvent、MotionEvent、TrackEvent各種類型等。
相關源代碼位置/frameworks/base/services/java/com/android/server/WindowManagerService.java(事件分發給最前面的窗口)
/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java(攔截消息的處理類)
/frameworks/base/core/java/android/view/KeyEvent.java(按鍵事件定義)
/frameworks/base/services/java/com/android/server/InputManager.Java(Java層輸入管理)
/frameworks/base/libs/ui/InputManager.cpp(native層輸入管理)
/frameworks/base/libs/ui/InputReader.cpp(事件讀取線程)
/frameworks/base/libs/ui/InputDispatcher.cpp(事件分發線程)
/frameworks/base/libs/ui/EventHub.cpp(鍵碼與鍵值轉換)