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

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

Merge changes Iaec9079d,I8d86f56f into main

* changes:
  EventHub: Reimplement sysfsNodeChanged
  EventHub: Refactor AssociatedDevice creation logic
parents 2def5e59 7fb7187d
Loading
Loading
Loading
Loading
+72 −52
Original line number Original line Diff line number Diff line
@@ -1620,41 +1620,43 @@ std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDevi


    const auto& path = *sysfsRootPathOpt;
    const auto& path = *sysfsRootPathOpt;


    std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>(
    std::shared_ptr<const AssociatedDevice> associatedDevice;
            AssociatedDevice{.sysfsRootPath = path,
                             .batteryInfos = readBatteryConfiguration(path),
                             .lightInfos = readLightsConfiguration(path),
                             .layoutInfo = readLayoutConfiguration(path)});

    bool associatedDeviceChanged = false;
    for (const auto& [id, dev] : mDevices) {
    for (const auto& [id, dev] : mDevices) {
        if (dev->associatedDevice && dev->associatedDevice->sysfsRootPath == path) {
        if (!dev->associatedDevice || dev->associatedDevice->sysfsRootPath != path) {
            if (*associatedDevice != *dev->associatedDevice) {
            continue;
                associatedDeviceChanged = true;
                dev->associatedDevice = associatedDevice;
        }
        }
        if (!associatedDevice) {
            // Found matching associated device for the first time.
            associatedDevice = dev->associatedDevice;
            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));
            }
            }
        }
        }
    ALOGI_IF(associatedDeviceChanged,
        // Update the associatedDevice.
             "The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s",
        dev->associatedDevice = associatedDevice;
             path.c_str(), associatedDevice->dump().c_str());
    }

    if (!associatedDevice) {
        // No existing associated device found for this path, so create a new one.
        associatedDevice = std::make_shared<AssociatedDevice>(path);
    }


    return associatedDevice;
    return associatedDevice;
}
}


bool EventHub::AssociatedDevice::isChanged() const {
EventHub::AssociatedDevice::AssociatedDevice(const std::filesystem::path& sysfsRootPath)
    std::unordered_map<int32_t, RawBatteryInfo> newBatteryInfos =
      : sysfsRootPath(sysfsRootPath),
            readBatteryConfiguration(sysfsRootPath);
        batteryInfos(readBatteryConfiguration(sysfsRootPath)),
    std::unordered_map<int32_t, RawLightInfo> newLightInfos =
        lightInfos(readLightsConfiguration(sysfsRootPath)),
            readLightsConfiguration(sysfsRootPath);
        layoutInfo(readLayoutConfiguration(sysfsRootPath)) {}
    std::optional<RawLayoutInfo> newLayoutInfo = readLayoutConfiguration(sysfsRootPath);


    if (newBatteryInfos == batteryInfos && newLightInfos == lightInfos &&
std::string EventHub::AssociatedDevice::dump() const {
        newLayoutInfo == layoutInfo) {
    return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(),
        return false;
                        batteryInfos.size(), lightInfos.size());
    }
    return true;
}
}


void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) {
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) {
void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(mLock);


    // Check in opening devices
    // Testing whether a sysfs node changed involves several syscalls, so use a cache to avoid
    for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end(); it++) {
    // testing the same node multiple times.
        std::unique_ptr<Device>& device = *it;
    std::map<std::shared_ptr<const AssociatedDevice>, bool /*changed*/> testedDevices;
        if (device->associatedDevice &&
    auto isAssociatedDeviceChanged = [&testedDevices, &sysfsNodePath](const Device& dev) {
            sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
        if (!dev.associatedDevice) {
                    std::string::npos &&
            return false;
            device->associatedDevice->isChanged()) {
        }
            it = mOpeningDevices.erase(it);
        if (auto testedIt = testedDevices.find(dev.associatedDevice);
            openDeviceLocked(device->path);
            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::set<Device*> devicesToClose;
    std::vector<Device*> devicesToReopen;
    std::set<std::string /*path*/> devicesToOpen;
    for (const auto& [id, device] : mDevices) {

        if (device->associatedDevice &&
    // Check in opening devices. If its associated device changed,
            sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
    // the device should be removed from mOpeningDevices and needs to be opened again.
                    std::string::npos &&
    std::erase_if(mOpeningDevices, [&](const auto& dev) {
            device->associatedDevice->isChanged()) {
        if (isAssociatedDeviceChanged(*dev)) {
            devicesToReopen.push_back(device.get());
            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);
        closeDeviceLocked(*device);
        openDeviceLocked(device->path);
    }
    }
    devicesToReopen.clear();
    for (const auto& path : devicesToOpen) {
        openDeviceLocked(path);
    }
}
}


void EventHub::createVirtualKeyboardLocked() {
void EventHub::createVirtualKeyboardLocked() {
@@ -2972,9 +2997,4 @@ void EventHub::monitor() const {
    std::unique_lock<std::mutex> lock(mLock);
    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
} // namespace android
+1 −1
Original line number Original line Diff line number Diff line
@@ -619,13 +619,13 @@ public:
private:
private:
    // Holds information about the sysfs device associated with the Device.
    // Holds information about the sysfs device associated with the Device.
    struct AssociatedDevice {
    struct AssociatedDevice {
        AssociatedDevice(const std::filesystem::path& sysfsRootPath);
        // The sysfs root path of the misc device.
        // The sysfs root path of the misc device.
        std::filesystem::path sysfsRootPath;
        std::filesystem::path sysfsRootPath;
        std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos;
        std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos;
        std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos;
        std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos;
        std::optional<RawLayoutInfo> layoutInfo;
        std::optional<RawLayoutInfo> layoutInfo;


        bool isChanged() const;
        bool operator==(const AssociatedDevice&) const = default;
        bool operator==(const AssociatedDevice&) const = default;
        bool operator!=(const AssociatedDevice&) const = default;
        bool operator!=(const AssociatedDevice&) const = default;
        std::string dump() const;
        std::string dump() const;