Linux/Android——Input系統之(zhī)frameworks層InputManag
發表時(shí)間:2020-10-19
發布人(rén):融晨科技
浏覽次數:52
上(shàng)一篇Linux/Android——input體系之(zhī) kernel層 與 frameworks層交互 (五) 中有介紹kernel層一下以(yǐ)及與android這(zhè)邊frameworks層之(zhī)間的(de)接洽,算是(shì)打通android 應用層與 kernel驅動層,半數個(gè)input體系的(de)進修是(shì)至關重要(yào / yāo)的(de),個(gè)中frameworks層隻是(shì)簡單記錄了(le/liǎo)幾個(gè)接入點,這(zhè)裏開端分析frameworks層的(de)細節部分。
撰寫不(bù)易,轉載需注明出(chū)處:http://blog.csdn.net/jscese/article/details/42392311
input辦事的(de)啓動:
android啓動的(de)時(shí)刻會啓動很多個(gè)service,這(zhè)個(gè)可以(yǐ)參考SystemServer.java ,會啓動InputManagerService這(zhè)個(gè)辦事:
Slog.i(TAG, "Input Manager"); inputManager = new InputManagerService(context, wmHandler); ... ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
直接看InputManagerService.java中的(de)start函數:
public void start() { Slog.i(TAG, "Starting input manager"); nativeStart(mPtr); //調用了(le/liǎo)本處所法,JNI對應的(de)cpp 在(zài)server下的(de)jni目次下 ... }
這(zhè)個(gè)牽扯到(dào)android的(de)server的(de)jni,最開端是(shì)在(zài)SystemServer中加載android_server這(zhè)個(gè)動态庫,
至于(yú)這(zhè)個(gè)動态庫的(de)編譯可參考/frameworks/base/services/jni/Android.mk中的(de)内容
所以(yǐ)在(zài)調用這(zhè)個(gè)nativeStart辦法時(shí),相幹的(de)動态庫已經加載到(dào)SystemServer的(de)過程中。
先看下這(zhè)個(gè)start函數在(zài)jni文件中的(de)實現,frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp中:
static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); //這(zhè)個(gè)NativeInputManager 是(shì)在(zài)膳绫擎InputMangerService構造的(de)時(shí)刻調用nativeInit時(shí)new出(chū)來(lái)的(de) status_t result = im->getInputManager()->start(); //這(zhè)裏是(shì)調用了(le/liǎo)NativeInputManager中的(de)InputManager中的(de)start辦法,同樣這(zhè)個(gè)InputManager是(shì)NativeInputManager構造的(de)時(shí)刻new出(chū)來(lái)的(de) if (result) { jniThrowRuntimeException(env, "Input manager could not be started."); } }
其實熟悉JNI的(de)話,我分析到(dào)這(zhè)裏,就(jiù)應當差不(bù)多了(le/liǎo)。。對于(yú)JNI 不(bù)是(shì)很懂得的(de)話可以(yǐ)參考我之(zhī)前的(de)博客:Andorid——ubuntu下的(de) NDK / JNI
看下NativeInputManager構造函數中的(de):
sp<EventHub> eventHub = new EventHub(); mInputManager = new InputManager(eventHub, this, this);
這(zhè)裏的(de)JNI部分就(jiù)不(bù)多說(shuō)了(le/liǎo),如今就(jiù)看這(zhè)個(gè)InputManager的(de)start辦法,膳绫擎提到(dào)到(dào)Android.mk,可以(yǐ)看到(dào)include了(le/liǎo)一個(gè)libinput的(de)動态庫,
而(ér)這(zhè)個(gè)動态庫的(de)路徑是(shì)在(zài)/frameworks/base/services/input下,這(zhè)就(jiù)清楚明潦攀啦.此目次下有InputManager.cpp . EventHub.cpp等
直接看start:
status_t InputManager::start() { status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY); //這(zhè)個(gè)mDispatcherThread是(shì)在(zài)InputManager構造函數裏調用initialize初始化,這(zhè)裏很明顯啓動了(le/liǎo)這(zhè)個(gè)名爲(wéi / wèi)InputDispatcher的(de)線程 if (result) { ALOGE("Could not start InputDispatcher thread due to error %d.", result); return result; } result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY); //同上(shàng),開啓線程 if (result) { ALOGE("Could not start InputReader thread due to error %d.", result); mDispatcherThread->requestExit(); return result; } return OK; }
到(dào)這(zhè)裏算是(shì)看到(dào)真面貌的(de)感到(dào),看這(zhè)兩個(gè)線程,字面意思,一個(gè)是(shì)分發給input事宜給當前的(de)activity的(de),一個(gè)是(shì)攫取大(dà)年夜基層發上(shàng)來(lái)的(de)input事宜的(de)
InputDispatcher分發:
大(dà)年夜膳绫擎的(de)線程啓動分析:
bool InputDispatcherThread::threadLoop() { mDispatcher->dispatchOnce(); return true; }調用分發一次的(de)函數:
void InputDispatcher::dispatchOnce() { nsecs_t nextWakeupTime = LONG_LONG_MAX; { // acquire lock AutoMutex _l(mLock); mDispatcherIsAliveCondition.broadcast(); // Run a dispatch loop if there are no pending commands. // The dispatch loop might enqueue commands to run afterwards. if (!haveCommandsLocked()) { //如不(bù)雅有緩存的(de)敕令就(jiù)調用下面的(de)runCommand去履行,沒有的(de)話這(zhè)裏去檢查是(shì)否有新的(de)input事宜,這(zhè)裏定義一個(gè)喚醒時(shí)光┞菲握 dispatchOnceInnerLocked(&nextWakeupTime); } // Run all pending commands if there are any. // If any commands were run then force the next poll to wake up immediately. if (runCommandsLockedInterruptible()) { nextWakeupTime = LONG_LONG_MIN; } } // release lock // Wait for callback or timeout or wake. (make sure we round up, not down) nsecs_t currentTime = now(); int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime); mLooper->pollOnce(timeoutMillis); //履行膳绫擎一次分發之(zhī)後,就(jiù)進入了(le/liǎo)loop,這(zhè)個(gè)loop會持續的(de)檢測對應的(de)管道(dào)中是(shì)否有内容可讀,而(ér)别的(de)一個(gè)線程InputReader 攫取到(dào)input事宜之(zhī)後就(jiù)會往這(zhè)個(gè)管道(dào)寫入 }
這(zhè)個(gè)是(shì)處理input事宜的(de),後續分析,先看怎麽攫取事宜.
InputReader攫取:
源碼位于(yú)frameworks/base/libs/ui/InputReader.cpp ,開啓線程如下:
bool InputReaderThread::threadLoop() { mReader->loopOnce(); return true; }
這(zhè)裏看這(zhè)個(gè)loopOnce:
void InputReader::loopOnce() { ... size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); //這(zhè)裏去獲取event事宜 ... if (count) { processEventsLocked(mEventBuffer, count); //如不(bù)雅獲取到(dào)事宜,就(jiù)處理 } ... }
可以(yǐ)看到(dào)這(zhè)裏就(jiù)到(dào)了(le/liǎo)獲取event事宜了(le/liǎo)。上(shàng)一篇中有提到(dào)!
getEvent中會一向read,直到(dào)get到(dào)event之(zhī)後,經由過程precessevent處理,最終會喚醒膳绫擎介紹到(dào)的(de)InputDispatcherThread,通知它有新的(de)事沂攀來(lái)了(le/liǎo)