【安卓13 源码】Input子系统(3) - EventHub增加设备的流程
由前面的分析知道,在创建inputreader 线程的时候,会去循环执行 looponce 方法。主要的处理工作是:
- 通过 getEvents() 从 EventHub 获取未处理的事件,这些事件分为两类:一类是原始输入事 件即从设备节点中读取出的原始事件;一类是设备事件即输入设备可用性变化事件
- 通过 processEventsLocked() 对事件进行预处理
/frameworks/native/services/inputflinger/reader/InputReader.cpp
void InputReader::loopOnce() {
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
std::vector<InputDeviceInfo> inputDevices;
{ // acquire lock
std::scoped_lock _l(mLock);
oldGeneration = mGeneration;
timeoutMillis = -1;
uint32_t changes = mConfigurationChangesToRefresh;
if (changes) {
mConfigurationChangesToRefresh = 0;
timeoutMillis = 0;
refreshConfigurationLocked(changes);
} else if (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
}
} // release lock
// 1)首先去eventhub 中获取事件,缓存到 mEventBuffer
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
{ // acquire lock
std::scoped_lock _l(mLock);
mReaderIsAliveCondition.notify_all();
if (count) {
// 2)对 mEventBuffer 事件进行处理
processEventsLocked(mEventBuffer, count);
}
1)首先去eventhub 中获取事件,缓存到 mEventBuffer
/frameworks/native/services/inputflinger/reader/EventHub.cpp
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
ALOG_ASSERT(bufferSize >= 1);
std::scoped_lock _l(mLock);
。。。。
// 初始值 mNeedToScanDevices 是为true 的
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
// 去扫描设备 scanDevicesLocked
scanDevicesLocked();
mNeedToSendFinishedDeviceScan = true;
}
// 遍历所有的打开的设备mOpeningDevices
while (!mOpeningDevices.empty()) {
// 获取设备 Device
std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin());
mOpeningDevices.pop_back();
ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str());
event->when = now;
event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
// 设置event事件类型是增加的DEVICE_ADDED
event->type = DEVICE_ADDED;
event += 1;
// Try to find a matching video device by comparing device names
for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end();
it++) {
std::unique_ptr<TouchVideoDevice>& videoDevice = *it;
if (tryAddVideoDeviceLocked(*device, videoDevice)) {
// videoDevice was transferred to 'device'
it = mUnattachedVideoDevices.erase(it);
break;
}
}
// 然后将设备的id和设备保存到 mDevices 中
auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device));
// 扫描设备 scanDevicesLocked
// 扫描设备,path 为:DEVICE_PATH = "/dev/input";
void EventHub::scanDevicesLocked() {
status_t result = scanDirLocked(DEVICE_PATH);
=======
status_t EventHub::scanDirLocked(const std::string& dirname) {
for (const auto& entry : std::filesystem::directory_iterator(dirname)) {
// 打开所有的设备
openDeviceLocked(entry.path());
}
=======
void EventHub::openDeviceLocked(const std::string& devicePath) {
ALOGV("Opening device: %s", devicePath.c_str());
// 打开驱动设备
int fd = open(devicePath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
。。。。。
// Allocate device. (The device object takes ownership of the fd at this point.)
int32_t deviceId = mNextDeviceId++;
// 创建 Device 对象
std::unique_ptr<Device> device = std::make_unique<Device>(fd, deviceId, devicePath, identifier);
。。。。
device->configureFd();
// 增肌 device,会打印下列log
ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=%s, "
"configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, ",
deviceId, fd, devicePath.c_str(), device->identifier.name.c_str(),
device->classes.string().c_str(), device->configurationFile.c_str(),
device->keyMap.keyLayoutFile.c_str(), device->keyMap.keyCharacterMapFile.c_str(),
toString(mBuiltInKeyboardId == deviceId));
// 将其增加到map 中
addDeviceLocked(std::move(device));
}
======
void EventHub::addDeviceLocked(std::unique_ptr<Device> device) {
reportDeviceAddedForStatisticsLocked(device->identifier, device->classes);
// 将其保存到已经打开的设备map 中mOpeningDevices
mOpeningDevices.push_back(std::move(device));
}
eventhub 将打开的设备保存到了 mOpeningDevices 中,在 InputReader 调用eventhub getevents的时候,去获取 mOpeningDevices先去eventhub 中获取事件,缓存到 mEventBuffer
2)对 mEventBuffer 事件进行处理
设置事件类型是增加的DEVICE_ADDED ,然后在inputreader 线程中处理 processEventsLocked
/frameworks/native/services/inputflinger/reader/InputReader.cpp
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: %zu Count: %zu", 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;
}
}
void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
if (mDevices.find(eventHubId) != mDevices.end()) {
ALOGW("Ignoring spurious device added event for eventHubId %d.", eventHubId);
return;
}
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
// 依据设备的id 创建了 inputdevice 对象
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
device->configure(when, &mConfig, 0);
device->reset(when);
if (device->isIgnored()) {
ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
"(ignored non-input device)",
device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str());
} else {
// 会打印下列log 增加了设备
ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s',sources=0x%08x",
device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str(),
device->getSources());
}
// 将id 和对应的device 增加到了 mDevices 中
mDevices.emplace(eventHubId, device);
// Add device to device to EventHub ids map.
const auto mapIt = mDeviceToEventHubIdsMap.find(device);
if (mapIt == mDeviceToEventHubIdsMap.end()) {
std::vector<int32_t> ids = {eventHubId};
mDeviceToEventHubIdsMap.emplace(device, ids);
} else {
mapIt->second.push_back(eventHubId);
}
bumpGenerationLocked();
// 依据设备的id 创建了 inputdevice 对象
std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
int32_t eventHubId, const InputDeviceIdentifier& identifier) {
auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) {
return devicePair.second->getDescriptor().size() && identifier.descriptor.size() &&
devicePair.second->getDescriptor() == identifier.descriptor;
});
std::shared_ptr<InputDevice> device;
if (deviceIt != mDevices.end()) {
device = deviceIt->second;
} else {
int32_t deviceId = (eventHubId < END_RESERVED_ID) ? eventHubId : nextInputDeviceIdLocked();
// 创建了 InputDevice 对象
device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
identifier);
}
// 调用方法 addEventHubDevice
device->addEventHubDevice(eventHubId);
return device;
}
// 调用方法 addEventHubDevice
/frameworks/native/services/inputflinger/reader/InputDevice.cpp
New device: id=2, fd=246, path='/dev/input/event4', name='adaptive_ts', classes=TOUCH | TOUCH_MT
void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
if (mDevices.find(eventHubId) != mDevices.end()) {
return;
}
/ / 创建了 InputDeviceContext 对象,传入this 对象和 eventHubId
std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
Flags<InputDeviceClass> classes = contextPtr->getDeviceClasses();
std::vector<std::unique_ptr<InputMapper>> mappers;
// Check if we should skip population
if (!populateMappers) {
mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
return;
}
// 然后依据不同的设备创建不同的 mapper:SwitchInputMapper
// 将其放到 mappers 中
// Switch-like devices.
if (classes.test(InputDeviceClass::SWITCH)) {
mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
}
// 下列是多点触控和单触控的
// Touchscreens and touchpad devices.
if (classes.test(InputDeviceClass::TOUCH_MT)) {
mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
} else if (classes.test(InputDeviceClass::TOUCH)) {
mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
}
。。。。
// insert the context into the devices set
// 最后将其保存到 mDevices 中
mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
MultiTouchInputMapper 多点触控是继承了 TouchInputMapper
class MultiTouchInputMapper : public TouchInputMapper
/frameworks/native/services/inputflinger/reader/mapper/InputMapper.h
47 inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
48 inline const std::string getDeviceName() { return mDeviceContext.getName(); }
49 inline InputReaderContext* getContext() { return mDeviceContext.getContext(); }
50 inline InputReaderPolicyInterface* getPolicy() { return getContext()->getPolicy(); }
// getContext 获取的值是 inputreader::contextimpl 对象,在获取getListener,则是
51 inline InputListenerInterface* getListener() { return getContext()->getListener(); }
=======
/frameworks/native/services/inputflinger/reader/InputReader.cpp
InputListenerInterface* InputReader::ContextImpl::getListener() {
// 获取的是 mQueuedListener
return mReader->mQueuedListener.get();
}