3,Event的获取和处理
3,1 获取
第一章中讲到, InputManagerService的start方法最后会调用InputReaderThread的run方法,开始启动线程,首先看运行方法,
bool InputReaderThread::threadLoop() {
mReader->loopOnce();
return true;
}
void InputReader::loopOnce() {
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
Vector<InputDeviceInfo> inputDevices;
{
•••
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
•••
processEventsLocked(mEventBuffer, count);
•••
mQueuedListener->flush();
•••
}loopOnce方法很长,主要做2件事情,
1,调用EventHub的getEvents方法读取Event
2,调用198. processEventsLocked方法处理Event
3, flush方法是啥,后面会逐步讲解。
为什么可以一直读取Event?因为如果没有Event,就调用epoll_wait阻塞等待。如果设备上有Event到来,将会唤醒线程,从设备中读取数据,然后再调用processEventsLocked方法处理,所以InputReaderThread线程大部分时间都是在epoll_wait上等待。
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { ••• ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32); ••• Device* device = mDevices.valueAt(deviceIndex); if (eventItem.events & EPOLLIN) { int32_t readSize = read(device->fd, readBuffer, sizeof(struct input_event) * capacity); ••• int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis); ••• }
3,2 处理
从设备中读取数据后就会调用processEventsLocked方法进行数据的处理处理
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) { for (const RawEvent* rawEvent = rawEvents; count;) { int32_t type = rawEvent->type; size_t batchSize = 1; if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) { int32_t deviceId = rawEvent->deviceId; while (batchSize < count) { if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT || rawEvent[batchSize].deviceId != deviceId) { break; } batchSize += 1; } #if DEBUG_RAW_EVENTS ALOGD("BatchSize: %d Count: %d", batchSize, count); #endif processEventsForDeviceLocked(deviceId, rawEvent, batchSize); } else { 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; } } count -= batchSize; rawEvent += batchSize; } }
processEventsLocked方法的Event方法分为2类,一类是设备发生变化的Event,主要是添加,移除和扫描设备结束3种情况,分别调用对应的方法来处理;另一类是设备产生的Event,例如键盘的按键Event,首先会从RawEvent数组中取出连续的同类Event,然后调用processEventsForDeviceLocked方法处理,
3.2.1 添加设备
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); 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()); } mDevices.add(deviceId, device); bumpGenerationLocked(); if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) { notifyExternalStylusPresenceChanged(); } }
addDeviceLocked和扫描的时候差不多,首先调用createDeviceLocked构造
InputDevice对象,然后将InputDevice添加到列表中。
InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) { InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(), controllerNumber, identifier, classes); // External devices. if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { device->setExternal(true); } // Devices with mics. if (classes & INPUT_DEVICE_CLASS_MIC) { device->setMic(true); } // Switch-like devices. if (classes & INPUT_DEVICE_CLASS_SWITCH) { device->addMapper(new SwitchInputMapper(device)); } // Vibrator-like devices. if (classes & INPUT_DEVICE_CLASS_VIBRATOR) { device->addMapper(new VibratorInputMapper(device)); } // Keyboard-like devices. uint32_t keyboardSource = 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(new KeyboardInputMapper(device, keyboardSource, keyboardType)); } // Cursor-like devices. if (classes & INPUT_DEVICE_CLASS_CURSOR) { device->addMapper(new CursorInputMapper(device)); } // Touchscreens and touchpad devices. if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) { device->addMapper(new MultiTouchInputMapper(device)); } else if (classes & INPUT_DEVICE_CLASS_TOUCH) { device->addMapper(new SingleTouchInputMapper(device)); } // Joystick-like devices. if (classes & INPUT_DEVICE_CLASS_JOYSTICK) { device->addMapper(new JoystickInputMapper(device)); } // External stylus-like devices. if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) { device->addMapper(new ExternalStylusInputMapper(device)); } return device; }
void InputDevice::addMapper(InputMapper* mapper) { mMappers.add(mapper); }
由代码可以看出,每一个输入设备都对应一个InputMapper,首先根据输入设备创建一个对应的InputMapper对象,然后将这些对象添加到mMappers中。
这些InputMapper类图关系如下:
这些类都是InputReader.cpp文件中的类。