diff options
-rw-r--r-- | services/inputflinger/reader/EventHub.cpp | 205 | ||||
-rw-r--r-- | services/inputflinger/reader/include/EventHub.h | 19 |
2 files changed, 117 insertions, 107 deletions
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp index db5032d51e..5744b83d64 100644 --- a/services/inputflinger/reader/EventHub.cpp +++ b/services/inputflinger/reader/EventHub.cpp @@ -52,6 +52,7 @@ #include <filesystem> #include <regex> +#include <utility> #include "EventHub.h" @@ -193,8 +194,7 @@ static nsecs_t processEventTimestamp(const struct input_event& event) { } /** - * Returns the sysfs root path of the input device - * + * Returns the sysfs root path of the input device. */ static std::optional<std::filesystem::path> getSysfsRootPath(const char* devicePath) { std::error_code errorCode; @@ -301,6 +301,83 @@ static std::optional<std::array<LightColor, COLOR_NUM>> getColorIndexArray( return colors; } +/** + * Read information about batteries exposed through the sysfs path. + */ +static std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> readBatteryConfiguration( + const std::filesystem::path& sysfsRootPath) { + std::unordered_map<int32_t, RawBatteryInfo> batteryInfos; + int32_t nextBatteryId = 0; + // Check if device has any battery. + const auto& paths = findSysfsNodes(sysfsRootPath, SysfsClass::POWER_SUPPLY); + for (const auto& nodePath : paths) { + RawBatteryInfo info; + info.id = ++nextBatteryId; + info.path = nodePath; + info.name = nodePath.filename(); + + // Scan the path for all the files + // Refer to https://www.kernel.org/doc/Documentation/leds/leds-class.txt + const auto& files = allFilesInPath(nodePath); + for (const auto& file : files) { + const auto it = BATTERY_CLASSES.find(file.filename().string()); + if (it != BATTERY_CLASSES.end()) { + info.flags |= it->second; + } + } + batteryInfos.insert_or_assign(info.id, info); + ALOGD("configureBatteryLocked rawBatteryId %d name %s", info.id, info.name.c_str()); + } + return batteryInfos; +} + +/** + * Read information about lights exposed through the sysfs path. + */ +static std::unordered_map<int32_t /*lightId*/, RawLightInfo> readLightsConfiguration( + const std::filesystem::path& sysfsRootPath) { + std::unordered_map<int32_t, RawLightInfo> lightInfos; + int32_t nextLightId = 0; + // Check if device has any lights. + const auto& paths = findSysfsNodes(sysfsRootPath, SysfsClass::LEDS); + for (const auto& nodePath : paths) { + RawLightInfo info; + info.id = ++nextLightId; + info.path = nodePath; + info.name = nodePath.filename(); + info.maxBrightness = std::nullopt; + size_t nameStart = info.name.rfind(":"); + if (nameStart != std::string::npos) { + // Trim the name to color name + info.name = info.name.substr(nameStart + 1); + // Set InputLightClass flag for colors + const auto it = LIGHT_CLASSES.find(info.name); + if (it != LIGHT_CLASSES.end()) { + info.flags |= it->second; + } + } + // Scan the path for all the files + // Refer to https://www.kernel.org/doc/Documentation/leds/leds-class.txt + const auto& files = allFilesInPath(nodePath); + for (const auto& file : files) { + const auto it = LIGHT_CLASSES.find(file.filename().string()); + if (it != LIGHT_CLASSES.end()) { + info.flags |= it->second; + // If the node has maximum brightness, read it + if (it->second == InputLightClass::MAX_BRIGHTNESS) { + std::string str; + if (base::ReadFileToString(file, &str)) { + info.maxBrightness = std::stoi(str); + } + } + } + } + lightInfos.insert_or_assign(info.id, info); + ALOGD("configureLightsLocked rawLightId %d name %s", info.id, info.name.c_str()); + } + return lightInfos; +} + // --- Global Functions --- ftl::Flags<InputDeviceClass> getAbsAxisUsage(int32_t axis, @@ -357,18 +434,18 @@ ftl::Flags<InputDeviceClass> getAbsAxisUsage(int32_t axis, // --- EventHub::Device --- -EventHub::Device::Device(int fd, int32_t id, const std::string& path, - const InputDeviceIdentifier& identifier) +EventHub::Device::Device(int fd, int32_t id, std::string path, InputDeviceIdentifier identifier, + std::shared_ptr<const AssociatedDevice> assocDev) : fd(fd), id(id), - path(path), - identifier(identifier), + path(std::move(path)), + identifier(std::move(identifier)), classes(0), configuration(nullptr), virtualKeyMap(nullptr), ffEffectPlaying(false), ffEffectId(-1), - associatedDevice(nullptr), + associatedDevice(std::move(assocDev)), controllerNumber(0), enabled(true), isVirtual(fd < 0) {} @@ -557,75 +634,6 @@ status_t EventHub::Device::mapLed(int32_t led, int32_t* outScanCode) const { return NAME_NOT_FOUND; } -// Check the sysfs path for any input device batteries, returns true if battery found. -bool EventHub::AssociatedDevice::configureBatteryLocked() { - nextBatteryId = 0; - // Check if device has any battery. - const auto& paths = findSysfsNodes(sysfsRootPath, SysfsClass::POWER_SUPPLY); - for (const auto& nodePath : paths) { - RawBatteryInfo info; - info.id = ++nextBatteryId; - info.path = nodePath; - info.name = nodePath.filename(); - - // Scan the path for all the files - // Refer to https://www.kernel.org/doc/Documentation/leds/leds-class.txt - const auto& files = allFilesInPath(nodePath); - for (const auto& file : files) { - const auto it = BATTERY_CLASSES.find(file.filename().string()); - if (it != BATTERY_CLASSES.end()) { - info.flags |= it->second; - } - } - batteryInfos.insert_or_assign(info.id, info); - ALOGD("configureBatteryLocked rawBatteryId %d name %s", info.id, info.name.c_str()); - } - return !batteryInfos.empty(); -} - -// Check the sysfs path for any input device lights, returns true if lights found. -bool EventHub::AssociatedDevice::configureLightsLocked() { - nextLightId = 0; - // Check if device has any lights. - const auto& paths = findSysfsNodes(sysfsRootPath, SysfsClass::LEDS); - for (const auto& nodePath : paths) { - RawLightInfo info; - info.id = ++nextLightId; - info.path = nodePath; - info.name = nodePath.filename(); - info.maxBrightness = std::nullopt; - size_t nameStart = info.name.rfind(":"); - if (nameStart != std::string::npos) { - // Trim the name to color name - info.name = info.name.substr(nameStart + 1); - // Set InputLightClass flag for colors - const auto it = LIGHT_CLASSES.find(info.name); - if (it != LIGHT_CLASSES.end()) { - info.flags |= it->second; - } - } - // Scan the path for all the files - // Refer to https://www.kernel.org/doc/Documentation/leds/leds-class.txt - const auto& files = allFilesInPath(nodePath); - for (const auto& file : files) { - const auto it = LIGHT_CLASSES.find(file.filename().string()); - if (it != LIGHT_CLASSES.end()) { - info.flags |= it->second; - // If the node has maximum brightness, read it - if (it->second == InputLightClass::MAX_BRIGHTNESS) { - std::string str; - if (base::ReadFileToString(file, &str)) { - info.maxBrightness = std::stoi(str); - } - } - } - } - lightInfos.insert_or_assign(info.id, info); - ALOGD("configureLightsLocked rawLightId %d name %s", info.id, info.name.c_str()); - } - return !lightInfos.empty(); -} - /** * Get the capabilities for the current process. * Crashes the system if unable to create / check / destroy the capabilities object. @@ -1358,6 +1366,27 @@ void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) { identifier.descriptor.c_str()); } +std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDeviceLocked( + const std::filesystem::path& devicePath) const { + const std::optional<std::filesystem::path> sysfsRootPathOpt = + getSysfsRootPath(devicePath.c_str()); + if (!sysfsRootPathOpt) { + return nullptr; + } + + const auto& path = *sysfsRootPathOpt; + for (const auto& [id, dev] : mDevices) { + if (dev->associatedDevice && dev->associatedDevice->sysfsRootPath == path) { + return dev->associatedDevice; + } + } + + return std::make_shared<AssociatedDevice>( + AssociatedDevice{.sysfsRootPath = path, + .batteryInfos = readBatteryConfiguration(path), + .lightInfos = readLightsConfiguration(path)}); +} + void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) { std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); @@ -2024,7 +2053,9 @@ void EventHub::openDeviceLocked(const std::string& devicePath) { // Allocate device. (The device object takes ownership of the fd at this point.) int32_t deviceId = mNextDeviceId++; - std::unique_ptr<Device> device = std::make_unique<Device>(fd, deviceId, devicePath, identifier); + std::unique_ptr<Device> device = + std::make_unique<Device>(fd, deviceId, devicePath, identifier, + obtainAssociatedDeviceLocked(devicePath)); ALOGV("add device %d: %s\n", deviceId, devicePath.c_str()); ALOGV(" bus: %04x\n" @@ -2042,24 +2073,6 @@ void EventHub::openDeviceLocked(const std::string& devicePath) { // Load the configuration file for the device. device->loadConfigurationLocked(); - // Check the sysfs root path - const std::optional<std::filesystem::path> sysfsRootPath = getSysfsRootPath(devicePath.c_str()); - if (sysfsRootPath.has_value()) { - std::shared_ptr<AssociatedDevice> associatedDevice; - for (const auto& [id, dev] : mDevices) { - if (dev->associatedDevice && dev->associatedDevice->sysfsRootPath == *sysfsRootPath) { - associatedDevice = dev->associatedDevice; - } - } - if (!associatedDevice) { - associatedDevice = std::make_shared<AssociatedDevice>(sysfsRootPath.value()); - associatedDevice->configureBatteryLocked(); - associatedDevice->configureLightsLocked(); - } - - device->associatedDevice = associatedDevice; - } - // Figure out the kinds of events the device reports. device->readDeviceBitMask(EVIOCGBIT(EV_KEY, 0), device->keyBitmask); device->readDeviceBitMask(EVIOCGBIT(EV_ABS, 0), device->absBitmask); @@ -2337,7 +2350,7 @@ void EventHub::createVirtualKeyboardLocked() { std::unique_ptr<Device> device = std::make_unique<Device>(-1, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, "<virtual>", - identifier); + identifier, nullptr /*associatedDevice*/); device->classes = InputDeviceClass::KEYBOARD | InputDeviceClass::ALPHAKEY | InputDeviceClass::DPAD | InputDeviceClass::VIRTUAL; device->loadKeyMapLocked(); diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h index 7d4196a05c..60460b4105 100644 --- a/services/inputflinger/reader/include/EventHub.h +++ b/services/inputflinger/reader/include/EventHub.h @@ -537,18 +537,13 @@ public: ~EventHub() override; private: + // Holds information about the sysfs device associated with the Device. struct AssociatedDevice { // The sysfs root path of the misc device. std::filesystem::path sysfsRootPath; - int32_t nextBatteryId; - int32_t nextLightId; - std::unordered_map<int32_t, RawBatteryInfo> batteryInfos; - std::unordered_map<int32_t, RawLightInfo> lightInfos; - explicit AssociatedDevice(std::filesystem::path sysfsRootPath) - : sysfsRootPath(sysfsRootPath), nextBatteryId(0), nextLightId(0) {} - bool configureBatteryLocked(); - bool configureLightsLocked(); + std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos; + std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos; }; struct Device { @@ -582,12 +577,12 @@ private: // A shared_ptr of a device associated with the input device. // The input devices that have the same sysfs path have the same associated device. - std::shared_ptr<AssociatedDevice> associatedDevice; + const std::shared_ptr<const AssociatedDevice> associatedDevice; int32_t controllerNumber; - Device(int fd, int32_t id, const std::string& path, - const InputDeviceIdentifier& identifier); + Device(int fd, int32_t id, std::string path, InputDeviceIdentifier identifier, + std::shared_ptr<const AssociatedDevice> assocDev); ~Device(); void close(); @@ -632,6 +627,8 @@ private: void createVirtualKeyboardLocked() REQUIRES(mLock); void addDeviceLocked(std::unique_ptr<Device> device) REQUIRES(mLock); void assignDescriptorLocked(InputDeviceIdentifier& identifier) REQUIRES(mLock); + std::shared_ptr<const AssociatedDevice> obtainAssociatedDeviceLocked( + const std::filesystem::path& devicePath) const REQUIRES(mLock); void closeDeviceByPathLocked(const std::string& devicePath) REQUIRES(mLock); void closeVideoDeviceByPathLocked(const std::string& devicePath) REQUIRES(mLock); |