summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-02-06 17:52:44 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-06 17:52:44 -0800
commitaedbed0cd2ce7a2caf16466f060ebee464b02b3e (patch)
tree12797698fa3e90ada962f79f6bfbed3d5eb7316e
parent2def5e59fd2c1a18b1343c03954e528860bcc141 (diff)
parent7fb7187dabe8c92b064221785ee198cb616ecef5 (diff)
Merge changes Iaec9079d,I8d86f56f into main
* changes: EventHub: Reimplement sysfsNodeChanged EventHub: Refactor AssociatedDevice creation logic
-rw-r--r--services/inputflinger/reader/EventHub.cpp124
-rw-r--r--services/inputflinger/reader/include/EventHub.h2
2 files changed, 73 insertions, 53 deletions
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 013ef862ad..3c8b6f54c1 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -1620,41 +1620,43 @@ std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDevi
const auto& path = *sysfsRootPathOpt;
- std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>(
- AssociatedDevice{.sysfsRootPath = path,
- .batteryInfos = readBatteryConfiguration(path),
- .lightInfos = readLightsConfiguration(path),
- .layoutInfo = readLayoutConfiguration(path)});
-
- bool associatedDeviceChanged = false;
+ std::shared_ptr<const AssociatedDevice> associatedDevice;
for (const auto& [id, dev] : mDevices) {
- if (dev->associatedDevice && dev->associatedDevice->sysfsRootPath == path) {
- if (*associatedDevice != *dev->associatedDevice) {
- associatedDeviceChanged = true;
- dev->associatedDevice = associatedDevice;
- }
+ if (!dev->associatedDevice || dev->associatedDevice->sysfsRootPath != path) {
+ continue;
+ }
+ if (!associatedDevice) {
+ // Found matching associated device for the first time.
associatedDevice = dev->associatedDevice;
+ // Reload this associated device if needed.
+ const auto reloadedDevice = AssociatedDevice(path);
+ if (reloadedDevice != *dev->associatedDevice) {
+ ALOGI("The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s",
+ path.c_str(), associatedDevice->dump().c_str());
+ associatedDevice = std::make_shared<AssociatedDevice>(std::move(reloadedDevice));
+ }
}
+ // Update the associatedDevice.
+ dev->associatedDevice = associatedDevice;
+ }
+
+ if (!associatedDevice) {
+ // No existing associated device found for this path, so create a new one.
+ associatedDevice = std::make_shared<AssociatedDevice>(path);
}
- ALOGI_IF(associatedDeviceChanged,
- "The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s",
- path.c_str(), associatedDevice->dump().c_str());
return associatedDevice;
}
-bool EventHub::AssociatedDevice::isChanged() const {
- std::unordered_map<int32_t, RawBatteryInfo> newBatteryInfos =
- readBatteryConfiguration(sysfsRootPath);
- std::unordered_map<int32_t, RawLightInfo> newLightInfos =
- readLightsConfiguration(sysfsRootPath);
- std::optional<RawLayoutInfo> newLayoutInfo = readLayoutConfiguration(sysfsRootPath);
+EventHub::AssociatedDevice::AssociatedDevice(const std::filesystem::path& sysfsRootPath)
+ : sysfsRootPath(sysfsRootPath),
+ batteryInfos(readBatteryConfiguration(sysfsRootPath)),
+ lightInfos(readLightsConfiguration(sysfsRootPath)),
+ layoutInfo(readLayoutConfiguration(sysfsRootPath)) {}
- if (newBatteryInfos == batteryInfos && newLightInfos == lightInfos &&
- newLayoutInfo == layoutInfo) {
- return false;
- }
- return true;
+std::string EventHub::AssociatedDevice::dump() const {
+ return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(),
+ batteryInfos.size(), lightInfos.size());
}
void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) {
@@ -2646,33 +2648,56 @@ status_t EventHub::disableDevice(int32_t deviceId) {
void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
std::scoped_lock _l(mLock);
- // Check in opening devices
- for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end(); it++) {
- std::unique_ptr<Device>& device = *it;
- if (device->associatedDevice &&
- sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
- std::string::npos &&
- device->associatedDevice->isChanged()) {
- it = mOpeningDevices.erase(it);
- openDeviceLocked(device->path);
+ // Testing whether a sysfs node changed involves several syscalls, so use a cache to avoid
+ // testing the same node multiple times.
+ std::map<std::shared_ptr<const AssociatedDevice>, bool /*changed*/> testedDevices;
+ auto isAssociatedDeviceChanged = [&testedDevices, &sysfsNodePath](const Device& dev) {
+ if (!dev.associatedDevice) {
+ return false;
}
- }
+ if (auto testedIt = testedDevices.find(dev.associatedDevice);
+ testedIt != testedDevices.end()) {
+ return testedIt->second;
+ }
+ // Cache miss
+ if (sysfsNodePath.find(dev.associatedDevice->sysfsRootPath.string()) == std::string::npos) {
+ testedDevices.emplace(dev.associatedDevice, false);
+ return false;
+ }
+ auto reloadedDevice = AssociatedDevice(dev.associatedDevice->sysfsRootPath);
+ const bool changed = *dev.associatedDevice != reloadedDevice;
+ testedDevices.emplace(dev.associatedDevice, changed);
+ return changed;
+ };
- // Check in already added device
- std::vector<Device*> devicesToReopen;
- for (const auto& [id, device] : mDevices) {
- if (device->associatedDevice &&
- sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
- std::string::npos &&
- device->associatedDevice->isChanged()) {
- devicesToReopen.push_back(device.get());
+ std::set<Device*> devicesToClose;
+ std::set<std::string /*path*/> devicesToOpen;
+
+ // Check in opening devices. If its associated device changed,
+ // the device should be removed from mOpeningDevices and needs to be opened again.
+ std::erase_if(mOpeningDevices, [&](const auto& dev) {
+ if (isAssociatedDeviceChanged(*dev)) {
+ devicesToOpen.emplace(dev->path);
+ return true;
+ }
+ return false;
+ });
+
+ // Check in already added device. If its associated device changed,
+ // the device needs to be re-opened.
+ for (const auto& [id, dev] : mDevices) {
+ if (isAssociatedDeviceChanged(*dev)) {
+ devicesToOpen.emplace(dev->path);
+ devicesToClose.emplace(dev.get());
}
}
- for (const auto& device : devicesToReopen) {
+
+ for (auto* device : devicesToClose) {
closeDeviceLocked(*device);
- openDeviceLocked(device->path);
}
- devicesToReopen.clear();
+ for (const auto& path : devicesToOpen) {
+ openDeviceLocked(path);
+ }
}
void EventHub::createVirtualKeyboardLocked() {
@@ -2972,9 +2997,4 @@ void EventHub::monitor() const {
std::unique_lock<std::mutex> lock(mLock);
}
-std::string EventHub::AssociatedDevice::dump() const {
- return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(),
- batteryInfos.size(), lightInfos.size());
-}
-
} // namespace android
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 5839b4c41c..31ac63f31e 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -619,13 +619,13 @@ public:
private:
// Holds information about the sysfs device associated with the Device.
struct AssociatedDevice {
+ AssociatedDevice(const std::filesystem::path& sysfsRootPath);
// The sysfs root path of the misc device.
std::filesystem::path sysfsRootPath;
std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos;
std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos;
std::optional<RawLayoutInfo> layoutInfo;
- bool isChanged() const;
bool operator==(const AssociatedDevice&) const = default;
bool operator!=(const AssociatedDevice&) const = default;
std::string dump() const;