文章托管在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
/**
* Finishes an input event and indicates whether it was handled.
* Must be called on the same Looper thread to which the receiver is attached.
*
* @param event The input event that was finished.
* @param handled True if the event was handled.
*/
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[] = {
/* name, signature, funcPtr */
{ "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<NativeInputEventReceiver> receiver =
reinterpret_cast<NativeInputEventReceiver*>(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::handleReceiveCallback
int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
InputDispatcher* d = static_cast<InputDispatcher*>(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> 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>& 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>& connection, uint32_t seq,
bool handled) {
// 创建 CommandEntry, 它的command是类成员 InputDispatcher::doDispatchCycleFinishedLockedInterruptible
std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
&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> 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::function<void(InputDispatcher&, CommandEntry*)> Command;
class Connection;
struct CommandEntry {
explicit CommandEntry(Command command);
~CommandEntry();
Command command;
// parameters for the command (usage varies by command)
sp<Connection> connection;
nsecs_t eventTime;
KeyEntry* keyEntry;
sp<InputApplicationHandle> inputApplicationHandle;
std::string reason;
int32_t userActivityEventType;
uint32_t seq;
bool handled;
sp<InputChannel> inputChannel;
sp<IBinder> oldToken;
sp<IBinder> newToken;
};
看看对Command注释的翻译:
初始处理完成后,命令条目将捕获要在调度循环中执行的操作的状态和行为。 从本质上讲,这是一种延续,用于将敏感的策略交互延迟到分发循环中能安全释放锁的某个点(通常在完成分发周期的关键部分之后)。
关于命令的特殊之处在于它们可以随意释放并重新获取调度程序锁。 最初,当命令开始运行时,将保持调度程序锁定。 但是,如果命令需要调用策略以执行某些工作,则可以释放该锁,执行该工作,然后在返回之前再次重新获取该锁。
这种机制有点笨拙,但有助于保留不变性:在分发保持其锁定状态时永远不会调用策略。
再次回到 InputDispatcher::handleReceiveCallback , 当执行InputDispatcher#finishDispatchCycleLocked后,会将要执行的操作封装成CommandEntry并添加到CommandQueue. 接下来执行InputDispatcher#runCommandsLockedInterruptible方法执行command
InputDispatcher#runCommandsLockedInterruptible
bool InputDispatcher::runCommandsLockedInterruptible() {
if (mCommandQueue.empty()) {
return false;
}
do {
// 从mCommandQueu取出CommandEntry, 然后执行其Command
std::unique_ptr<CommandEntry> 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> 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<DispatchEntry*>::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<KeyEntry*>(dispatchEntry->eventEntry);
// 处理key事件未处理的情况, 返回true则此事件会重新派发
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;
}
// 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 sp<Connection>& 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;
}
InputDispatcher::startDispatchCycleLocked
执行新一轮的派发
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& 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<KeyEntry*>(eventEntry);
std::array<uint8_t, 32> 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<FocusEntry*>(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 /*notify*/);
} 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 /*notify*/);
}
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);
}
}
|