Skip to content

fix: strip input suffix from m_SysPath on mismatch - #736

Open
tianming-1996 wants to merge 1 commit into
linuxdeepin:release/eaglefrom
tianming-1996:agent/pms-bug-bot/05fe061c
Open

fix: strip input suffix from m_SysPath on mismatch#736
tianming-1996 wants to merge 1 commit into
linuxdeepin:release/eaglefrom
tianming-1996:agent/pms-bug-bot/05fe061c

Conversation

@tianming-1996

@tianming-1996 tianming-1996 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Root Cause Analysis

In DeviceInput::getPS2Syspath() (DeviceInput.cpp:200-240), m_SysPath is only reassigned when the event-number match against /proc/bus/input/devices succeeds. When the match fails, m_SysPath retains the raw hwinfo "SysFS ID" value, which carries an extra /input/inputN (i2c_designware) or /inputN suffix. Downstream wakeupPath() then builds /sys/.../input/power/wakeup (an extra input layer) which does not exist, so canWakeupMachine() returns false and the right-click menu item "允许唤出电脑" (Allow waking up computer) is greyed out. Connecting an external keyboard shifts input device enumeration, causing the event-number mismatch between hwinfo --keyboard and /proc/bus/input/devices. PS/2 and L2C keyboards share the same setInfoFromHwinfogetPS2Syspath path, which is why both are affected.

Fix Approach

Add an idempotent fallback at the end of getPS2Syspath() (before return true) that strips the trailing /input/inputN (for i2c_designware) or /inputN suffix from m_SysPath. Normalizing at the source fixes both the client-side wakeupPath() check and the server-side DBusWakeupInterface::setWakeupMachine() call that receives sysPath(), matching the analysis report's Method A recommendation.

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • The m_SysPath = regfs.cap(1) assignment (line 236) has been untouched since its introduction (commit be1e8349, 2022-03-08); this change does not revert any historical fix — related bugs (172035, 147047, 147393) target different code paths (USB mouse DBus, serial ID logic).
  • Highest-risk affected callers: wakeupPath() (DeviceInput.cpp:408) and setWakeupMachine() (PageSingleInfo.cpp:351, TextBrowser.cpp:114) — both are positively fixed by the normalized path. The strip is idempotent (no-op when the suffix is already absent on a successful match).

Business Impact Scope

Device Manager — keyboard/mouse "Allow waking up computer": the right-click context menu for PS/2 and L2C keyboards. After attaching an external keyboard the menu item must appear enabled and toggle correctly; the server-side wake-up DBus call must receive a valid sysfs path.

Verification Suggestion

Test with and without an external keyboard: confirm the "允许唤出电脑" menu item is enabled for both PS/2 and L2C (i2c_designware) keyboards, and that wake-from-keyboard still functions as a regression check.


根因分析

DeviceInput::getPS2Syspath()DeviceInput.cpp:200-240)仅在 event 号与 /proc/bus/input/devices 匹配成功时才重新赋值 m_SysPath;匹配失败时 m_SysPath 仍保留 hwinfo 原始 "SysFS ID" 值,带有多余的 /input/inputN(i2c_designware)或 /inputN 后缀。下游 wakeupPath() 据此拼出 /sys/.../input/power/wakeup(多一层 input),该文件不存在,canWakeupMachine() 返回 false,右键菜单项"允许唤出电脑"被置灰。外接键盘改变输入设备枚举,导致 hwinfo --keyboard/proc/bus/input/devices 的 event 号不一致而匹配失败。PS/2 与 L2C 键盘走同一 setInfoFromHwinfogetPS2Syspath 路径,故两者同时受影响。

修复方案

getPS2Syspath() 末尾(return true 之前)新增幂等的兜底逻辑,剥离 m_SysPath 尾部的 /input/inputN(i2c_designware)或 /inputN 后缀。在源头规范化 m_SysPath,一次性修复客户端 wakeupPath() 检查与服务端 DBusWakeupInterface::setWakeupMachine() 调用两条路径,与分析报告 Method A 建议一致。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • m_SysPath = regfs.cap(1)(第 236 行)自引入以来(commit be1e8349,2022-03-08)未被修改,本次修复不撤销任何历史修复——关联 bug(172035、147047、147393)走的是 USB 鼠标 DBus、序列号获取等不同路径。
  • 受影响最高风险调用者:wakeupPath()DeviceInput.cpp:408)与 setWakeupMachine()PageSingleInfo.cpp:351TextBrowser.cpp:114)均被正面修复;剥离幂等,匹配成功时后缀已不存在,remove 为空操作。

业务影响范围

设备管理器 — 键鼠"允许唤出电脑"功能:PS/2 与 L2C 键盘右键上下文菜单。外接键盘后菜单项应正常显示并可切换,服务端唤出 DBus 调用应收到正确 sysfs 路径。

验证建议

分别在不外接与外接键盘环境下测试:确认 PS/2 与 L2C(i2c_designware)键盘"允许唤出电脑"菜单项可用,并回归验证键盘唤出功能正常。

PMS: BUG-294489

Summary by Sourcery

Bug Fixes:

  • Normalize PS/2 and L2C keyboard sysfs paths when device matching fails, restoring valid wake-up detection and enabling the computer-wake menu action.

1. Root cause: getPS2Syspath() only updates m_SysPath on
   event-number match success; on failure m_SysPath keeps the
   hwinfo raw SysFS ID with /input/inputN or /inputN suffix
2. Fix: strip the trailing input suffix from m_SysPath after
   matching so wakeupPath() and DBus wakeup call use the
   correct sysfs path
3. Impact: external keyboard changes input enumeration and
   triggers the mismatch; "allow waking up computer" menu is
   no longer greyed out for PS/2 and L2C keyboards

Log: Fix greyed-out wake-up menu item after attaching external keyboard

Influence:
1. Connect an external keyboard and verify the right-click
   "allow waking up computer" menu is enabled for PS/2 keyboard
2. Repeat the same check for L2C (i2c_designware) keyboard
3. Verify wake-up-from-keyboard still works without external
   keyboard

fix: 修复外接键盘后唤出电脑菜单置灰

1. 根因:getPS2Syspath() 仅在 event 号匹配成功时更新
   m_SysPath;匹配失败时 m_SysPath 仍保留 hwinfo 原始 SysFS
   ID(含 /input/inputN 或 /inputN 后缀)
2. 方案:匹配后剥离 m_SysPath 尾部的 /input/inputN
   (i2c_designware)或 /inputN 后缀,使 wakeupPath() 与
   DBus 唤出调用拼出正确的 sysfs 路径
3. 影响:外接键盘改变输入设备枚举导致匹配失败,修复后
   PS/2 与 L2C 键盘右键"允许唤出电脑"菜单不再置灰

Log: 修复外接键盘后"允许唤出电脑"菜单置灰问题

Influence:
1. 外接键盘后验证 PS/2 键盘右键"允许唤出电脑"菜单可用
2. 外接键盘后验证 L2C(i2c_designware)键盘同样可用
3. 不外接键盘时验证唤出电脑功能无回归

PMS: BUG-294489
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: tianming-1996

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

@sourcery-ai

sourcery-ai Bot commented Aug 20, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Normalizes keyboard sysfs paths in getPS2Syspath() by stripping trailing /input segments when the /proc/bus/input/devices event match fails, ensuring wakeup-related code receives a valid path.

Sequence diagram for normalized sysfs path in keyboard wakeup flow

sequenceDiagram
    actor User
    participant DeviceManagerUI
    participant DeviceInput
    participant ProcBusInputDevices
    participant DBusWakeupInterface

    User->>DeviceManagerUI: open context_menu "允许唤出电脑"
    DeviceManagerUI->>DeviceInput: setInfoFromHwinfo(hwinfoOutput)
    DeviceInput->>ProcBusInputDevices: getPS2Syspath(dfs)
    ProcBusInputDevices-->>DeviceInput: event_match_or_mismatch
    alt event_match_success
        DeviceInput->>DeviceInput: assign m_SysPath from regfs_cap
    else event_match_failure
        DeviceInput->>DeviceInput: remove(QRegExp("/input/input[0-9]{1,2}$"))
        DeviceInput->>DeviceInput: remove(QRegExp("/input[0-9]{1,2}$"))
    end

    DeviceManagerUI->>DeviceInput: wakeupPath()
    DeviceInput-->>DeviceManagerUI: /sys/.../power/wakeup (from normalized m_SysPath)
    DeviceManagerUI->>DeviceInput: canWakeupMachine()
    DeviceInput-->>DeviceManagerUI: true
    DeviceManagerUI->>DBusWakeupInterface: setWakeupMachine(sysPath())
    DBusWakeupInterface-->>DeviceManagerUI: success
Loading

File-Level Changes

Change Details Files
Normalize m_SysPath in getPS2Syspath() by removing trailing /input suffixes when hwinfo-based paths are left untouched after a failed event-number match.
  • Add an idempotent post-processing step at the end of getPS2Syspath() to clean up m_SysPath when no /proc/bus/input/devices match was found.
  • Detect i2c_designware devices via substring match and strip a trailing /input/inputN segment from m_SysPath using a regular expression.
  • For non-i2c_designware devices, strip a trailing /inputN segment from m_SysPath using a regular expression to obtain the correct device sysfs path.
  • Rely on the normalized m_SysPath so that wakeupPath() and DBusWakeupInterface::setWakeupMachine() build valid /sys/.../power/wakeup paths and enable the "Allow waking up computer" menu item.
deepin-devicemanager/src/DeviceManager/DeviceInput.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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The i2c_designware check makes the suffix stripping logic device-name–dependent; consider using a single regex that handles both /input/inputN and /inputN suffixes without relying on the driver string.
  • New usage of QRegExp could be modernized to QRegularExpression for consistency with newer Qt APIs and better performance, especially since this path normalization may run multiple times.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `i2c_designware` check makes the suffix stripping logic device-name–dependent; consider using a single regex that handles both `/input/inputN` and `/inputN` suffixes without relying on the driver string.
- New usage of `QRegExp` could be modernized to `QRegularExpression` for consistency with newer Qt APIs and better performance, especially since this path normalization may run multiple times.

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.

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:95分

■ 【总体评价】

代码修复了路径拼接错误的问题,逻辑清晰且注释完善,整体质量良好。
逻辑正确且无安全漏洞,仅因使用过时的正则类和临时对象构造扣5分。

■ 【详细分析】

  • 1.语法逻辑(基本正确)✓

代码位于 DeviceInput.cpp 的 getPS2Syspath 函数中,通过 QString::remove 和 QRegExp 正确移除了路径后缀。正则表达式语法无误,条件分支逻辑符合预期。
潜在问题:无
建议:无

  • 2.代码质量(良好)✓

代码注释详细解释了修改原因,可读性高。但在较新的 Qt 版本中,QRegExp 已被标记为废弃,推荐使用 QRegularExpression。此外,每次调用都构造临时的 QRegExp 对象,不够优雅。
潜在问题:使用了过时的 QRegExp 类;每次执行构造临时正则对象。
建议:替换为 QRegularExpression,并将正则表达式定义为静态常量以避免重复构造。

  • 3.代码性能(无性能问题)✓

字符串匹配和移除操作的时间复杂度为 O(n),在设备管理场景下调用频率极低,性能影响可忽略不计。
潜在问题:
建议:无

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码仅进行本地字符串处理,不涉及外部输入执行、网络请求或敏感权限操作,无安全风险。

  • 建议:无

■ 【改进建议代码示例】

    // 匹配失败时 m_SysPath 仍保留 hwinfo 原始 SysFS ID(含 /input/inputN 或 /inputN 后缀),
    // 需剥离后缀得到正确设备 syspath,否则 wakeupPath() 等会拼出错误路径
    static const QRegularExpression i2cPattern("/input/input[0-9]{1,2}$");
    static const QRegularExpression normalPattern("/input[0-9]{1,2}$");
    if (m_SysPath.contains("i2c_designware")) {
        m_SysPath.remove(i2cPattern);
    } else {
        m_SysPath.remove(normalPattern);
    }

    return true;
}

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.

2 participants