开局叠甲,可能理解有误,请大佬们斧正。
- Android Framework-Input-1 基础梳理
- Android Framework-Input-2 构建和启动
- Android Framework-Input-3 数据处理
- Android Framework-Input-4 IQ到OQ
- Android Framework-Input-5 分发事件
- Android Framework-Input-6 事件分发到View
- Android Framework-Input-7 事件的移除
- Android Framework-Input-8 ANR相关
我们在上篇讲到 再 调用 processPointerEvent()后,事件最终分发到了ViewRootImp里的mView。
最后返回了 FINISH_HANDLED。
//android/view/ViewRootImpl.java
public final void deliver(QueuedInputEvent q) {
if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) {
forward(q);
} else if (shouldDropInputEvent(q)) {
finish(q, false);
} else {
traceEvent(q, Trace.TRACE_TAG_VIEW);
final int result;
try {
//我们已经知道这里的返回值是 FINISH_HANDLED
result = onProcess(q);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
apply(q, result);
}
}
protected void apply(QueuedInputEvent q, int result) {
if (result == FORWARD) {
forward(q);
} else if (result == FINISH_HANDLED) {
finish(q, true);
} else if (result == FINISH_NOT_HANDLED) {
finish(q, false);
} else {
throw new IllegalArgumentException("Invalid result: " + result);
}
}
//--> //这里handled是true
protected void finish(QueuedInputEvent q, boolean handled) {
q.mFlags |= QueuedInputEvent.FLAG_FINISHED;
if (handled) {
//注意flag
q.mFlags |= QueuedInputEvent.FLAG_FINISHED_HANDLED;
}
forward(q);
}
protected void forward(QueuedInputEvent q) {
onDeliverToNext(q);
}
protected void onDeliverToNext(QueuedInputEvent q) {
if (DEBUG_INPUT_STAGES) {
Log.v(mTag, "Done with " + getClass().getSimpleName() + ". " + q);
}
if (mNext != null) {
mNext.deliver(q);
} else {
finishInputEvent(q);
}
}
private void finishInputEvent(QueuedInputEvent q) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "deliverInputEvent",
q.mEvent.getId());
if (q.mReceiver != null) {
boolean handled = (q.mFlags & QueuedInputEvent.FLAG_FINISHED_HANDLED) != 0;
boolean modified = (q.mFlags & QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY) != 0;
if (modified) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventBeforeFinish");
InputEvent processedEvent;
try {
processedEvent =
mInputCompatProcessor.processInputEventBeforeFinish(q.mEvent);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
if (processedEvent != null) {
q.mReceiver.finishInputEvent(processedEvent, handled);
}
} else {
q.mReceiver.finishInputEvent(q.mEvent, handled);
}
} else {
q.mEvent.recycleIfNeededAfterDispatch();
}
recycleQueuedInputEvent(q);
}
//这里的基本调用逻辑就是 finish(q, true);-->
这里代码比较多,我们简单梳理一下。 apply(QueuedInputEvent q, int result) 该方法,因为返回值的原因,走了 finish(q, true); 所以 q.mFlags |= QueuedInputEvent.FLAG_FINISHED_HANDLED;。然后调用了 finishInputEvent(QueuedInputEvent q);方法。因为flag的原因 调用到了 q.mReceiver.finishInputEvent(q.mEvent, handled);。还是不要看细节,记住最后调用回到了finishInputEvent()就好。
finishInputEvent()会调用到 nativeFinishInputEvent(mReceiverPtr, seq, handled);
这里看出传参里面包含一个参数seq,之前说过seq 是很关键的一个参数,主要用来查询消息。
public final void finishInputEvent(InputEvent event, boolean handled) {
if (event == null) {
//省略
}
if (mReceiverPtr == 0) {
//省略
} else {
int index = mSeqMap.indexOfKey(event.getSequenceNumber());
if (index < 0) {
//省略
} else {
int seq = mSeqMap.valueAt(index);
mSeqMap.removeAt(index);
nativeFinishInputEvent(mReceiverPtr, seq, handled);
}
}
event.recycleIfNeededAfterDispatch();
}
再次进入 android_view_InputEventReceiver.cpp
static void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jlong receiverPtr,
jint seq, jboolean handled) {
sp<NativeInputEventReceiver> receiver =
reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
status_t status = receiver->finishInputEvent(seq, handled);
if (status == OK || status == WOULD_BLOCK) {
return; // normal operation
}
if (status != DEAD_OBJECT) {
std::string message =
android::base::StringPrintf("Failed to finish input event. status=%s(%d)",
statusToString(status).c_str(), status);
jniThrowRuntimeException(env, message.c_str());
}
}
调用到 NativeInputEventReceiver的finishInputEvent(seq);
status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) {
//省略
Finish finish{
.seq = seq,
.handled = handled,
};
//加入mOutboundQueue
mOutboundQueue.push_back(finish);
return processOutboundEvents();
}
看到这里是不是好奇,咋消息又进了 mOutboundQueue 也就是我们说的OQ;按照道理来说这玩意还有啥用? 秘密在 processOutboundEvents()里。
status_t NativeInputEventReceiver::processOutboundEvents() {
while (!mOutboundQueue.empty()) {
OutboundEvent& outbound = *mOutboundQueue.begin();
status_t status;
if (std::holds_alternative<Finish>(outbound)) {
const Finish& finish = std::get<Finish>(outbound);
//发送给消费者
status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled);
} else if (std::holds_alternative<Timeline>(outbound)) {
const Timeline& timeline = std::get<Timeline>(outbound);
status = mInputConsumer.sendTimeline(timeline.inputEventId, timeline.timeline);
} else {
status = BAD_VALUE;
}
if (status == OK) {
//成功就移除
mOutboundQueue.erase(mOutboundQueue.begin());
continue;
}
// Publisher is busy, try again later. Keep this entry (do not erase)
if (status == WOULD_BLOCK) {
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Remaining outbound events: %zu.",
getInputChannelName().c_str(), mOutboundQueue.size());
}
setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT);
return WOULD_BLOCK; // try again later
}
return status;
}
setFdEvents(ALOOPER_EVENT_INPUT);
return OK;
}
这里我们看了下核心代码就得看的mInputConsumer.sendFinishedSignal(),如果拷贝消息发送成功了就移除,否则就循环等待。我们看下代码的调用逻辑。其实可以理解为事件的删除之旅。
status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
InputMessage msg;
msg.header.type = InputMessage::Type::FINISHED;
msg.header.seq = seq;//序列号很关键 靠他找消息
msg.body.finished.handled = handled;
msg.body.finished.consumeTime = getConsumeTime(seq);
//核心代码
status_t result = mChannel->sendMessage(&msg);
if (result == OK) {
popConsumeTime(seq);
}
return result;
}
进行了一次转化 ,将seq和handled 转了一次,调用sendMessage(const InputMessage* msg) 注意这里的 msg.header.type = InputMessage::Type::FINISHED;下面会用到。
status_t InputChannel::sendMessage(const InputMessage* msg) {
const size_t msgLength = msg->size();
InputMessage cleanMsg;
// 数据的拷贝转移
msg->getSanitizedCopy(&cleanMsg);
ssize_t nWrite;
do {
//socketpair 发送 进入inputDisPatcher
nWrite = ::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
} while (nWrite == -1 && errno == EINTR);
//省略
return OK;
}
涉及FD再次到达InputDispatcher.cpp,这里为什么回掉handleReceiveCallback是因为
在构造里有注册。
//native/services/inputflinger/dispatcher/InputDispatcher.cpp
std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback, this, std::placeholders::_1, token);
mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
这段代码涉及消息的收取转换receiveConsumerResponse()和处理 finishDispatchCycleLocked()
//native/services/inputflinger/dispatcher/InputDispatcher.cpp
int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
std::scoped_lock _l(mLock);
//找 connection
sp<Connection> connection = getConnectionLocked(connectionToken);
if (connection == nullptr) {
//找不到 g
return 0; // remove the callback
}
bool notify;
if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
if (!(events & ALOOPER_EVENT_INPUT)) {
return 1;
}
nsecs_t currentTime = now();
bool gotOne = false;
status_t status = OK;
for (;;) {
//先收取消息
Result<InputPublisher::ConsumerResponse> result =
connection->inputPublisher.receiveConsumerResponse();
if (!result.ok()) {
status = result.error().code();
break;
}
if (std::holds_alternative<InputPublisher::Finished>(*result)) {
const InputPublisher::Finished& finish =
std::get<InputPublisher::Finished>(*result);
//转化成功 调用这里finishDispatchCycleLocked
finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
finish.consumeTime);
} else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
if (shouldReportMetricsForConnection(*connection)) {
const InputPublisher::Timeline& timeline =
std::get<InputPublisher::Timeline>(*result);
mLatencyTracker
.trackGraphicsLatency(timeline.inputEventId,
connection->inputChannel->getConnectionToken(),
std::move(timeline.graphicsTimeline));
}
}
gotOne = true;
}
if (gotOne) {
runCommandsLockedInterruptible();
if (status == WOULD_BLOCK) {
return 1;
}
}
notify = status != DEAD_OBJECT || !connection->monitor;
} else {
const bool stillHaveWindowHandle =
getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
notify = !connection->monitor && stillHaveWindowHandle;
// Remove the channel.
removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
return 0; // remove the callback
}
先看下 receiveConsumerResponse() 消息的收取。我们上面说到type是FINISHED
android::base::Result<InputPublisher::ConsumerResponse> InputPublisher::receiveConsumerResponse() {
if (DEBUG_TRANSPORT_ACTIONS) {
ALOGD("channel '%s' publisher ~ %s", mChannel->getName().c_str(), __func__);
}
InputMessage msg;
status_t result = mChannel->receiveMessage(&msg);
if (result) {
return android::base::Error(result);
}
//当前是FINISHED
if (msg.header.type == InputMessage::Type::FINISHED) {
return Finished{
.seq = msg.header.seq,
.handled = msg.body.finished.handled,
.consumeTime = msg.body.finished.consumeTime,
};
}
if (msg.header.type == InputMessage::Type::TIMELINE) {
return Timeline{
.inputEventId = msg.body.timeline.eventId,
.graphicsTimeline = msg.body.timeline.graphicsTimeline,
};
}
return android::base::Error(UNKNOWN_ERROR);
}
看下处理finishDispatchCycleLocked()调用onDispatchCycleFinishedLocked()
void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection, uint32_t seq,
bool handled, nsecs_t consumeTime) {
//省略
onDispatchCycleFinishedLocked(currentTime, connection, seq, handled, consumeTime);
}
onDispatchCycleFinishedLocked()
void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
const sp<Connection>& connection, uint32_t seq,
bool handled, nsecs_t consumeTime) {
// doDispatchCycleFinishedLockedInterruptible 相当于一个回调
std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
&InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
commandEntry->connection = connection;
commandEntry->eventTime = currentTime;
commandEntry->seq = seq;
commandEntry->handled = handled;
commandEntry->consumeTime = consumeTime;
//这里会涉及dispatchOnce 里面的 haveCommandsLocked
postCommandLocked(std::move(commandEntry));
}
调用 doDispatchCycleFinishedLockedInterruptible(),postCommandLocked() 会涉及到ANR部分我们后面再说。
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;
//查找该connection 的等待队列
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 (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
connection->inputChannel->getConnectionToken(),
dispatchEntry->deliveryTime, commandEntry->consumeTime,
finishTime);
}
bool restartEvent;
if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
//省略
} else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
//只管MOTION
MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,handled);
} else {
restartEvent = false;
}
//根据序列码找到该事件
dispatchEntryIt = connection->findWaitQueueEntry(seq);
if (dispatchEntryIt != connection->waitQueue.end()) {
dispatchEntry = *dispatchEntryIt;
//从wq 删除该消息
connection->waitQueue.erase(dispatchEntryIt);
const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
if (!connection->responsive) {
connection->responsive = isConnectionResponsive(*connection);
if (connection->responsive) {
processConnectionResponsiveLocked(*connection);
}
}
traceWaitQueueLength(*connection);
if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
connection->outboundQueue.push_front(dispatchEntry);
traceOutboundQueueLength(*connection);
} else {
releaseDispatchEntry(dispatchEntry);
}
}
startDispatchCycleLocked(now(), connection);
}
其实这段代码核心部分可以理解,就是依托于seq,找到对应的消息,从WQ删除。自此整个消息从产生到发送,到销毁,经历IQ->OQ->WQ->OQ删除->WQ删除的过程。我们讲ANR将在下一篇进行探秘。