Skip to content

Fix(battery): get battery info error.#661

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
GongHeng2017:202605141352-master-fix
May 14, 2026
Merged

Fix(battery): get battery info error.#661
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
GongHeng2017:202605141352-master-fix

Conversation

@GongHeng2017
Copy link
Copy Markdown
Contributor

@GongHeng2017 GongHeng2017 commented May 14, 2026

-- In Qt 6, when using QProcess::start(), you must separate the program name from the argument list for the command to execute correctly.

Log: fix issue
Bug: https://pms.uniontech.com/bug-view-361071.html

Summary by Sourcery

Fix battery information retrieval by correctly invoking the upower command with separated program and arguments and adding a timeout for the process execution.

Bug Fixes:

  • Resolve failure to obtain current power information caused by improper QProcess usage when running the upower command.

Enhancements:

  • Add a finite timeout when waiting for the upower process to finish to avoid potential indefinite hangs.
  • Update the source file copyright years to include 2026.

-- In Qt 6, when using QProcess::start(), you must separate the
program name from the argument list for the command to execute correctly.

Log: fix issue
Bug: https://pms.uniontech.com/bug-view-361071.html
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 14, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates battery information retrieval to use Qt 6–compliant QProcess invocation for the upower --dump command and tightens process completion waiting, while also updating the SPDX copyright years.

Sequence diagram for updated battery info retrieval with QProcess in Qt6

sequenceDiagram
    participant CmdTool_getCurPowerInfo as CmdTool::getCurPowerInfo
    participant QProcess_process as QProcess
    participant upower as upower

    CmdTool_getCurPowerInfo->>QProcess_process: start("upower", QStringList(--dump))
    activate QProcess_process
    QProcess_process->>upower: execute upower --dump
    upower-->>QProcess_process: stdout (battery info)
    QProcess_process-->>CmdTool_getCurPowerInfo: waitForFinished(5000)
    deactivate QProcess_process
    CmdTool_getCurPowerInfo->>QProcess_process: readAllStandardOutput()
    QProcess_process-->>CmdTool_getCurPowerInfo: powerInfo
Loading

File-Level Changes

Change Details Files
Fix QProcess invocation of upower --dump for Qt 6 compatibility and improve process timeout handling when retrieving battery info.
  • Instantiate QProcess closer to its use within getCurPowerInfo to run the upower command.
  • Replace single-string QProcess::start call with program-and-arguments form: program "upower" and argument "--dump" to satisfy Qt 6 requirements.
  • Change process waiting behavior from an indefinite wait to a 5-second timeout before reading command output.
  • Retain logic to read standard output and split the result for further parsing.
deepin-devicemanager/src/GenerateDevice/CmdTool.cpp
Update SPDX copyright header to reflect an extended year range.
  • Modify the SPDX-FileCopyrightText header to cover years 2022 through 2026.
deepin-devicemanager/src/GenerateDevice/CmdTool.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的Git Diff内容。这次修改主要针对外部命令的调用方式和超时处理进行了优化,整体改进方向是非常好的,但也存在一些需要关注的隐患。以下是详细的审查意见:

一、 语法与逻辑

  1. 进程启动失败与输出读取逻辑

    • 问题:代码在调用 process.start() 后,直接调用了 process.waitForFinished(5000),然后使用 process.readAllStandardOutput() 读取输出。如果 upower 命令不存在,或者启动失败,readAllStandardOutput() 将返回空字符串,程序会静默失败,没有进行任何错误处理。
    • 改进建议:在读取输出前,检查进程的启动状态和退出状态。
  2. 进程异常退出或超时后的清理

    • 问题:如果 upower --dump 执行时间超过5秒,waitForFinished(5000) 会返回 false,此时进程并未结束,仍在后台运行。代码没有对这种超时情况进行处理,可能导致僵尸进程或资源泄漏。
    • 改进建议:判断 waitForFinished 的返回值,如果超时,应主动终止并回收进程资源。

二、 代码质量

  1. 命令参数构建方式(优点)

    • 亮点:将 process.start("upower --dump") 改为 process.start("upower", QStringList() << "--dump") 是一个非常棒的改进!这避免了底层通过 /bin/sh -c 执行命令,不仅提升了性能,还消除了命令注入的风险(虽然这里参数是硬编码的,但这是一个良好的编程习惯)。
    • 现代C++写法建议:可以使用 QProcess::splitCommand() (Qt 5.14+) 或者更直观的初始化列表 QStringList{"--dump"} 来替代 QStringList() << "--dump",使代码更简洁。
  2. 错误日志缺失

    • 问题:当命令执行失败或超时时,只有正常的 debug 日志,没有错误日志,不利于后续的问题排查。
    • 改进建议:增加 qCWarningqCCritical 输出错误信息及标准错误输出(readAllStandardError())。

三、 代码性能

  1. 超时时间的设定(优点)
    • 亮点:将 waitForFinished(-1)(无限期阻塞)改为 waitForFinished(5000)(5秒超时)是非常必要的改进。在GUI程序中,无限期阻塞会导致界面卡死,严重影响用户体验。
    • 注意:5秒对于本地 upower 命令通常足够,但如果系统负载极高或出现IO挂起,5秒的阻塞依然会让用户感到明显卡顿。建议确保此代码不在主线程(UI线程)中执行。

四、 代码安全

  1. 命令执行安全(优点)
    • 如前所述,使用 QStringList 传递参数分离了程序名和参数,避免了Shell解析带来的潜在风险,安全性得到提升。
  2. 版权年份更新
    • 修改了 SPDX 版权信息至 2026 年,请确保符合贵公司的法务合规要求(通常版权结束年份应为代码修改的当年,预测到2026年可能存在合规争议,但这是非代码逻辑问题,仅作提醒)。

🚀 综合改进后的代码建议

结合以上分析,我为你重构了这部分代码,增强了健壮性、错误处理和资源管理:

QMap<QString, QMap<QString, QString>> CmdTool::getCurPowerInfo()
{
    qCDebug(appLog) << "Getting current power info from upower.";
    QString powerInfo;
    QMap<QString, QMap<QString, QString>> map;

    // 执行"upower --dump"命令获取电池相关信息
    QProcess process;
    // 推荐使用现代C++初始化列表风格
    process.start("upower", QStringList{"--dump"});

    // 获取命令执行结果,设置5秒超时
    if (!process.waitForFinished(5000)) {
        // 区分是启动失败还是执行超时
        if (process.error() == QProcess::Timedout) {
            qCWarning(appLog) << "upower --dump timed out after 5000ms.";
            process.kill(); // 终止进程
            process.waitForFinished(); // 等待进程资源回收
        } else {
            qCWarning(appLog) << "Failed to start upower:" << process.errorString();
        }
        return map; // 返回空map,避免后续解析错误数据
    }

    // 检查进程退出码,确保命令正常执行完毕
    if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
        qCWarning(appLog) << "upower --dump exited with error. Exit code:" << process.exitCode() 
                          << "Error output:" << process.readAllStandardError();
        return map;
    }

    powerInfo = process.readAllStandardOutput();
    qCDebug(appLog) << "upower --dump output:" << powerInfo;
    QStringList items = powerInfo.split("\n\n");
    
    // ... 后续解析逻辑 ...
    return map;
}

主要改进点说明:

  1. 增加了 waitForFinished 返回值的判断,处理了超时(kill() 并回收资源)和启动失败的情况。
  2. 增加了退出状态和退出码的检查,防止命令行程序异常退出(如 upower 自身崩溃)导致读取到不完整或错误的数据。
  3. 在异常分支增加了 qCWarning 日志输出,输出包含标准错误流,极大方便了后期排查问题。
  4. 使用 QStringList{"--dump"} 替代 QStringList() << "--dump",书写更现代、简洁。

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Consider checking the return value of process.waitForFinished(5000) and handling the timeout or failure case explicitly instead of assuming the process completed successfully.
  • If a fixed 5-second timeout is required, it might be clearer to define it as a named constant (or configuration) so its rationale and usage are easier to adjust in the future.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider checking the return value of `process.waitForFinished(5000)` and handling the timeout or failure case explicitly instead of assuming the process completed successfully.
- If a fixed 5-second timeout is required, it might be clearer to define it as a named constant (or configuration) so its rationale and usage are easier to adjust in the future.

## Individual Comments

### Comment 1
<location path="deepin-devicemanager/src/GenerateDevice/CmdTool.cpp" line_range="1324" />
<code_context>
+    process.start("upower", QStringList() << "--dump");
     // 获取命令执行结果
-    process.waitForFinished(-1);
+    process.waitForFinished(5000);
     powerInfo = process.readAllStandardOutput();
     qCDebug(appLog) << "upower --dump output:" << powerInfo;
</code_context>
<issue_to_address>
**issue (bug_risk):** A fixed 5s timeout may cause incomplete results or subtle bugs on slower systems.

With this change, `waitForFinished(5000)` may return while `upower --dump` is still running, so you could parse partial output as if it were complete. If you need a timeout, check the boolean return value and handle timeouts explicitly (e.g., log and skip parsing), or make the timeout configurable so it can be tuned for slower systems.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread deepin-devicemanager/src/GenerateDevice/CmdTool.cpp
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: GongHeng2017, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@GongHeng2017
Copy link
Copy Markdown
Contributor Author

/merge

@deepin-bot deepin-bot Bot merged commit 1e19a3b into linuxdeepin:master May 14, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants