Link:
Android Input (1) -- InputManagerService启动
Android Input (2) -- inputReader
Android Input (3) -- inputDispatcher
Android Input (4) -- inputDispatcher到ViewRootImpl
Android Input (5) -- ViewRootImpl 的事件分发(Activity ViewGroup View )
Android Input (6) -- PhoneWindowManager中Power,BACK等按键处理流程
Android Input (7) -- 模块的锁检测
Android Input (8) -- ANR input event原理
目录
1.1 publishKeyEvent后,向fd写入event触发回调
1.2 handleEvent回调处理
2.1 NativeInputEventReceiver ::consumeEvents
2.2 gInputEventReceiverClassInfo.dispatchInputEvent
2.3 ViewRootImpl.java dispatchInputEvent/enqueueInputEvent
2.4 finishIn
3.1 sendFinishedSignal
3.2 sendUnchainedFinishedSignal
4.1 handleReceiveCallback
4.2 InputPublisher.receiveFinishedSignal
4.3 finishDispatchCycleLocked
4.4 onDispatchCycleFinishedLocked
4.5 runCommandsLockedInterruptible
4.6 doDispatchCycleFinishedLockedInterruptible
流程图
@frameworks/native/libs/input/InputTransport.cpp
status_t InputPublisher::publishKeyEvent(
...
return mChannel->sendMessage(&msg); //sendMessage
}
InputPublisher::InputPublisher(const sp& channel) :
mChannel(channel) {
}
//写入mfd
status_t InputChannel::sendMessage(const InputMessage* msg) {
do {
nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
} while (nWrite == -1 && errno == EINTR);
return OK;
}
frameworks\base\core\java\android\view\ViewRootImpl.java
WindowInputEventReceiver 的父类为InputEventReceiver
final class WindowInputEventReceiver extends InputEventReceiver {
public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
}
}
frameworks\base\core\java\android\view\InputEventReceiver.java
public InputEventReceiver(InputChannel inputChannel, Looper looper) {
mInputChannel = inputChannel;
mMessageQueue = looper.getQueue();
mReceiverPtr = nativeInit(new WeakReference(this),
inputChannel, mMessageQueue);
mCloseGuard.open("dispose");
}
frameworks\base\core\jni\android_view_InputEventReceiver.cpp
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject inputChannelObj, jobject messageQueueObj) {
sp inputChannel = android_view_InputChannel_getInputChannel(env,
inputChannelObj);
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
//NativeInputEventReceiver 实现了 LooperCallback ,处理Looper的事件
sp receiver = new NativeInputEventReceiver(env,
receiverWeak, inputChannel, messageQueue);
status_t status = receiver->initialize(); //初始化
receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast(receiver.get());
}
frameworks\base\core\jni\android_view_InputEventReceiver.cpp
这里mInputConsumer将持有inputChannel
NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env,
jobject receiverWeak, const sp& inputChannel,
const sp& messageQueue) :
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
mInputConsumer(inputChannel), mMessageQueue(messageQueue),
mBatchedInputEventPending(false), mFdEvents(0) {
}
frameworks\native\libs\input\InputTransport.cpp
InputConsumer::InputConsumer(const sp& channel) :
mResampleTouch(isTouchResamplingEnabled()),
mChannel(channel), mMsgDeferred(false) {
}
frameworks\base\core\jni\android_view_InputEventReceiver.cpp
status_t NativeInputEventReceiver::initialize() {
setFdEvents(ALOOPER_EVENT_INPUT);
return OK;
}
frameworks\base\core\jni\android_view_InputEventReceiver.cpp
void NativeInputEventReceiver::setFdEvents(int events) {
if (mFdEvents != events) {
mFdEvents = events;
int fd = mInputConsumer.getChannel()->getFd(); //获取通道文件描述符
if (events) {
//往消息循环加事件, this 参数 表示消息处理由本接收器处理 handEvent
mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL);
} else {
mMessageQueue->getLooper()->removeFd(fd);
}
}
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
if (events & ALOOPER_EVENT_INPUT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL); //consumeEvents 消耗事件
return status == OK || status == NO_MEMORY ? 1 : 0;
}
if (events & ALOOPER_EVENT_OUTPUT) {
for (size_t i = 0; i < mFinishQueue.size(); i++) {
const Finish& finish = mFinishQueue.itemAt(i);
status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled); //2 sendFinishedSignal向inputDispatcher finish signal
if (status) {
mFinishQueue.removeItemsAt(0, i);
...
}
}
}
}
}
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
bool skipCallbacks = false;
for (;;) {
status_t status = mInputConsumer.consume(&mInputEventFactory,
consumeBatches, frameTime, &seq, &inputEvent, &displayId,
&motionEventType, &touchMoveNum, &flag);
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchMotionEventInfo, motionEventType, touchMoveNum);
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchBatchedInputEventPending);
if (inputEventObj) {
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj, //gInputEventReceiverClassInfo.dispatchInputEvent
displayId);
if (env->ExceptionCheck()) {
ALOGE("Exception dispatching input event.");
skipCallbacks = true;
}
env->DeleteLocalRef(inputEventObj);
}
}
}
@/frameworks/base/core/java/android/view/InputEventReceiver.java
@SuppressWarnings("unused")
private void dispatchMotionEventInfo(int motionEventType, int touchMoveNum) {
try {
if (mChoreographer == null)
mChoreographer = Choreographer.getInstance();
if (mChoreographer != null)
mChoreographer.setMotionEventInfo(motionEventType, touchMoveNum);
} catch (Exception e) {
Log.e(TAG, "cannot invoke setMotionEventInfo.");
}
}
private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
mSeqMap.put(event.getSequenceNumber(), seq);
onInputEvent(event, displayId);
}
还记得上面InputEventReceiver初始化时的流程吗?是通过setView--->new WindowInputEventReceiver--->new InputEventReceiver--->new NativeInputEventReceiver这样一步一步创建的。
通过上述的JNI调用,会调用到WindowInputEventReceiver的dispatchInputEvent方法,不过由于WindowInputEventReceiver并没有自己实现这个方法,因此会调用父类InputEventReceiver::dispatchInputEvent,内部会真正调用到WindowInputEventReceiver::onInputEvent
@frameworks/base/core/java/android/view/ViewRootImpl.java
final class WindowInputEventReceiver extends InputEventReceiver {
public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
}
@Override
public void onInputEvent(InputEvent event, int displayId) {
enqueueInputEvent(event, this, 0, true);
}
void enqueueInputEvent(InputEvent event,
InputEventReceiver receiver, int flags, boolean processImmediately) {
QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
QueuedInputEvent last = mPendingInputEventTail;
if (processImmediately) {
doProcessInputEvents();
} else {
scheduleProcessInputEvents();
}
}
void doProcessInputEvents() {
while (mPendingInputEventHead != null) {
QueuedInputEvent q = mPendingInputEventHead;
mPendingInputEventHead = q.mNext;
q.mNext = null;
deliverInputEvent(q);
}
}
//处理完事件后就会finishInputEvent来完成事件分发操作
private void deliverInputEvent(QueuedInputEvent q) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
}
InputStage stage;
if (stage != null) {
stage.deliver(q);
} else {
finishInputEvent(q);
}
}
private void finishInputEvent(QueuedInputEvent q) {
if (q.mReceiver != null) {
boolean handled = (q.mFlags & QueuedInputEvent.FLAG_FINISHED_HANDLED) != 0;
q.mReceiver.finishInputEvent(q.mEvent, handled);
} else {
q.mEvent.recycleIfNeededAfterDispatch();
}
recycleQueuedInputEvent(q);
}
mReceiver.finishInputEvent
public final void finishInputEvent(InputEvent event, boolean handled) {
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();
}
[-> InputTransport.cpp ::InputConsumer]
status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
...
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; ) {
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) {
//[见小节3.5.1]
status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
}
if (status) {
// An error occurred so at least one signal was not sent, reconstruct the chain.
do {
SeqChain seqChain;
seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
seqChain.chain = chainSeqs[chainIndex];
mSeqChains.push(seqChain);
} while (chainIndex-- > 0);
return status;
}
}
return sendUnchainedFinishedSignal(seq, handled);
}
[-> InputTransport.cpp ::InputConsumer]
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;
return mChannel->sendMessage(&msg);
}
通过InputChannel->sendMessage,将TYPE_FINISHED类型的消息,发送回InputDispatcher线程。
InputDispatcher接收finish signal处理,并移除waitQueue
[-> InputDispatcher]
int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
InputDispatcher* d = static_cast(data);
{
AutoMutex _l(d->mLock);
ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
bool notify;
sp 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;
//【见小节4.4】
status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
if (status) {
break;
}
//【见小节4.5】
d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
gotOne = true;
}
if (gotOne) {
d->runCommandsLockedInterruptible(); //执行命令【见小节4.6】
if (status == WOULD_BLOCK) {
return 1;
}
}
notify = status != DEAD_OBJECT || !connection->monitor;
} else {
...
//input channel被关闭或者发生错误
}
//取消注册channel
d->unregisterInputChannelLocked(connection->inputChannel, notify);
return 0;
}
}
[-> InputTransport.cpp]
status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
InputMessage msg;
//接收消息
status_t result = mChannel->receiveMessage(&msg);
if (result) {
*outSeq = 0;
*outHandled = false;
return result;
}
if (msg.header.type != InputMessage::TYPE_FINISHED) {
return UNKNOWN_ERROR; //发生错误
}
*outSeq = msg.body.finished.seq;
*outHandled = msg.body.finished.handled;
return OK;
}
[-> InputDispatcher.cpp]
void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
const sp& connection, uint32_t seq, bool handled) {
connection->inputPublisherBlocked = false;
if (connection->status == Connection::STATUS_BROKEN
|| connection->status == Connection::STATUS_ZOMBIE) {
return;
}
//通知系统准备启动下一次分发流程【见小节4.5.1】
onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
}
[-> InputDispatcher.cpp]
void InputDispatcher::onDispatchCycleFinishedLocked(
nsecs_t currentTime, const sp& connection, uint32_t seq, bool handled) {
//向mCommandQueue添加命令
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
commandEntry->connection = connection;
commandEntry->eventTime = currentTime;
commandEntry->seq = seq;
commandEntry->handled = handled;
}
[-> InputDispatcher.cpp]
bool InputDispatcher::runCommandsLockedInterruptible() {
if (mCommandQueue.isEmpty()) {
return false;
}
do {
//从mCommandQueue队列的头部取出第一个元素【见小节4.6.1】
CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
Command command = commandEntry->command;
//此处调用的命令隐式地包含'LockedInterruptible'
(this->*command)(commandEntry);
commandEntry->connection.clear();
delete commandEntry;
} while (! mCommandQueue.isEmpty());
return true;
}
可以队列中的元素至少有doDispatchCycleFinishedLockedInterruptible。
[-> InputDispatcher.cpp]
将dispatchEntry事件从等待队列(waitQueue)中移除
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
CommandEntry* commandEntry) {
sp connection = commandEntry->connection;
nsecs_t finishTime = commandEntry->eventTime;
uint32_t seq = commandEntry->seq;
bool handled = commandEntry->handled;
//获取分发事件
DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
if (dispatchEntry) {
nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
//打印出所有分发时间超过2s的事件
if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
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(dispatchEntry->eventEntry);
restartEvent = afterKeyEventLockedInterruptible(connection,
dispatchEntry, keyEntry, handled);
} else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
...
} else {
...
}
if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
//将dispatchEntry事件从等待队列(waitQueue)中移除
connection->waitQueue.dequeue(dispatchEntry);
if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
connection->outboundQueue.enqueueAtHead(dispatchEntry);
} else {
releaseDispatchEntryLocked(dispatchEntry);
}
}
//启动下一个事件处理循环。
startDispatchCycleLocked(now(), connection);
}
}