本文首发于微信公众号「刘望舒」
前言
在上一篇文章中,我们学习了输入事件的处理,输入事件会交由InputDispatcher进行分发,那么InputDispatcher是如何进行分发的?这篇文章会给你答案。
1.InputReader的加工类型
在Android输入系统(二)IMS的启动过程和输入事件的处理这篇文章中,我们知道InputReader会对原始输入事件进行加工,如果事件的类型为按键类型的事件,就会调用如下一段代码。
frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
...
bool needWake;
{
...
} // release lock
if (needWake) {
mLooper->wake();
}
}
InputDispatcher的notifyKey方法用于唤醒InputDispatcherThread,它的参数NotifyKeyArgs是InputReader对按键类型的事件加工后得到的。
frameworks/native/services/inputflinger/InputListener.h
struct NotifyKeyArgs : public NotifyArgs {
nsecs_t eventTime;
int32_t deviceId;
uint32_t source;
uint32_t policyFlags;
int32_t action;
int32_t flags;
int32_t keyCode;
int32_t scanCode;
int32_t metaState;
nsecs_t downTime;
inline NotifyKeyArgs() {
}
NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
int32_t metaState, nsecs_t downTime);
NotifyKeyArgs(const NotifyKeyArgs& other);
virtual ~NotifyKeyArgs() {
}
virtual void notify(const sp<InputListenerInterface>& listener) const;
};
可以看到,NotifyKeyArgs结构体继承自NotifyArgs结构体,如下图所示。
NotifyArgs有三个子类,分别是NotifyKeyArgs、NotifyMotionArgs和NotifySwichArgs,这说明InputReader对原始输入事件加工后,最终会得出三种事件类型,分别是key事件、Motion事件和Swich事件,这些事件会交由InputDispatcher来进行分发,如下图所示。
2.InputDispatcher的分发过程
不同的事件类型有着不同的分发过程,其中Swich事件的处理是没有派发过程的,在InputDispatcher的notifySwitch函数中会将Swich事件交由InputDispatcherPolicy来处理。本系列文章一直讲解key事件相关,这次换一下,以Motion事件的分发过程来进行举例,对key事件分发事件有兴趣的可以自行去看源码,本质上都差不多。
2.1 唤醒InputDispatcherThread
InputDispatcher的notifyMotion函数用来唤醒InputDispatcherThread。
frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::notifyMotion(const NotifyMotionArgs*