原創(chuàng)內(nèi)容骡送,轉(zhuǎn)載請(qǐng)注明出處,多謝配合。
上一篇分析了InputReader獲取事件過(guò)程搀绣,最終InputReader將input event放到InputDispatcher的mInboundQueue后喚醒InputDispacher。本篇就來(lái)分析下InputDispatcher的事件分發(fā)過(guò)程戳气。
一链患、InputDispatcher初始化
frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy);//創(chuàng)建InputDispatcher
...
}
frameworks/native/services/inputflinger/InputDispatcher.cpp
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) ... : {
mLooper = new Looper(false);//這里InputDispatcher新建了一個(gè)Looper
...
}
InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
}
bool InputDispatcherThread::threadLoop() {
mDispatcher->dispatchOnce();//開(kāi)始處理分發(fā)
return true;
}
二、InputDispatcher運(yùn)行
frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::dispatchOnce() {
nsecs_t nextWakeupTime = LONG_LONG_MAX;register_android_server_InputManager
...
//優(yōu)先處理Command
if (!haveCommandsLocked()) {
//這里處理input event
dispatchOnceInnerLocked(&nextWakeupTime);
}
if (runCommandsLockedInterruptible()) {
// 處理完Command瓶您,立即喚醒loop來(lái)處理input event
nextWakeupTime = LONG_LONG_MIN;
}
...
nsecs_t currentTime = now();
int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
// 這里進(jìn)入epoll_wait麻捻,
// InputReader可以用Looper::wake()喚醒InputDispacher
// 窗口也可以通過(guò)回執(zhí)event喚醒Looper
mLooper->pollOnce(timeoutMillis);
}
InputDispatcher處理的事件主要分兩種:一種是command命令(Command是mPolicy處理的具體事務(wù),這個(gè)mPolicy就是NativeInputManager呀袱,最終對(duì)應(yīng)的上層是InputManagerService)贸毕,一種是input event。每次dispatchOnce夜赵,會(huì)優(yōu)先執(zhí)行前者明棍。
這里Command一些列回調(diào)命令保存在mCommandQueue中,主要包括:
doPokeUserActivityLockedInterruptible
doNotifyANRLockedInterruptible
doInterceptKeyBeforeDispatchingLockedInterruptible
doDispatchCycleFinishedLockedInterruptible
doNotifyInputChannelBrokenLockedInterruptible
doNotifyConfigurationChangedInterruptible
再看dispatchOnceInnerLocked處理input event部分:
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
nsecs_t currentTime = now();
...
//當(dāng)事件分發(fā)的時(shí)間點(diǎn)距離該事件加入mInboundQueue的時(shí)間超過(guò)500ms,則認(rèn)為app切換過(guò)期,即
//isAppSwitchDue=true;
bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
...
if (!mPendingEvent) {
return;
}
} else {
//事件是從InboundQueue頭部取的
mPendingEvent = mInboundQueue.dequeueAtHead();
traceInboundQueueLengthLocked();
}
// Poke user activity for this event.
if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
pokeUserActivityLocked(mPendingEvent);
}
// Get ready to dispatch the event.
resetANRTimeoutsLocked(); //重置ANR 超時(shí)時(shí)間
}
// Now we have an event to dispatch.
// All events are eventually dequeued and processed this way, even if we intend to drop them.
ALOG_ASSERT(mPendingEvent != NULL);
bool done = false;
DropReason dropReason = DROP_REASON_NOT_DROPPED;
if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
dropReason = DROP_REASON_POLICY;
} else if (!mDispatchEnabled) {
dropReason = DROP_REASON_DISABLED;
}
if (mNextUnblockedEvent == mPendingEvent) {
mNextUnblockedEvent = NULL;
}
switch (mPendingEvent->type) {
…
//這里有很多類型的EventEntry type 重點(diǎn)看看key
case EventEntry::TYPE_KEY: {
KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
if (isAppSwitchDue) {
if (isAppSwitchKeyEventLocked(typedEntry)) {
resetPendingAppSwitchLocked(true);
isAppSwitchDue = false;
} else if (dropReason == DROP_REASON_NOT_DROPPED) {
dropReason = DROP_REASON_APP_SWITCH;
}
}
if (dropReason == DROP_REASON_NOT_DROPPED
&& isStaleEventLocked(currentTime, typedEntry)) {
dropReason = DROP_REASON_STALE;
}
if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
dropReason = DROP_REASON_BLOCKED;
}
//分發(fā)事件處理
done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
break;
}
...
}
//分發(fā)操作完成
if (done) {
if (dropReason != DROP_REASON_NOT_DROPPED) {
dropInboundEventLocked(mPendingEvent, dropReason);//丟棄事件
}
mLastDropReason = dropReason;
releasePendingEventLocked();//釋放當(dāng)前正在處理的事件
*nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
}
}
這個(gè)過(guò)程簡(jiǎn)單看就是從mInboundQueue頭部取出事件交給dispatchKeyLocked執(zhí)行分發(fā)處理寇僧,并重置ANR時(shí)間摊腋,以及執(zhí)行完之后根據(jù)done來(lái)做一些收尾操作。
接下來(lái)看看dispatchKeyLocked:
bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
...
//尋找焦點(diǎn)窗口inputTargets
int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime);
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked(inputTargets);
//只有injectionResult為true才會(huì)繼續(xù)往下執(zhí)行分發(fā)操作
dispatchEventLocked(currentTime, entry, inputTargets);
return true;
}
這個(gè)方法核心內(nèi)容是執(zhí)行findFocusedWindowTargetsLocked尋找焦點(diǎn)窗口inputTargets嘁傀,但是在此之前會(huì)有若干判斷有可能直接return 兴蒸。
int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
int32_t injectionResult;
String8 reason;
...
// Check permissions.
if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
goto Failed;
}
// 檢測(cè)窗口是否為更多的輸入操作而準(zhǔn)備就緒
reason = checkWindowReadyForMoreInputLocked(currentTime,
mFocusedWindowHandle, entry, "focused");
if (!reason.isEmpty()) { //如果滿足,handleTargetsNotReadyLocked會(huì)觸發(fā)anr判斷
injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime, reason.string());
goto Unresponsive;
}
// Success! Output targets.
injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
//添加目標(biāo)窗口
addWindowTargetLocked(mFocusedWindowHandle,
InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
inputTargets);
// Done.
Failed:
Unresponsive:
nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
updateDispatchStatisticsLocked(currentTime, entry,
injectionResult, timeSpentWaitingForApplication);
#if DEBUG_FOCUS
ALOGD("findFocusedWindow finished: injectionResult=%d, "
"timeSpentWaitingForApplication=%0.1fms",
injectionResult, timeSpentWaitingForApplication / 1000000.0);
#endif
return injectionResult;
}
這里主要就是添加目標(biāo)窗口细办,與目前窗口建立InputChannel連接
void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
inputTargets.push();
const InputWindowInfo* windowInfo = windowHandle->getInfo();
InputTarget& target = inputTargets.editTop();
target.inputChannel = windowInfo->inputChannel;
target.flags = targetFlags;
target.xOffset = - windowInfo->frameLeft;
target.yOffset = - windowInfo->frameTop;
target.scaleFactor = windowInfo->scaleFactor;
target.pointerIds = pointerIds;
}
將當(dāng)前聚焦窗口mFocusedWindowHandle的inputChannel傳遞到inputTargets类咧。
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("dispatchEventToCurrentInputTargets");
#endif
ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
//調(diào)用到Java層的PowerManagerService.java中的userActivityFromNative()方法. 這也是PMS中唯一的native call方法
pokeUserActivityLocked(eventEntry);
for (size_t i = 0; i < inputTargets.size(); i++) {
const InputTarget& inputTarget = inputTargets.itemAt(i);
//根據(jù)inputChannel的fd從mConnectionsByFd隊(duì)列中查詢目標(biāo)connection.
ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
if (connectionIndex >= 0) {
sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
//找到目標(biāo)連接
prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
} else {
#if DEBUG_FOCUS
ALOGD("Dropping event delivery to target with channel '%s' because it "
"is no longer registered with the input dispatcher.",
inputTarget.inputChannel->getName().string());
#endif
}
}
}
該方法主要功能是將eventEntry發(fā)送到目標(biāo)inputTargets。
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
...
enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
}
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
bool wasEmpty = connection->outboundQueue.isEmpty();
...
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, InputTarget::FLAG_DISPATCH_AS_IS);
...
if (wasEmpty && !connection->outboundQueue.isEmpty()) {
startDispatchCycleLocked(currentTime, connection);
}
}
void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget, int32_t dispatchMode) {
int32_t inputTargetFlags = inputTarget->flags;
if (!(inputTargetFlags & dispatchMode)) {
return;
}
//這里又轉(zhuǎn)了一次數(shù)據(jù)結(jié)構(gòu)蟹腾,生成新的事件, 加入connection的outbound隊(duì)列痕惋。
DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset, inputTarget->scaleFactor);
switch (eventEntry->type) {
case EventEntry::TYPE_KEY: {
KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
dispatchEntry->resolvedAction = keyEntry->action;
dispatchEntry->resolvedFlags = keyEntry->flags;
break;
}
//添加到outboundQueue隊(duì)尾
connection->outboundQueue.enqueueAtTail(dispatchEntry);
}
執(zhí)行到這里,其實(shí)等于由做了一次搬運(yùn)的工作,將InputDispatcher中mInboundQueue中的eventEntry事件取出后, 找到目標(biāo)window后,將eventEntry封裝dispatchEntry加入到connection的outbound隊(duì)列。
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection) {
while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.isEmpty()) {
DispatchEntry* dispatchEntry = connection->outboundQueue.head;
dispatchEntry->deliveryTime = currentTime;
// Publish the event.
status_t status;
EventEntry* eventEntry = dispatchEntry->eventEntry;
switch (eventEntry->type) {
case EventEntry::TYPE_KEY: {
KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
keyEntry->deviceId, keyEntry->source,
dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
keyEntry->keyCode, keyEntry->scanCode,
keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
keyEntry->eventTime);
break;
}
...
}
// Re-enqueue the event on the wait queue.
connection->outboundQueue.dequeue(dispatchEntry);
connection->waitQueue.enqueueAtTail(dispatchEntry);
}
通過(guò)InputPublisher將DispatchEntry發(fā)送給窗口娃殖,再將DispatchEntry從outboundQueue移到waitQueue里值戳。該通信過(guò)程是異步的,當(dāng)窗口處理完事件后會(huì)通過(guò)handleReceiveCallback()回調(diào)函數(shù)通知InputDispatcher炉爆。
status_t InputPublisher::publishKeyEvent(...) {
if (!seq) {
return BAD_VALUE;
}
InputMessage msg;
msg.header.type = InputMessage::TYPE_KEY;
msg.body.key.seq = seq;
msg.body.key.deviceId = deviceId;
msg.body.key.source = source;
msg.body.key.action = action;
msg.body.key.flags = flags;
msg.body.key.keyCode = keyCode;
msg.body.key.scanCode = scanCode;
msg.body.key.metaState = metaState;
msg.body.key.repeatCount = repeatCount;
msg.body.key.downTime = downTime;
msg.body.key.eventTime = eventTime;
//通過(guò)InputChannel來(lái)發(fā)送消息
return mChannel->sendMessage(&msg);
}
publishKeyEvent調(diào)用InputChanel的SendMessage()堕虹,SendMessage()再動(dòng)用socket的send()函數(shù)卧晓,將打包好的Message發(fā)送給窗口。
最后看看handleReceiveCallback回調(diào):
frameworks/native/services/inputflinger/InputDispatcher.cpp
int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
InputDispatcher* d = static_cast<InputDispatcher*>(data);
ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
nsecs_t currentTime = now();
bool gotOne = false;
status_t status;
for (;;) {
uint32_t seq;
bool handled;
//接收窗口處理完成的消息
status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
if (status) { // 讀完socket即返回WOULD_BLOCK
break;
}
// 這里post一個(gè)command
d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
gotOne = true;
}
if (gotOne) {
// 這里執(zhí)行command的handle
d->runCommandsLockedInterruptible();
if (status == WOULD_BLOCK) { // 正常流程走這里
return 1;
}
}
}
// 這里是socket鏈接出現(xiàn)異常的情況
d->unregisterInputChannelLocked(connection->inputChannel, notify);
return 0; // remove the callback
}
再看看post command
frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
...
onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
}
void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
CommandEntry* commandEntry = postCommandLocked( & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
commandEntry->connection = connection;
commandEntry->eventTime = currentTime;
commandEntry->seq = seq;
commandEntry->handled = handled;
}
frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
sp<Connection> connection = commandEntry->connection;
nsecs_t finishTime = commandEntry->eventTime;
uint32_t seq = commandEntry->seq;
bool handled = commandEntry->handled;
// Handle post-event policy actions.
DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
if (dispatchEntry) {
nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
// 如果一個(gè)dispatch周期超過(guò)2秒赴捞,將打印警告信息
if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT /* 2sec */) {
String8 msg;
msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ", connection->getWindowName(), eventDuration * 0.000001f);
dispatchEntry->eventEntry->appendDescription(msg);
ALOGI("%s", msg.string());
}
bool restartEvent;
if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
// 主要是對(duì)unhandle key的policy逼裆,這里不做分析
restartEvent = afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
} else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry, handled);
} else {
restartEvent = false;
}
if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
// 從waitQueue中將當(dāng)前entry移除
connection->waitQueue.dequeue(dispatchEntry);
traceWaitQueueLengthLocked(connection);
if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
connection->outboundQueue.enqueueAtHead(dispatchEntry);
traceOutboundQueueLengthLocked(connection);
} else {
// 釋放內(nèi)存
releaseDispatchEntryLocked(dispatchEntry);
}
}
// 如果當(dāng)前connection的outBoundQueque里還有Event,則繼續(xù)下一輪的Dispatch周期
startDispatchCycleLocked(now(), connection);
}
}
從waitQueue中將當(dāng)前DispatchEntry移除赦政,如果當(dāng)前connection的outBoundQueque里還有EventEntry胜宇,則繼續(xù)下一輪的Dispatch周期。
最后放上整體流程圖和時(shí)序圖:
簡(jiǎn)單總結(jié)下InputDispatcher分發(fā)事件流程:
1)InputReader喚醒InputDispacher執(zhí)行分發(fā)處理恢着。
InputReader主要是將EventHub中的input_event轉(zhuǎn)換成具體的EventEntry,并添加到InputDispatcher的mInboundQueue里,然后喚醒InputDispacher線程桐愉。InputDispacher線程有自己的Looper,被喚醒后會(huì)執(zhí)行dispatchOnce方法掰派,InputDispatcher處理的事件主要分兩種:一種是command命令(Command是mPolicy處理的具體事務(wù)从诲,這個(gè)mPolicy就是NativeInputManager,最終對(duì)應(yīng)的上層是InputManagerService)靡羡,一種是input event系洛。每次dispatchOnce,會(huì)優(yōu)先執(zhí)行前者略步。
2)InboundQueue隊(duì)頭取出事件描扯,匹配焦點(diǎn)窗口,傳遞eventEntry纳像。
從mInboundQueue隊(duì)列頭部取出一個(gè)事件荆烈,尋找與之匹配的焦點(diǎn)窗口的inputTargets拯勉,這里先通過(guò)InputWindowHandle找到InputWindowInfo竟趾,再找到InputChannel,最終找到Connection宫峦,每個(gè)焦點(diǎn)窗口在InputDispacher里都有一個(gè)對(duì)應(yīng)的Connection岔帽,通過(guò)這個(gè)Connection可以跟InputDispacher通信。然后會(huì)將eventEntry轉(zhuǎn)為DispatchEntry放入Connection的outboundQueue导绷。通過(guò)InputPublisher通過(guò) InputChannel::sendMessage將DispatchEntry發(fā)送給窗口犀勒,再將dispatchEntry從outboundQueue移到waitQueue里。該通信過(guò)程是異步的妥曲,也就是說(shuō)當(dāng)InputDispatcher將Input事件發(fā)送給目標(biāo)窗口后會(huì)立即返回贾费,并不會(huì)等待窗口的處理結(jié)果。
3)窗口處理完又將處理結(jié)果返回給InputDispatcher
當(dāng)窗口處理完事件后檐盟,會(huì)通過(guò)handleReceiveCallback()回調(diào)函數(shù)通知InputDispatcher褂萧。回調(diào)主要是post一個(gè)command,從waitQueue中將當(dāng)前DispatchEntry移除葵萎,如果當(dāng)前connection的outBoundQueque里還有DispatchEntry导犹,則繼續(xù)下一輪的Dispatch周期唱凯。
到這里InputDispatcher分發(fā)事件過(guò)程就介紹完了。