【安卓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

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;
    }
}
cpp 复制代码
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 对象

cpp 复制代码
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

cpp 复制代码
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

cpp 复制代码
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();
}
相关推荐
API小爬虫16 分钟前
使用PHP爬虫获取淘宝App商品详情?
android·爬虫·php
一笑的小酒馆9 小时前
Android在ksp中简单使用Room
android
meimeiqian11 小时前
flutter android端抓包工具
android·flutter
Android技术之家11 小时前
谷歌决定终止开源Android以及对开发者的影响
android·开源
每次的天空12 小时前
Android Jetpack学习总结(源码级理解)
android·学习·android jetpack
木子庆五12 小时前
Android设计模式之代理模式
android·设计模式·代理模式
在雨季等你13 小时前
创业之旅 - 反思 - 整改 - 新的方向 - 诚邀
android
Long_poem13 小时前
【自学笔记】PHP语言基础知识点总览-持续更新
android·笔记·php
fatiaozhang952714 小时前
晶晨S905L3A(B)-安卓9.0-开启ADB和ROOT-支持IPTV6-支持外置游戏系统-支持多种无线芯片-支持救砖-完美通刷线刷固件包
android·游戏·adb·华为·电视盒子·机顶盒rom·魔百盒固件
行墨15 小时前
Kotlin语言的==与===比较操作
android