Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 026a1676 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "EventHub: Process sysfs node changes from InputReader thread" into main

parents a89f063a 6f9ad773
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -1897,6 +1897,8 @@ std::vector<RawEvent> EventHub::getEvents(int timeoutMillis) {
            break; // return to the caller before we actually rescan
        }

        handleSysfsNodeChangeNotificationsLocked();

        // Report any devices that had last been added/removed.
        for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) {
            std::unique_ptr<Device> device = std::move(*it);
@@ -2669,12 +2671,25 @@ status_t EventHub::disableDevice(int32_t deviceId) {
// NETLINK socket to observe UEvents. We can create similar infrastructure on Eventhub side to
// directly observe UEvents instead of triggering from Java side.
void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
    std::scoped_lock _l(mLock);
    mChangedSysfsNodeNotifications.emplace(sysfsNodePath);
}

void EventHub::handleSysfsNodeChangeNotificationsLocked() {
    // Use a set to de-dup any repeated notifications.
    std::set<std::string> changedNodes;
    while (true) {
        auto node = mChangedSysfsNodeNotifications.popWithTimeout(std::chrono::nanoseconds(0));
        if (!node.has_value()) break;
        changedNodes.emplace(*node);
    }
    if (changedNodes.empty()) {
        return;
    }

    // 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) {
    auto isAssociatedDeviceChanged = [&testedDevices, &changedNodes](const Device& dev) {
        if (!dev.associatedDevice) {
            return false;
        }
@@ -2683,7 +2698,12 @@ void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
            return testedIt->second;
        }
        // Cache miss
        if (sysfsNodePath.find(dev.associatedDevice->sysfsRootPath.string()) == std::string::npos) {
        const bool anyNodesChanged =
                std::any_of(changedNodes.begin(), changedNodes.end(), [&](const std::string& node) {
                    return node.find(dev.associatedDevice->sysfsRootPath.string()) !=
                            std::string::npos;
                });
        if (!anyNodesChanged) {
            testedDevices.emplace(dev.associatedDevice, false);
            return false;
        }
+1 −0
Original line number Diff line number Diff line
@@ -919,6 +919,7 @@ bool InputReader::canDispatchToDisplay(int32_t deviceId, ui::LogicalDisplayId di

void InputReader::sysfsNodeChanged(const std::string& sysfsNodePath) {
    mEventHub->sysfsNodeChanged(sysfsNodePath);
    mEventHub->wake();
}

DeviceId InputReader::getLastUsedInputDeviceId() {
+7 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include <batteryservice/BatteryService.h>
#include <ftl/flags.h>
#include <input/BlockingQueue.h>
#include <input/Input.h>
#include <input/InputDevice.h>
#include <input/KeyCharacterMap.h>
@@ -775,6 +776,8 @@ private:
    void addDeviceInputInotify();
    void addDeviceInotify();

    void handleSysfsNodeChangeNotificationsLocked() REQUIRES(mLock);

    // Protect all internal state.
    mutable std::mutex mLock;

@@ -824,6 +827,10 @@ private:
    size_t mPendingEventCount;
    size_t mPendingEventIndex;
    bool mPendingINotify;

    // The sysfs node change notifications that have been sent to EventHub.
    // Enqueuing notifications does not require the lock to be held.
    BlockingQueue<std::string> mChangedSysfsNodeNotifications;
};

} // namespace android