文章托管在gitee上 Android Notes , 同步csdn
Client处理完input事件后, 会向ims发送finish反馈信号,即向对端的server InputChannel发送反馈, server 端InputChannel被InputDispatcher所管理 .这个 *** 作通常在InputEventReceiver的finishInputEvent方法.
InputEventReceiver#finishInputEvent/// @frameworks/base/core/java/android/view/InputEventReceiver.java public final void finishInputEvent(InputEvent event, boolean handled) { if (event == null) { throw new IllegalArgumentException("event must not be null"); } // mReceiverPtr是native的NativeInputEventReceiver地址 if (mReceiverPtr == 0) { Log.w(TAG, "Attempted to finish an input event but the input event " + "receiver has already been disposed."); } else { int index = mSeqMap.indexOfKey(event.getSequenceNumber()); if (index < 0) { Log.w(TAG, "Attempted to finish an input event that is not in progress."); } else { int seq = mSeqMap.valueAt(index); mSeqMap.removeAt(index); // 调用 native 方法 nativeFinishInputEvent(mReceiverPtr, seq, handled); } } event.recycleIfNeededAfterDispatch(); }InputEventReceiver JNI函数注册表
/// @frameworks/base/core/jni/android_view_InputEventReceiver.cpp static const JNINativeMethod gMethods[] = { { "nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)J", (void*)nativeInit }, { "nativeDispose", "(J)V", (void*)nativeDispose }, { "nativeFinishInputEvent", "(JIZ)V", (void*)nativeFinishInputEvent }, { "nativeConsumeBatchedInputEvents", "(JJ)Z", (void*)nativeConsumeBatchedInputEvents }, };
从上可知 nativeFinishInputEvent方法对应的jni函数是android_view_InputEventReceiver.cpp中的nativeFinishInputEvent函数
static void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jlong receiverPtr, jint seq, jboolean handled) { spNativeInputEventReceiver::finishInputEventreceiver = reinterpret_cast (receiverPtr); // 调用NativeInputEventReceiver的finishInputEvent status_t status = receiver->finishInputEvent(seq, handled); if (status && status != DEAD_OBJECT) { String8 message; message.appendFormat("Failed to finish input event. status=%d", status); jniThrowRuntimeException(env, message.string()); } }
status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) { if (kDebugDispatchCycle) { ALOGD("channel '%s' ~ Finished input event.", getInputChannelName().c_str()); } // 通过mInputConsumer发送finish信号 status_t status = mInputConsumer.sendFinishedSignal(seq, handled); if (status) { if (status == WOULD_BLOCK) {// 此时处于阻塞状态,添加到mFinishQueue if (kDebugDispatchCycle) { ALOGD("channel '%s' ~ Could not send finished signal immediately. " "Enqueued for later.", getInputChannelName().c_str()); } Finish finish; finish.seq = seq; finish.handled = handled; mFinishQueue.add(finish); // 从0 -> 1 时设置ALOOPER_EVENT_OUTPUT=1事件监听, 当fd可写时收到相关事件,回调NativeInputEventReceiver::handleEvent, // 然后遍历mFinishQueue中的元素,取出继续发送pending的事件反馈, 所有发送完成后清除队列,并移除ALOOPER_EVENT_OUTPUT监听 if (mFinishQueue.size() == 1) { setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT); } return OK; } ALOGW("Failed to send finished signal on channel '%s'. status=%d", getInputChannelName().c_str(), status); } return status; }InputConsumer::sendFinishedSignal
status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { if (DEBUG_TRANSPORT_ACTIONS) { ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s", mChannel->getName().c_str(), seq, toString(handled)); } if (!seq) { // seq不能是0 ALOGE("Attempted to send a finished signal with sequence number 0."); return BAD_VALUE; } // 先处理 batch sequence chain // Send finished signals for the batch sequence chain first. size_t seqChainCount = mSeqChains.size(); if (seqChainCount) { uint32_t currentSeq = seq; uint32_t chainSeqs[seqChainCount]; size_t chainIndex = 0; for (size_t i = seqChainCount; i > 0; ) { i--; const SeqChain& seqChain = mSeqChains.itemAt(i); if (seqChain.seq == currentSeq) { currentSeq = seqChain.chain; chainSeqs[chainIndex++] = currentSeq; mSeqChains.removeAt(i); } } status_t status = OK; while (!status && chainIndex > 0) { chainIndex--; status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled); } if (status) { // An error occurred so at least one signal was not sent, reconstruct the chain. for (;;) { SeqChain seqChain; seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq; seqChain.chain = chainSeqs[chainIndex]; mSeqChains.push(seqChain); if (!chainIndex) break; chainIndex--; } return status; } } // Send finished signal for the last message in the batch. // 发送最后一条 return sendUnchainedFinishedSignal(seq, handled); }InputConsumer::sendUnchainedFinishedSignal
status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) { InputMessage msg; msg.header.type = InputMessage::Type::FINISHED; msg.body.finished.seq = seq; msg.body.finished.handled = handled ? 1 : 0; return mChannel->sendMessage(&msg); }InputChannel::sendMessage
status_t InputChannel::sendMessage(const InputMessage* msg) { const size_t msgLength = msg->size(); InputMessage cleanMsg; msg->getSanitizedCopy(&cleanMsg); ssize_t nWrite; do { // 调用send 函数, send a message on a socket // ssize_t send(int sockfd, const void *buf, size_t len, int flags); nWrite = ::send(mFd.get(), &cleanMsg, msgLength, MSG_DonTWAIT | MSG_NOSIGNAL); } while (nWrite == -1 && errno == EINTR); if (nWrite < 0) { // 发送的长度<0 发送失败 int error = errno; #if DEBUG_CHANNEL_MESSAGES ALOGD("channel '%s' ~ error sending message of type %d, %s", mName.c_str(), msg->header.type, strerror(error)); #endif if (error == EAGAIN || error == EWOULDBLOCK) { return WOULD_BLOCK; } if (error == EPIPE || error == ENOTCONN || error == EConNREFUSED || error == ECONNRESET) { return DEAD_OBJECT; } return -error; } if (size_t(nWrite) != msgLength) { // 发送长度和实际的不一致 #if DEBUG_CHANNEL_MESSAGES ALOGD("channel '%s' ~ error sending message type %d, send was incomplete", mName.c_str(), msg->header.type); #endif return DEAD_OBJECT; } #if DEBUG_CHANNEL_MESSAGES ALOGD("channel '%s' ~ sent message of type %d", mName.c_str(), msg->header.type); #endif return OK; }
接下来看Server端的处理.Server端通常是管理在inputDispatcher. 当收到新消息到来,会触发ims的Looper处理相关fd事件, 之后InputDispatcher::handleReceiveCallback会被回调
InputDispatcher::handleReceiveCallbackint InputDispatcher::handleReceiveCallback(int fd, int events, void* data) { InputDispatcher* d = static_castInputPublisher::receiveFinishedSignal(data); { // acquire lock std::scoped_lock _l(d->mLock); // 寻找fd对应的Connection if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) { ALOGE("Received spurious receive callback for unknown input channel. " "fd=%d, events=0x%x", fd, events); return 0; // remove the callback } bool notify; sp connection = d->mConnectionsByFd[fd]; if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) { if (!(events & ALOOPER_EVENT_INPUT)) { // 非input事件则返回 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " "events=0x%x", connection->getInputChannelName().c_str(), events); return 1; } nsecs_t currentTime = now(); bool gotOne = false; status_t status; for (;;) { uint32_t seq; bool handled; // 接收client的finish消息 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled); if (status) { break; } // 结束派发反馈的cycle, 将要执行的 *** 作封装成一个CommandEntry,添加到mCommandQueue d->finishDispatchCycleLocked(currentTime, connection, seq, handled); gotOne = true; } // gotOne为true , 则必然成功收到了client的finish消息, 执行mCommandQueue中的commands if (gotOne) { d->runCommandsLockedInterruptible(); if (status == WOULD_BLOCK) { return 1; } } notify = status != DEAD_OBJECT || !connection->monitor; if (notify) { ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d", connection->getInputChannelName().c_str(), status); } } else { // Monitor channels are never explicitly unregistered. // We do it automatically when the remote endpoint is closed so don't warn // about them. const bool stillHaveWindowHandle = d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr; notify = !connection->monitor && stillHaveWindowHandle; if (notify) { ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. " "events=0x%x", connection->getInputChannelName().c_str(), events); } } // Unregister the channel. d->unregisterInputChannelLocked(connection->inputChannel, notify); return 0; // remove the callback } // release lock }
接收来自client的finish 信息
status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) { if (DEBUG_TRANSPORT_ACTIONS) { ALOGD("channel '%s' publisher ~ receiveFinishedSignal", mChannel->getName().c_str()); } InputMessage msg; // 调用InputChannel的receiveMessage读取msg status_t result = mChannel->receiveMessage(&msg); if (result) { *outSeq = 0; *outHandled = false; return result; } if (msg.header.type != InputMessage::Type::FINISHED) { ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer", mChannel->getName().c_str(), msg.header.type); return UNKNOWN_ERROR; } *outSeq = msg.body.finished.seq; *outHandled = msg.body.finished.handled == 1; // 判断是否handled, 为1则handled return OK; }InputChannel::receiveMessage
status_t InputChannel::receiveMessage(InputMessage* msg) { ssize_t nRead; do { // 读取到msg nRead = ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT); } while (nRead == -1 && errno == EINTR); if (nRead < 0) { int error = errno; #if DEBUG_CHANNEL_MESSAGES ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.c_str(), errno); #endif if (error == EAGAIN || error == EWOULDBLOCK) { return WOULD_BLOCK; } if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) { return DEAD_OBJECT; } return -error; } if (nRead == 0) { // check for EOF #if DEBUG_CHANNEL_MESSAGES ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.c_str()); #endif return DEAD_OBJECT; } if (!msg->isValid(nRead)) { #if DEBUG_CHANNEL_MESSAGES ALOGD("channel '%s' ~ received invalid message", mName.c_str()); #endif return BAD_VALUE; } #if DEBUG_CHANNEL_MESSAGES ALOGD("channel '%s' ~ received message of type %d", mName.c_str(), msg->header.type); #endif return OK; }InputDispatcher::finishDispatchCycleLocked
void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, const spInputDispatcher::onDispatchCycleFinishedLocked& connection, uint32_t seq, bool handled) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s", connection->getInputChannelName().c_str(), seq, toString(handled)); #endif if (connection->status == Connection::STATUS_BROKEN || connection->status == Connection::STATUS_ZOMBIE) { return; } // Notify other system components and prepare to start the next dispatch cycle. // 结束当前事件循环, 准备执行下一个派发循环 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled); }
void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime, const sp& connection, uint32_t seq, bool handled) { // 创建 CommandEntry, 它的command是类成员 InputDispatcher::doDispatchCycleFinishedLockedInterruptible std::unique_ptr commandEntry = std::make_unique ( &InputDispatcher::doDispatchCycleFinishedLockedInterruptible); commandEntry->connection = connection; commandEntry->eventTime = currentTime; // 事件处理结束时间 commandEntry->seq = seq; commandEntry->handled = handled; postCommandLocked(std::move(commandEntry)); } // 添加到 mCommandQueue void InputDispatcher::postCommandLocked(std::unique_ptr commandEntry) { mCommandQueue.push_back(std::move(commandEntry)); }
接下来看看CommandEntry的定义:
/// @frameworks/native/services/inputflinger/dispatcher/Entry.h class InputDispatcher; // A command entry captures state and behavior for an action to be performed in the // dispatch loop after the initial processing has taken place. It is essentially // a kind of continuation used to postpone sensitive policy interactions to a point // in the dispatch loop where it is safe to release the lock (generally after finishing // the critical parts of the dispatch cycle). // // The special thing about commands is that they can voluntarily release and reacquire // the dispatcher lock at will. Initially when the command starts running, the // dispatcher lock is held. However, if the command needs to call into the policy to // do some work, it can release the lock, do the work, then reacquire the lock again // before returning. // // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch // never calls into the policy while holding its lock. // // Commands are implicitly 'LockedInterruptible'. struct CommandEntry; // Command 的定义, 本质上是函数指针. 对于InputDispatcher类成员函数而言,第一个参数即是InputDispatcher自身 typedef std::functionCommand; class Connection; struct CommandEntry { explicit CommandEntry(Command command); ~CommandEntry(); Command command; // parameters for the command (usage varies by command) sp connection; nsecs_t eventTime; KeyEntry* keyEntry; sp inputApplicationHandle; std::string reason; int32_t userActivityEventType; uint32_t seq; bool handled; sp inputChannel; sp oldToken; sp newToken; };
看看对Command注释的翻译:
初始处理完成后,命令条目将捕获要在调度循环中执行的 *** 作的状态和行为。 从本质上讲,这是一种延续,用于将敏感的策略交互延迟到分发循环中能安全释放锁的某个点(通常在完成分发周期的关键部分之后)。
关于命令的特殊之处在于它们可以随意释放并重新获取调度程序锁。 最初,当命令开始运行时,将保持调度程序锁定。 但是,如果命令需要调用策略以执行某些工作,则可以释放该锁,执行该工作,然后在返回之前再次重新获取该锁。
这种机制有点笨拙,但有助于保留不变性:在分发保持其锁定状态时永远不会调用策略。
再次回到 InputDispatcher::handleReceiveCallback , 当执行InputDispatcher#finishDispatchCycleLocked后,会将要执行的 *** 作封装成CommandEntry并添加到CommandQueue. 接下来执行InputDispatcher#runCommandsLockedInterruptible方法执行command
InputDispatcher#runCommandsLockedInterruptiblebool InputDispatcher::runCommandsLockedInterruptible() { if (mCommandQueue.empty()) { return false; } do { // 从mCommandQueu取出CommandEntry, 然后执行其Command std::unique_ptrInputDispatcher::doDispatchCycleFinishedLockedInterruptiblecommandEntry = std::move(mCommandQueue.front()); mCommandQueue.pop_front(); Command command = commandEntry->command; command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible' commandEntry->connection.clear(); } while (!mCommandQueue.empty()); return true; }
对于onDispatchCycleFinishedLocked方法中添加的CommandEntry而言,执行command则会调用InputDispatcher::doDispatchCycleFinishedLockedInterruptible方法
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) { spInputDispatcher::afterKeyEventLockedInterruptibleconnection = commandEntry->connection; const nsecs_t finishTime = commandEntry->eventTime; uint32_t seq = commandEntry->seq; const bool handled = commandEntry->handled; // Handle post-event policy actions. // 获取WaitQueue中seq对于的条目 std::deque ::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq); if (dispatchEntryIt == connection->waitQueue.end()) { return; } DispatchEntry* dispatchEntry = *dispatchEntryIt; const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime; if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) { // 事件处理超时 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(), ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str()); } // TODO Write some statistics about how long we spend waiting. reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled); // 判断是否需要重新派发此事件 bool restartEvent; if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) { // key事件 KeyEntry* keyEntry = static_cast (dispatchEntry->eventEntry); // 处理key事件未处理的情况, 返回true则此事件会重新派发 restartEvent = afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled); } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) { // 触摸事件 MotionEntry* motionEntry = static_cast (dispatchEntry->eventEntry); restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry, handled); } else { restartEvent = false; } // Dequeue the event and start the next cycle. // Because the lock might have been released, it is possible that the // contents of the wait queue to have been drained, so we need to double-check // a few things. dispatchEntryIt = connection->findWaitQueueEntry(seq); // 重新获取一次,防止wait queue变化 if (dispatchEntryIt != connection->waitQueue.end()) { dispatchEntry = *dispatchEntryIt; connection->waitQueue.erase(dispatchEntryIt); // 将此entry从waitQueue移除 mAnrTracker.erase(dispatchEntry->timeoutTime, // 将此token从mAnrTracker移除 connection->inputChannel->getConnectionToken()); if (!connection->responsive) { // 更新connection的responsive状态 connection->responsive = isConnectionResponsive(*connection); } traceWaitQueueLength(connection); // 如果需要重新派发, 则将此entry添加到outboundQueue的队列头,待下一次派发 if (restartEvent && connection->status == Connection::STATUS_NORMAL) { connection->outboundQueue.push_front(dispatchEntry); traceOutboundQueueLength(connection); } else { // 否则释放此entry releaseDispatchEntry(dispatchEntry); } } // 执行下一个派发循环 // Start the next dispatch cycle for this connection. startDispatchCycleLocked(now(), connection); }
处理unhandled key
bool InputDispatcher::afterKeyEventLockedInterruptible(const spInputDispatcher::startDispatchCycleLocked& connection, DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) { // 若此keyEntry已经有fallback标志,则返回以防事件持续未处理 , 以防反复调用 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) { if (!handled) { // Report the key as unhandled, since the fallback was not handled. mReporter->reportUnhandledKey(keyEntry->id); } return false; } // Get the fallback key state. // Clear it out after dispatching the UP. int32_t originalKeyCode = keyEntry->keyCode; int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode); if (keyEntry->action == AKEY_EVENT_ACTION_UP) { // 若是up事件,则移除FallbackKey connection->inputState.removeFallbackKey(originalKeyCode); } if (handled || !dispatchEntry->hasForegroundTarget()) { // If the application handles the original key for which we previously // generated a fallback or if the window is not a foreground window, // then cancel the associated fallback key, if any. if (fallbackKeyCode != -1) { // 如果应用处理了原始key或者window不是前台的,则取消fallback key // Dispatch the unhandled key to the policy with the cancel flag. #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Unhandled key event: Asking policy to cancel fallback action. " "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags); #endif KeyEvent event = createKeyEvent(*keyEntry); event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED); mLock.unlock(); mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event, keyEntry->policyFlags, &event); mLock.lock(); // Cancel the fallback key. if (fallbackKeyCode != AKEYCODE_UNKNOWN) { CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS, "application handled the original non-fallback key " "or is no longer a foreground target, " "canceling previously dispatched fallback key"); options.keyCode = fallbackKeyCode; synthesizeCancelationEventsForConnectionLocked(connection, options); } connection->inputState.removeFallbackKey(originalKeyCode); } } else { // 处理非fallback key 未处理的情况 // If the application did not handle a non-fallback key, first check // that we are in a good state to perform unhandled key event processing // Then ask the policy what to do with it. bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0; if (fallbackKeyCode == -1 && !initialDown) {// 还没设置fallbackKeyCode且不是初始down事件 #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Unhandled key event: Skipping unhandled key event processing " "since this is not an initial down. " "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags); #endif return false; } // 通过策略派发未处理key事件 // Dispatch the unhandled key to the policy. #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Unhandled key event: Asking policy to perform fallback action. " "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags); #endif KeyEvent event = createKeyEvent(*keyEntry); mLock.unlock(); bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event, keyEntry->policyFlags, &event); mLock.lock(); if (connection->status != Connection::STATUS_NORMAL) { connection->inputState.removeFallbackKey(originalKeyCode); return false; } // Latch the fallback keycode for this key on an initial down. // The fallback keycode cannot change at any other point in the lifecycle. if (initialDown) { if (fallback) { fallbackKeyCode = event.getKeyCode(); } else { fallbackKeyCode = AKEYCODE_UNKNOWN; } connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode); } ALOG_ASSERT(fallbackKeyCode != -1); // Cancel the fallback key if the policy decides not to send it anymore. // We will continue to dispatch the key to the policy but we will no // longer dispatch a fallback key to the application. if (fallbackKeyCode != AKEYCODE_UNKNOWN && (!fallback || fallbackKeyCode != event.getKeyCode())) { // 处理keyCode不一致的情况 #if DEBUG_OUTBOUND_EVENT_DETAILS if (fallback) { ALOGD("Unhandled key event: Policy requested to send key %d" "as a fallback for %d, but on the DOWN it had requested " "to send %d instead. Fallback canceled.", event.getKeyCode(), originalKeyCode, fallbackKeyCode); } else { ALOGD("Unhandled key event: Policy did not request fallback for %d, " "but on the DOWN it had requested to send %d. " "Fallback canceled.", originalKeyCode, fallbackKeyCode); } #endif CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS, "canceling fallback, policy no longer desires it"); options.keyCode = fallbackKeyCode; synthesizeCancelationEventsForConnectionLocked(connection, options); fallback = false; fallbackKeyCode = AKEYCODE_UNKNOWN; if (keyEntry->action != AKEY_EVENT_ACTION_UP) { connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode); } } if (fallback) { /// 初始化fallback keyEntry // Restart the dispatch cycle using the fallback key. keyEntry->eventTime = event.getEventTime(); keyEntry->deviceId = event.getDeviceId(); keyEntry->source = event.getSource(); keyEntry->displayId = event.getDisplayId(); keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK; keyEntry->keyCode = fallbackKeyCode; keyEntry->scanCode = event.getScanCode(); keyEntry->metaState = event.getmetaState(); keyEntry->repeatCount = event.getRepeatCount(); keyEntry->downTime = event.getDownTime(); keyEntry->syntheticRepeat = false; #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Unhandled key event: Dispatching fallback key. " "originalKeyCode=%d, fallbackKeyCode=%d, fallbackmetaState=%08x", originalKeyCode, fallbackKeyCode, keyEntry->metaState); #endif return true; // restart the event } else { #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Unhandled key event: No fallback key."); #endif // Report the key as unhandled, since there is no fallback key. mReporter->reportUnhandledKey(keyEntry->id); } } return false; }
执行新一轮的派发
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, const sp& connection) { if (ATRACE_ENABLED()) { std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)", connection->getInputChannelName().c_str()); ATRACE_NAME(message.c_str()); } #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str()); #endif while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) { DispatchEntry* dispatchEntry = connection->outboundQueue.front(); dispatchEntry->deliveryTime = currentTime; const nsecs_t timeout = getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken()); dispatchEntry->timeoutTime = currentTime + timeout; // Publish the event. status_t status; EventEntry* eventEntry = dispatchEntry->eventEntry; switch (eventEntry->type) { case EventEntry::Type::KEY: { // 派发key事件 const KeyEntry* keyEntry = static_cast (eventEntry); std::array hmac = getSignature(*keyEntry, *dispatchEntry); // Publish the key event. status = connection->inputPublisher .publishKeyEvent(dispatchEntry->seq, dispatchEntry->resolvedEventId, keyEntry->deviceId, keyEntry->source, keyEntry->displayId, std::move(hmac), dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags, keyEntry->keyCode, keyEntry->scanCode, keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime, keyEntry->eventTime); break; } case EventEntry::Type::MOTION: { ... // Publish the motion event. status = connection->inputPublisher.publishMotionEvent(...) break; } case EventEntry::Type::FOCUS: { FocusEntry* focusEntry = static_cast (eventEntry); status = connection->inputPublisher.publishFocusEvent(...); break; } case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: { LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events", EventEntry::typeToString(eventEntry->type)); return; } } // Check the result. if (status) { if (status == WOULD_BLOCK) { if (connection->waitQueue.empty()) { ALOGE("channel '%s' ~ Could not publish event because the pipe is full. " "This is unexpected because the wait queue is empty, so the pipe " "should be empty and we shouldn't have any problems writing an " "event to it, status=%d", connection->getInputChannelName().c_str(), status); abortBrokenDispatchCycleLocked(currentTime, connection, true ); } else { // Pipe is full and we are waiting for the app to finish process some events // before sending more events to it. #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Could not publish event because the pipe is full, " "waiting for the application to catch up", connection->getInputChannelName().c_str()); #endif } } else { ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, " "status=%d", connection->getInputChannelName().c_str(), status); abortBrokenDispatchCycleLocked(currentTime, connection, true ); } return; } // 将已派发的dispatchEntry从outboundQueue移除 // Re-enqueue the event on the wait queue. connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(), connection->outboundQueue.end(), dispatchEntry)); traceOutboundQueueLength(connection); // 添加dispatchEntry到waitQueue, 等待client的finish反馈 connection->waitQueue.push_back(dispatchEntry); if (connection->responsive) { // 设置anr检测 mAnrTracker.insert(dispatchEntry->timeoutTime, connection->inputChannel->getConnectionToken()); } traceWaitQueueLength(connection); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)