Skip to content

Commit aedbed0

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge changes Iaec9079d,I8d86f56f into main
* changes: EventHub: Reimplement sysfsNodeChanged EventHub: Refactor AssociatedDevice creation logic
2 parents 2def5e5 + 7fb7187 commit aedbed0

2 files changed

Lines changed: 73 additions & 53 deletions

File tree

services/inputflinger/reader/EventHub.cpp

Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,41 +1620,43 @@ std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDevi
16201620

16211621
const auto& path = *sysfsRootPathOpt;
16221622

1623-
std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>(
1624-
AssociatedDevice{.sysfsRootPath = path,
1625-
.batteryInfos = readBatteryConfiguration(path),
1626-
.lightInfos = readLightsConfiguration(path),
1627-
.layoutInfo = readLayoutConfiguration(path)});
1628-
1629-
bool associatedDeviceChanged = false;
1623+
std::shared_ptr<const AssociatedDevice> associatedDevice;
16301624
for (const auto& [id, dev] : mDevices) {
1631-
if (dev->associatedDevice && dev->associatedDevice->sysfsRootPath == path) {
1632-
if (*associatedDevice != *dev->associatedDevice) {
1633-
associatedDeviceChanged = true;
1634-
dev->associatedDevice = associatedDevice;
1635-
}
1625+
if (!dev->associatedDevice || dev->associatedDevice->sysfsRootPath != path) {
1626+
continue;
1627+
}
1628+
if (!associatedDevice) {
1629+
// Found matching associated device for the first time.
16361630
associatedDevice = dev->associatedDevice;
1631+
// Reload this associated device if needed.
1632+
const auto reloadedDevice = AssociatedDevice(path);
1633+
if (reloadedDevice != *dev->associatedDevice) {
1634+
ALOGI("The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s",
1635+
path.c_str(), associatedDevice->dump().c_str());
1636+
associatedDevice = std::make_shared<AssociatedDevice>(std::move(reloadedDevice));
1637+
}
16371638
}
1639+
// Update the associatedDevice.
1640+
dev->associatedDevice = associatedDevice;
1641+
}
1642+
1643+
if (!associatedDevice) {
1644+
// No existing associated device found for this path, so create a new one.
1645+
associatedDevice = std::make_shared<AssociatedDevice>(path);
16381646
}
1639-
ALOGI_IF(associatedDeviceChanged,
1640-
"The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s",
1641-
path.c_str(), associatedDevice->dump().c_str());
16421647

16431648
return associatedDevice;
16441649
}
16451650

1646-
bool EventHub::AssociatedDevice::isChanged() const {
1647-
std::unordered_map<int32_t, RawBatteryInfo> newBatteryInfos =
1648-
readBatteryConfiguration(sysfsRootPath);
1649-
std::unordered_map<int32_t, RawLightInfo> newLightInfos =
1650-
readLightsConfiguration(sysfsRootPath);
1651-
std::optional<RawLayoutInfo> newLayoutInfo = readLayoutConfiguration(sysfsRootPath);
1651+
EventHub::AssociatedDevice::AssociatedDevice(const std::filesystem::path& sysfsRootPath)
1652+
: sysfsRootPath(sysfsRootPath),
1653+
batteryInfos(readBatteryConfiguration(sysfsRootPath)),
1654+
lightInfos(readLightsConfiguration(sysfsRootPath)),
1655+
layoutInfo(readLayoutConfiguration(sysfsRootPath)) {}
16521656

1653-
if (newBatteryInfos == batteryInfos && newLightInfos == lightInfos &&
1654-
newLayoutInfo == layoutInfo) {
1655-
return false;
1656-
}
1657-
return true;
1657+
std::string EventHub::AssociatedDevice::dump() const {
1658+
return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(),
1659+
batteryInfos.size(), lightInfos.size());
16581660
}
16591661

16601662
void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) {
@@ -2646,33 +2648,56 @@ status_t EventHub::disableDevice(int32_t deviceId) {
26462648
void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
26472649
std::scoped_lock _l(mLock);
26482650

2649-
// Check in opening devices
2650-
for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end(); it++) {
2651-
std::unique_ptr<Device>& device = *it;
2652-
if (device->associatedDevice &&
2653-
sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
2654-
std::string::npos &&
2655-
device->associatedDevice->isChanged()) {
2656-
it = mOpeningDevices.erase(it);
2657-
openDeviceLocked(device->path);
2651+
// Testing whether a sysfs node changed involves several syscalls, so use a cache to avoid
2652+
// testing the same node multiple times.
2653+
std::map<std::shared_ptr<const AssociatedDevice>, bool /*changed*/> testedDevices;
2654+
auto isAssociatedDeviceChanged = [&testedDevices, &sysfsNodePath](const Device& dev) {
2655+
if (!dev.associatedDevice) {
2656+
return false;
26582657
}
2659-
}
2658+
if (auto testedIt = testedDevices.find(dev.associatedDevice);
2659+
testedIt != testedDevices.end()) {
2660+
return testedIt->second;
2661+
}
2662+
// Cache miss
2663+
if (sysfsNodePath.find(dev.associatedDevice->sysfsRootPath.string()) == std::string::npos) {
2664+
testedDevices.emplace(dev.associatedDevice, false);
2665+
return false;
2666+
}
2667+
auto reloadedDevice = AssociatedDevice(dev.associatedDevice->sysfsRootPath);
2668+
const bool changed = *dev.associatedDevice != reloadedDevice;
2669+
testedDevices.emplace(dev.associatedDevice, changed);
2670+
return changed;
2671+
};
26602672

2661-
// Check in already added device
2662-
std::vector<Device*> devicesToReopen;
2663-
for (const auto& [id, device] : mDevices) {
2664-
if (device->associatedDevice &&
2665-
sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
2666-
std::string::npos &&
2667-
device->associatedDevice->isChanged()) {
2668-
devicesToReopen.push_back(device.get());
2673+
std::set<Device*> devicesToClose;
2674+
std::set<std::string /*path*/> devicesToOpen;
2675+
2676+
// Check in opening devices. If its associated device changed,
2677+
// the device should be removed from mOpeningDevices and needs to be opened again.
2678+
std::erase_if(mOpeningDevices, [&](const auto& dev) {
2679+
if (isAssociatedDeviceChanged(*dev)) {
2680+
devicesToOpen.emplace(dev->path);
2681+
return true;
2682+
}
2683+
return false;
2684+
});
2685+
2686+
// Check in already added device. If its associated device changed,
2687+
// the device needs to be re-opened.
2688+
for (const auto& [id, dev] : mDevices) {
2689+
if (isAssociatedDeviceChanged(*dev)) {
2690+
devicesToOpen.emplace(dev->path);
2691+
devicesToClose.emplace(dev.get());
26692692
}
26702693
}
2671-
for (const auto& device : devicesToReopen) {
2694+
2695+
for (auto* device : devicesToClose) {
26722696
closeDeviceLocked(*device);
2673-
openDeviceLocked(device->path);
26742697
}
2675-
devicesToReopen.clear();
2698+
for (const auto& path : devicesToOpen) {
2699+
openDeviceLocked(path);
2700+
}
26762701
}
26772702

26782703
void EventHub::createVirtualKeyboardLocked() {
@@ -2972,9 +2997,4 @@ void EventHub::monitor() const {
29722997
std::unique_lock<std::mutex> lock(mLock);
29732998
}
29742999

2975-
std::string EventHub::AssociatedDevice::dump() const {
2976-
return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(),
2977-
batteryInfos.size(), lightInfos.size());
2978-
}
2979-
29803000
} // namespace android

services/inputflinger/reader/include/EventHub.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,13 +619,13 @@ class EventHub : public EventHubInterface {
619619
private:
620620
// Holds information about the sysfs device associated with the Device.
621621
struct AssociatedDevice {
622+
AssociatedDevice(const std::filesystem::path& sysfsRootPath);
622623
// The sysfs root path of the misc device.
623624
std::filesystem::path sysfsRootPath;
624625
std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos;
625626
std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos;
626627
std::optional<RawLayoutInfo> layoutInfo;
627628

628-
bool isChanged() const;
629629
bool operator==(const AssociatedDevice&) const = default;
630630
bool operator!=(const AssociatedDevice&) const = default;
631631
std::string dump() const;

0 commit comments

Comments
 (0)