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

Commit 5d22b76f authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Avoid UI freezing when reading battery capacity/status" am: aaa9f802...

Merge "Avoid UI freezing when reading battery capacity/status" am: aaa9f802 am: 83193e69 am: bc075eb1

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2198903



Change-Id: Ib96abbafd1d5aa2ea250ba500b49649a44d2b13c
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents f562fc15 bc075eb1
Loading
Loading
Loading
Loading
+38 −16
Original line number Diff line number Diff line
@@ -1485,6 +1485,14 @@ EventHub::Device* EventHub::getDeviceByFdLocked(int fd) const {
}

std::optional<int32_t> EventHub::getBatteryCapacity(int32_t deviceId, int32_t batteryId) const {
    std::filesystem::path batteryPath;
    {
        // Do not read the sysfs node to get the battery state while holding
        // the EventHub lock. For some peripheral devices, reading battery state
        // can be broken and take 5+ seconds. Holding the lock in this case would
        // block all other event processing during this time. For now, we assume this
        // call never happens on the InputReader thread and read the sysfs node outside
        // the lock to prevent event processing from being blocked by this call.
        std::scoped_lock _l(mLock);

        const auto infos = getBatteryInfoLocked(deviceId);
@@ -1492,18 +1500,20 @@ std::optional<int32_t> EventHub::getBatteryCapacity(int32_t deviceId, int32_t ba
        if (it == infos.end()) {
            return std::nullopt;
        }
        batteryPath = it->second.path;
    } // release lock

    std::string buffer;

    // Some devices report battery capacity as an integer through the "capacity" file
    if (base::ReadFileToString(it->second.path / BATTERY_NODES.at(InputBatteryClass::CAPACITY),
    if (base::ReadFileToString(batteryPath / BATTERY_NODES.at(InputBatteryClass::CAPACITY),
                               &buffer)) {
        return std::stoi(base::Trim(buffer));
    }

    // Other devices report capacity as an enum value POWER_SUPPLY_CAPACITY_LEVEL_XXX
    // These values are taken from kernel source code include/linux/power_supply.h
    if (base::ReadFileToString(it->second.path /
                                       BATTERY_NODES.at(InputBatteryClass::CAPACITY_LEVEL),
    if (base::ReadFileToString(batteryPath / BATTERY_NODES.at(InputBatteryClass::CAPACITY_LEVEL),
                               &buffer)) {
        // Remove any white space such as trailing new line
        const auto levelIt = BATTERY_LEVEL.find(base::Trim(buffer));
@@ -1516,15 +1526,27 @@ std::optional<int32_t> EventHub::getBatteryCapacity(int32_t deviceId, int32_t ba
}

std::optional<int32_t> EventHub::getBatteryStatus(int32_t deviceId, int32_t batteryId) const {
    std::filesystem::path batteryPath;
    {
        // Do not read the sysfs node to get the battery state while holding
        // the EventHub lock. For some peripheral devices, reading battery state
        // can be broken and take 5+ seconds. Holding the lock in this case would
        // block all other event processing during this time. For now, we assume this
        // call never happens on the InputReader thread and read the sysfs node outside
        // the lock to prevent event processing from being blocked by this call.
        std::scoped_lock _l(mLock);

        const auto infos = getBatteryInfoLocked(deviceId);
        auto it = infos.find(batteryId);
        if (it == infos.end()) {
            return std::nullopt;
        }
        batteryPath = it->second.path;
    } // release lock

    std::string buffer;

    if (!base::ReadFileToString(it->second.path / BATTERY_NODES.at(InputBatteryClass::STATUS),
    if (!base::ReadFileToString(batteryPath / BATTERY_NODES.at(InputBatteryClass::STATUS),
                                &buffer)) {
        ALOGE("Failed to read sysfs battery info: %s", strerror(errno));
        return std::nullopt;
+4 −8
Original line number Diff line number Diff line
@@ -547,14 +547,6 @@ void InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) {
    for_each_mapper([when, readTime](InputMapper& mapper) { mapper.cancelTouch(when, readTime); });
}

std::optional<int32_t> InputDevice::getBatteryCapacity() {
    return mController ? mController->getBatteryCapacity(DEFAULT_BATTERY_ID) : std::nullopt;
}

std::optional<int32_t> InputDevice::getBatteryStatus() {
    return mController ? mController->getBatteryStatus(DEFAULT_BATTERY_ID) : std::nullopt;
}

bool InputDevice::setLightColor(int32_t lightId, int32_t color) {
    return mController ? mController->setLightColor(lightId, color) : false;
}
@@ -622,6 +614,10 @@ void InputDevice::updateLedState(bool reset) {
    for_each_mapper([reset](InputMapper& mapper) { mapper.updateLedState(reset); });
}

std::optional<int32_t> InputDevice::getBatteryEventHubId() const {
    return mController ? std::make_optional(mController->getEventHubId()) : std::nullopt;
}

InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
      : mDevice(device),
        mContext(device.getContext()),
+32 −12
Original line number Diff line number Diff line
@@ -705,23 +705,43 @@ void InputReader::flushSensor(int32_t deviceId, InputDeviceSensorType sensorType
}

std::optional<int32_t> InputReader::getBatteryCapacity(int32_t deviceId) {
    std::optional<int32_t> eventHubId;
    {
        // Do not query the battery state while holding the lock. For some peripheral devices,
        // reading battery state can be broken and take 5+ seconds. Holding the lock in this case
        // would block all other event processing during this time. For now, we assume this
        // call never happens on the InputReader thread and get the battery state outside the
        // lock to prevent event processing from being blocked by this call.
        std::scoped_lock _l(mLock);

        InputDevice* device = findInputDeviceLocked(deviceId);
    if (device) {
        return device->getBatteryCapacity();
    }
    return std::nullopt;
        if (!device) return {};
        eventHubId = device->getBatteryEventHubId();
    } // release lock

    if (!eventHubId) return {};
    const auto batteryIds = mEventHub->getRawBatteryIds(*eventHubId);
    if (batteryIds.empty()) return {};
    return mEventHub->getBatteryCapacity(*eventHubId, batteryIds.front());
}

std::optional<int32_t> InputReader::getBatteryStatus(int32_t deviceId) {
    std::optional<int32_t> eventHubId;
    {
        // Do not query the battery state while holding the lock. For some peripheral devices,
        // reading battery state can be broken and take 5+ seconds. Holding the lock in this case
        // would block all other event processing during this time. For now, we assume this
        // call never happens on the InputReader thread and get the battery state outside the
        // lock to prevent event processing from being blocked by this call.
        std::scoped_lock _l(mLock);

        InputDevice* device = findInputDeviceLocked(deviceId);
    if (device) {
        return device->getBatteryStatus();
    }
    return std::nullopt;
        if (!device) return {};
        eventHubId = device->getBatteryEventHubId();
    } // release lock

    if (!eventHubId) return {};
    const auto batteryIds = mEventHub->getRawBatteryIds(*eventHubId);
    if (batteryIds.empty()) return {};
    return mEventHub->getBatteryStatus(*eventHubId, batteryIds.front());
}

std::vector<InputDeviceLightInfo> InputReader::getLights(int32_t deviceId) {
+4 −0
Original line number Diff line number Diff line
@@ -524,4 +524,8 @@ std::optional<int32_t> PeripheralController::getLightPlayerId(int32_t lightId) {
    return light->getLightPlayerId();
}

int32_t PeripheralController::getEventHubId() const {
    return getDeviceContext().getEventHubId();
}

} // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ public:
    explicit PeripheralController(InputDeviceContext& deviceContext);
    ~PeripheralController() override;

    int32_t getEventHubId() const override;
    void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
    void dump(std::string& dump) override;
    bool setLightColor(int32_t lightId, int32_t color) override;
@@ -43,6 +44,7 @@ public:
private:
    inline int32_t getDeviceId() { return mDeviceContext.getId(); }
    inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
    inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }

    InputDeviceContext& mDeviceContext;
    void configureLights();
Loading