文章托管在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) {
sp receiver =
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());
}
}
NativeInputEventReceiver::finishInputEvent
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_cast(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
}
InputPublisher::receiveFinishedSignal
接收来自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 sp& 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);
}
InputDispatcher::onDispatchCycleFinishedLocked
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_ptr commandEntry = 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;
}
InputDispatcher::doDispatchCycleFinishedLockedInterruptible
对于onDispatchCycleFinishedLocked方法中添加的CommandEntry而言,执行command则会调用InputDispatcher::doDispatchCycleFinishedLockedInterruptible方法
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
sp connection = 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);
}
InputDispatcher::afterKeyEventLockedInterruptible
处理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);
}
}



