之前分析说getEvent()返回原始结果到InputReader,今天针对InputReader对getevent返回的结果进行分析:
首先我们看看InputReader在哪里调用getEvent()方法.
void InputReader::loopOnce() {
...
{ // acquire lock
AutoMutex _l(mLock);
...
timeoutMillis = 0;
// 如果配置信息修改过则更新配置信息
refreshConfigurationLocked(changes);
...
} // release lock
....
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
{ // acquire lock
...
processEventsLocked(mEventBuffer, count);
getInputDevicesLocked(inputDevices);
....
} // release lock
// Send out a message that the describes the changed input devices.
if (inputDevicesChanged) {
mPolicy->notifyInputDevicesChanged(inputDevices);
}
...
mQueuedListener->flush();
}
其中我们先要知道这个loopOnce()是在InputReaderThread执行的.InputReaderThread是在InputManager中起的.
在这个loopOnce方法中我们可以看到,需要做的事就是以下内容:
在processEventsLocked()方法中,先要判断事件类型,如果是发生设备设备的增删扫描,则调用相应的方法进行处理,这里先不对增删扫描进行分析,主要对已经注册好的事件触发进行处理。type 接下来我们看看processEventsForDeviceLocked()方法干了些什么 可以看出processEventsForDeviceLocked()中通过deviceId找到InputDevice 对应的设备事件类型,然后判断是不是要将此次事件忽略,如果不忽略,则会调用InputDevice 的process()方法进行处理。我们继续来看InputDevice 的process()干了些什么: 以上代码主要是调用所有的Mapper,调用每个Mapper的process()方法进行处理,当然不是所有的Mapper都会对一个事件进行处理,只有与事件对应的Mapper才会进行处理。那么有多少个Mapper呢? 我们可以在InputReader.h头文件中可以看到有很对对应的Mapper:(下面只列出部分) 这里我们 在keyboardInputMapper的proces()代码我们可以看出它的主要工作: 当RawEvent->type为EV_KEY时,说明是按键类Input事件,则调用processKey对它进行处理。 在processKey()方法中: 调用getListener()->notifyKey(&args)调用的是QueuedInputListener的notifyKey函数,它里边有许多notifyXXX函数,做的事情都是将NotifyXXXArgs放入它的mArgsQueue队列中存储,等待处理。 再回到processEventsLocked,当事件类型为增删和扫描后,需要分别处理 以addDeviceLocked()来看看会怎么处理 addDeviceLocked主要的工作就是,创建新的InputDevice,然后再讲新创建的InputDevice对象放到mDevices中。 相同的,removeDeviceLocked则需要将mDevices对相应的InputDevice删除 handleConfigurationChangedLocked() 的工作就是重置全局元状态 ,修改配置列表,并通知mQueuedListener。 它就是把mDevices中不需要被忽略的InputDevice取出来放入参数outInputDevices,也就是loopOnce中的inputDevices。 InputDevice添加完成后,调用InputManagerService的notifyInputDevicesChanged函数通知系统输入设备信息需要更新。 处理设备的增删,预处理、归类事件,将事件放入事件队列,通知系统更新设备信息后,当然就是要通知InputDispatcher取出事件队列中的事件进行处理了。 flush()将事件传到InputDispatcher. 在flush中,循环取出队列里的NotifyXXXArgs(有多种,例如NotifyKeyArgs、NotifyMotionArgs),调用它的notify函数通知mInnerListener,也就是InputReader创建时传入的listener,即InputDispatcher,最终会调用mInnerListener的notifyXXX函数。void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
// 在for循环中处理
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
// 判断事件类型,方满足条件是才会处理,当type
void InputReader::processEventsForDeviceLocked(int32_t deviceId,
const RawEvent* rawEvents, size_t count) {
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
if (deviceIndex < 0) {
ALOGW("Discarding event for unknown deviceId %d.", deviceId);
return;
}
InputDevice* device = mDevices.valueAt(deviceIndex);
if (device->isIgnored()) {
//ALOGD("Discarding event for ignored deviceId %d.", deviceId);
return;
}
device->process(rawEvents, count);
}
// 在这里我们对所有的事件使用对应的映射器程序进行处理。
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
// Process all of the events in order for each mapper.
// We cannot simply ask each mapper to process them in bulk because mappers may
// have side-effects that must be interleaved. For example, joystick movement events and
// gamepad button presses are handled by different mappers but they should be dispatched
// in the order received.
size_t numMappers = mMappers.size();
for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
#if DEBUG_RAW_EVENTS
ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
rawEvent->when);
#endif
if (mDropUntilNextSync) {
if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
mDropUntilNextSync = false;
#if DEBUG_RAW_EVENTS
ALOGD("Recovered from input event buffer overrun.");
#endif
} else {
#if DEBUG_RAW_EVENTS
ALOGD("Dropped input event while waiting for next input sync.");
#endif
}
} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
ALOGI("Detected input event buffer overrun for device %s.", getName().string());
mDropUntilNextSync = true;
reset(rawEvent->when);
} else {
// 如果事件不需要丢弃,需要处理的话则将便利所有的映射器,与其对应的映射器将会处理。
for (size_t i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
mapper->process(rawEvent);
}
}
--count;
}
}
...
class VibratorInputMapper : public InputMapper {
...}
...
class KeyboardInputMapper : public InputMapper {
...}
...
class CursorInputMapper : public InputMapper {
...}
...
class RotaryEncoderInputMapper : public InputMapper {
...}
...
class TouchInputMapper : public InputMapper {
...}
...
class ExternalStylusInputMapper : public InputMapper {
...}
...
class JoystickInputMapper : public InputMapper {
...}
...
就对Android设备使用比较多的touch类型的TouchInputMapper为例(我反悔。这个内容太多,我要找个简单的分析),就找个KeyBoardInputMapper为例,看看是怎么进行处理的:void KeyboardInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_KEY: {
int32_t scanCode = rawEvent->code;
int32_t usageCode = mCurrentHidUsage;
mCurrentHidUsage = 0;
if (isKeyboardOrGamepadKey(scanCode)) {
processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
}
break;
}
case EV_MSC: {
if (rawEvent->code == MSC_SCAN) {
mCurrentHidUsage = rawEvent->value;
}
break;
}
case EV_SYN: {
if (rawEvent->code == SYN_REPORT) {
mCurrentHidUsage = 0;
}
}
}
}
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode,
int32_t usageCode) {
int32_t keyCode;
int32_t keyMetaState;
uint32_t policyFlags;
if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState,
&keyCode, &keyMetaState, &policyFlags)) {
keyCode = AKEYCODE_UNKNOWN;
keyMetaState = mMetaState;
policyFlags = 0;
}
if (down) {
...
} else {
...
}
if (updateMetaStateIfNeeded(keyCode, down)) {
keyMetaState = mMetaState;
}
nsecs_t downTime = mDownTime;
if (down && getDevice()->isExternal() && !isMediaKey(keyCode)) {
policyFlags |= POLICY_FLAG_WAKE;
}
if (mParameters.handlesKeyRepeat) {
policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
}
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);
}
switch (rawEvent->type) {
case EventHubInterface::DEVICE_ADDED:
addDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
case EventHubInterface::DEVICE_REMOVED:
removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
case EventHubInterface::FINISHED_DEVICE_SCAN:
handleConfigurationChangedLocked(rawEvent->when);
break;
default:
ALOG_ASSERT(false); // can't happen
break;
}
void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
if (deviceIndex >= 0) {
ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
return;
}
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
// 通过deviceId, controllerNumber, identifier, classes来创建新的InputDevice对象
InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
device->configure(when, &mConfig, 0);
device->reset(when);
if (device->isIgnored()) {
ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
identifier.name.string());
} else {
ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
identifier.name.string(), device->getSources());
}
// 将新创建的InputDevice放到mDevices中
mDevices.add(deviceId, device);
bumpGenerationLocked();
if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
notifyExternalStylusPresenceChanged();
}
}
void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
InputDevice* device = NULL;
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
if (deviceIndex < 0) {
ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
return;
}
device = mDevices.valueAt(deviceIndex);
mDevices.removeItemsAt(deviceIndex, 1);
bumpGenerationLocked();
....
device->reset(when);
delete device;
}
void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
// Reset global meta state because it depends on the list of all configured devices.
updateGlobalMetaStateLocked();
// Enqueue configuration changed.
NotifyConfigurationChangedArgs args(when);
mQueuedListener->notifyConfigurationChanged(&args);
}
2.getInputDevicesLocked
void InputReader::getInputDevicesLocked(Vector
3. 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();
}