三、另一个线程InputDispatchThread,它的实现核心是InputDispatch。
InputDispatchThread和InputReaderThread是要协同工作的,那是怎么协作的呢?
前面说过这两个线程是在frameworks/native/services/inputflinger/InputManager.cpp中创建的。
InputManager::InputManager(...){
mDispatcher= new InputDispatcher(dispatcherPolicy);
mReader= new InputReader(eventHub, readerPolicy, mDispatcher);
}
在创建时,就将InputReader和InputDispatch建立了关联。在InputReader的looponce中,事件是通过InputDispatch来送到Listener的。
void InputReader::loopOnce()@InputReader.cpp{
mQueuedListener->flush();
}
这里的 mQueuedListener实际是对InputDispatch的一个封装。
这样InputDispatch就可以持续获取到设备中发生的事件。并且可以向InputReader注册监听多种事件。
class QueuedInputListener : publicInputListenerInterface {
virtual void notifyConfigurationChanged(constNotifyConfigurationChangedArgs* args);
virtual void notifyKey(const NotifyKeyArgs* args);
virtual void notifyMotion(const NotifyMotionArgs* args);
virtual void notifySwitch(const NotifySwitchArgs* args);
virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
}
我们以key事件为例,看下是怎么注册这个监听的?
源头在EventHub,我们知道EventHub负责原始事件的读取,然后通知到InputReader,EventHub还监听设备的插拔,当然这也是事件。
voidInputReader::loopOnce()@InputReader.cpp{
size_tcount = mEventHub->getEvents(timeoutMillis, mEventBuffer,
EVENT_BUFFER_SIZE);
if (count) {
processEventsLocked(mEventBuffer, count);
}
}
getEvents是EventHub很重要的一个方法,就是获取原事件,接着的 processEventsLocked开始处理事件。
如果是添加了输入设备,我们知道系统肯定是要创建一个输入设备的,
void InputReader::processEventsLocked(constRawEvent* rawEvents, size_t count) {
//这里实际是一个循环,处理读取到的所有原始事件。
RawEvent*rawEvent = rawEvents;
switch(rawEvent->type) {
caseEventHubInterface::DEVICE_ADDED:
addDeviceLocked(rawEvent->when,rawEvent->deviceId);
}
}
我们直接找往InputReader注册监听的地方
void InputReader::addDeviceLocked(nsecs_twhen, int32_t deviceId) {
InputDevice*device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
}
InputDevice*InputReader::createDeviceLocked(...){
//Keyboard-like devices.
uint32_tkeyboardSource = 0;
int32_t keyboardType =AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
if (classes & INPUT_DEVICE_CLASS_KEYBOARD){
keyboardSource |= AINPUT_SOURCE_KEYBOARD;
}
if (classes &INPUT_DEVICE_CLASS_ALPHAKEY) {
keyboardType =AINPUT_KEYBOARD_TYPE_ALPHABETIC;
}
if (classes & INPUT_DEVICE_CLASS_DPAD){
keyboardSource |= AINPUT_SOURCE_DPAD;
}
if (classes &INPUT_DEVICE_CLASS_GAMEPAD) {
keyboardSource |= AINPUT_SOURCE_GAMEPAD;
}
if (keyboardSource != 0) {
device->addMapper(newKeyboardInputMapper(device, keyboardSource, keyboardType));
}
}
这样就把键盘设备添加到了Vector
接下来会执行 mMappers的所有设备的process()方法,当然也会执行到KeyboardInputMapper的process方法。
void KeyboardInputMapper::process(constRawEvent* rawEvent) {
if (isKeyboardOrGamepadKey(scanCode)) {
processKey(rawEvent->when, rawEvent->value != 0, scanCode,usageCode);
}
}
void KeyboardInputMapper::processKey(nsecs_twhen, bool down, int32_t scanCode,
int32_t usageCode) {
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState,
downTime);
getListener()->notifyKey(&args);
}
这里获取的listener实际就是InputReader中mQueuedListener,我们看mQueuedListener的处理。
void QueuedInputListener::notifyKey(constNotifyKeyArgs* args) @InputListener.cpp{
mArgsQueue.push(new NotifyKeyArgs(*args));
}
也就是把NotifyKeyArgs这个实例添加到Vector
还记得前面说InputReader的looponce中,把事件通知给监听这是通过mQueuedListener->flush();就是下面的这个方法,
void QueuedInputListener::flush() {
size_t count = mArgsQueue.size();
for (size_t i = 0; i < count; i++) {
NotifyArgs* args = mArgsQueue[i];
args->notify(mInnerListener);
delete args;
}
mArgsQueue.clear();
}
在这个方法中会回调具体实例的notify函数,
比如 NotifyKeyArgs的notify函数。
void NotifyKeyArgs::notify(constsp
listener->notifyKey(this);
}
注意这里的 mInnerListener来自QueuedInputListener的构造函数,
QueuedInputListener::QueuedInputListener(constsp
mInnerListener(innerListener) {
}
QueuedInputListener又是在InputReader的构造函数实例话的,同时传入的参数是const sp
class InputDispatcher : publicInputDispatcherInterface ;
class InputDispatcherInterface : publicvirtual RefBase, public InputListenerInterface ;
InputDispatch间接继承了 InputListenerInterface。
通过这个过程,InputReader就把事件传到了InputDispatch。