Skip to content

fix(input): detect PS/2 wakeup by interface, not name only - #735

Closed
tianming-1996 wants to merge 1 commit into
linuxdeepin:develop/eaglefrom
tianming-1996:agent/pms-bug-bot/6271b0d4
Closed

fix(input): detect PS/2 wakeup by interface, not name only#735
tianming-1996 wants to merge 1 commit into
linuxdeepin:develop/eaglefrom
tianming-1996:agent/pms-bug-bot/6271b0d4

Conversation

@tianming-1996

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

Copy link
Copy Markdown
Contributor

根因分析

DeviceInput::wakeupPath()src/DeviceManager/DeviceInput.cpp:508)判断 PS/2 时仅 m_Name.contains("PS/2"),与同文件 isWakeupMachine()(第 484 行 m_Name.contains("PS/2") || m_Interface.contains("PS/2"))不一致。L420 等机型的内置 PS/2 键盘 hwinfo 名称为 "AT Translated Set 2 keyboard"(不含 "PS/2"),而 m_Interface = "PS/2",导致 wakeupPath() 走错分支返回 sysfs /sys<syspath>/power/wakeup(PS/2 设备无此节点)→ canWakeupMachine() 打开失败返回 false → 右键菜单"允许唤起电脑"被置灰。

关键证据:

  • DeviceInput.cpp:508 name-only 判定 vs :484 name||interface 判定(同文件不一致即缺陷)。
  • DeviceInput.cpp:469-471 canWakeupMachine()wakeupPath() 打开失败返回 false(能力门禁)。
  • git 历史:98b67c8e(Bug 336943)已把姊妹函数 isInputWakeupMachine() 的 PS/2 判定改为按 interfaceType 判定并加 hardwareClass 区分 PS2M/PS2K,但未同步修正 wakeupPath()setWakeupMachine()PageMultiInfo 三处同源 name-only 判定,启用 PS/2 键盘唤醒菜单的意图被抵消。

修复方案

对齐三处同源 PS/2 name-only 判定,统一为 name.contains("PS/2") || interface.contains("PS/2")

  1. DeviceInput.cpp:508(主根因)wakeupPath()|| m_Interface.contains("PS/2"),与 isWakeupMachine():484 对齐 → canWakeupMachine() 返回 true,菜单显示。
  2. PageMultiInfo.cpp:328|| input->getInterface().contains("PS/2") → 表格页 menuControl 正确追加 PS/2 设备的 hardwareClass/interface,唤醒状态查询不再恒为未勾选。
  3. DBusWakeupInterface::setWakeupMachine() 扩展签名增加 interfaceType 形参,name.contains("PS/2")name.contains("PS/2") || interfaceType.contains("PS/2");同步 4 个调用点(DeviceInput.cpp:440/445TextBrowser.cpp:114PageSingleInfo.cpp:359)。其中 PageSingleInfo.cpp:359 原误将 getInterface() 传入 name 形参(历史遗留),一并纠正为 name() + getInterface()。该签名扩展与 98b67c8eisInputWakeupMachine 的改造同模式,name 形参仍用于判定故无新增 unused-param。

改动安全评估

风险等级:中(由 #3 的函数签名变更带来;#1/#2 为低风险单行加条件)。#3 经评估风险可控:有 98b67c8e 的成熟先例、4 处调用点全在仓内已同步、name 仅用于本次判定的 contains 检查、不变 DBus 协议(服务端 ControlInterface::setWakeupMachine 签名不变)、不撤销任何历史修复(相反补全了 98b67c8e 想做漏做的 setWakeupMachine 侧)。

PMS: https://pms.uniontech.com/bug-view-294489.html

Summary by Sourcery

Detect PS/2 wakeup devices by interface as well as name so PS/2 input wakeup controls work consistently.

Bug Fixes:

  • Fix PS/2 input wakeup detection for devices whose interface identifies them as PS/2 even when their names do not.
  • Correct wakeup capability and state handling for PS/2 devices across single-device, multi-device, and enable/disable flows.

Enhancements:

  • Extend wakeup control calls to use both device names and interface types when selecting PS/2 wakeup handling, while correcting the single-device call arguments.

Align wakeupPath() PS/2 check with isWakeupMachine() (name||interface).
Fix PageMultiInfo PS/2 guard to also match the interface field.
Extend setWakeupMachine() with interfaceType and fix caller args.

将 wakeupPath() 的 PS/2 判定与 isWakeupMachine() 对齐(name||interface)。
修正 PageMultiInfo 的 PS/2 条件,同时匹配接口字段。
为 setWakeupMachine() 增加 interfaceType 形参并修正调用点参数。

Log: 修复内置PS/2键盘因名称不含PS/2导致唤起电脑菜单缺失的问题
PMS: BUG-294489
Influence: PS/2键盘唤起电脑菜单可正常显示与切换,其他设备唤起行为不变
@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 18, 2026

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

Reviewer's Guide

Align PS/2 wakeup detection across DeviceInput, DBusWakeupInterface, and UI layers by using both device name and interface type, and extend setWakeupMachine to accept interfaceType so PS/2 keyboard devices without 'PS/2' in their name can properly control wake capability.

Sequence diagram for PS2 wakeup detection using name and interfaceType

sequenceDiagram
    actor User
    participant PageSingleInfo
    participant DeviceInput
    participant DBusWakeupInterface
    participant InputService

    User ->> PageSingleInfo: slotWakeupMachine()
    PageSingleInfo ->> DeviceInput: wakeupID()
    PageSingleInfo ->> DeviceInput: sysPath()
    PageSingleInfo ->> DeviceInput: name()
    PageSingleInfo ->> DeviceInput: hardwareClass()
    PageSingleInfo ->> DeviceInput: getInterface()
    PageSingleInfo ->> DBusWakeupInterface: setWakeupMachine(wakeupID, sysPath, wakeup, name, hardwareClass, interfaceType)

    alt [name or interfaceType contains PS/2]
        DBusWakeupInterface ->> InputService: setWakeupMachine using /proc/acpi/wakeup
    else [non PS/2 device]
        DBusWakeupInterface ->> InputService: setWakeupMachine using /sys/.../power/wakeup
    end

    DeviceInput ->> DeviceInput: wakeupPath()
    alt [m_Name contains PS/2 or m_Interface contains PS/2]
        DeviceInput --> DeviceInput: return /proc/acpi/wakeup
    else [other interfaces]
        DeviceInput --> DeviceInput: return /sys/.../power/wakeup
    end
Loading

File-Level Changes

Change Details Files
Align PS/2 wakeup path selection in DeviceInput with isWakeupMachine by considering both name and interface, and propagate interface through wakeup-related DBus calls.
  • Update wakeupPath() to treat devices as PS/2 when either the device name or interface contains 'PS/2', returning /proc/acpi/wakeup accordingly.
  • Pass m_Interface into DBusWakeupInterface::setWakeupMachine calls in DeviceInput::setEnable for both enabling and disabling wakeup.
  • Extend DBusWakeupInterface::setWakeupMachine signature and implementation to accept interfaceType and use it in PS/2 detection along with name.contains('PS/2').
deepin-devicemanager/src/DeviceManager/DeviceInput.cpp
deepin-devicemanager/src/WakeupControl/DBusWakeupInterface.h
deepin-devicemanager/src/WakeupControl/DBusWakeupInterface.cpp
Fix and enhance PS/2 wakeup menu control logic in single/multi-device UI, including passing correct name/interface values.
  • In PageMultiInfo, treat a device as PS/2 for menuControl construction when either the name or the interface contains 'PS/2', and continue appending bus info, name, and hardwareClass.
  • In PageSingleInfo, correct the previously swapped arguments by passing input->name() as the name parameter and input->getInterface() as the new interfaceType parameter when calling setWakeupMachine.
  • In TextBrowser, update the setWakeupMachine call to supply input->getInterface() as the interfaceType argument.
deepin-devicemanager/src/Page/PageMultiInfo.cpp
deepin-devicemanager/src/Page/PageSingleInfo.cpp
deepin-devicemanager/src/Widget/TextBrowser.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 PS/2 detection logic (name.contains("PS/2") || interface.contains("PS/2")) is now duplicated in several places; consider extracting a small helper (e.g. isPs2Device(name, interface)) to avoid future inconsistency between call sites.
  • In PageMultiInfo::getTableListInfo, the PS/2 check uses info->name() while other wakeup-related logic uses DeviceInput fields; aligning this to use input->name() would make the PS/2 detection more consistent with the rest of the input handling.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The PS/2 detection logic (`name.contains("PS/2") || interface.contains("PS/2")`) is now duplicated in several places; consider extracting a small helper (e.g. `isPs2Device(name, interface)`) to avoid future inconsistency between call sites.
- In `PageMultiInfo::getTableListInfo`, the PS/2 check uses `info->name()` while other wakeup-related logic uses `DeviceInput` fields; aligning this to use `input->name()` would make the PS/2 detection more consistent with the rest of the input handling.

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分

■ 【总体评价】

代码准确修复了PS/2设备唤醒识别缺失及参数传递顺序错误的缺陷,逻辑严密且无副作用。
各维度表现优异,仅因存在轻微的代码重复现象扣减5分。

■ 【详细分析】

  • 1.语法逻辑(完全正确)✓

修复了 PageSingleInfo::slotWakeupMachine 中长期存在的参数传反问题,将 namehardwareclassinterface 恢复为正确顺序。同时在 DBusWakeupInterface::setWakeupMachineDeviceInput::wakeupPath 等核心路径中,通过 || 运算符扩展了 PS/2 设备的判定条件,补全了仅依赖设备名称判定的逻辑漏洞,所有调用点的参数均已同步更新,无编译或运行时逻辑错误。
潜在问题:DBusWakeupInterface.cpp 中使用了 QString::SkipEmptyParts,该枚举在 Qt 5.15 及以上版本已被标记为废弃,推荐使用 Qt::SkipEmptyParts
建议:将 QString::SkipEmptyParts 替换为 Qt::SkipEmptyParts 以保证在后续 Qt 版本中的兼容性。

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

头文件 DBusWakeupInterface.h 中同步补充了新增参数 interfaceType 的详细注释,参数命名语义清晰,修改符合现有代码规范。
潜在问题:name.contains("PS/2") || interface.contains("PS/2") 这一判定逻辑在 DeviceInput.cppPageMultiInfo.cppDBusWakeupInterface.cpp 三处文件中重复出现,违反了 DRY 原则,若后续增加新的 PS/2 识别特征需多处修改。
建议:将此判定逻辑抽象为一个公共的静态内联函数或宏,统一进行调用。

  • 3.代码性能(高效)✓

新增的 QString::contains("PS/2") 调用仅在设备启用、禁用及界面信息加载时触发,属于低频操作,且字符串匹配目标极短,时间复杂度可忽略不计,对系统运行时性能无任何可感知影响。
建议:保持现状即可。

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

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
传入 setWakeupMachine 的设备名称、接口类型等参数均来源于底层的 sysfs 属性文件读取,不涉及外部不可信输入,DBus 调用过程受系统总线安全策略管控,不存在注入、越权或信息泄露风险。本次修改纯粹是内部逻辑修正,未引入新的攻击面。
建议:保持现有的参数传递与校验机制。

■ 【改进建议代码示例】

--- a/deepin-devicemanager/src/DeviceManager/DeviceInput.h
+++ b/deepin-devicemanager/src/DeviceManager/DeviceInput.h
@@ -12,6 +12,11 @@
 #include <QMap>
 
+namespace DeviceHelper {
+// 统一提取 PS/2 设备判断逻辑,避免多处理重复代码
+inline bool isPS2Device(const QString &name, const QString &interfaceType) {
+    return name.contains("PS/2") || interfaceType.contains("PS/2");
+}
+}
+
 class DeviceInput : public DeviceBaseInfo
 {
--- a/deepin-devicemanager/src/DeviceManager/DeviceInput.cpp
+++ b/deepin-devicemanager/src/DeviceManager/DeviceInput.cpp
@@ -508,7 +508,7 @@ QString DeviceInput::wakeupPath()
         return "";
     }
 
-    if (m_Name.contains("PS/2") || m_Interface.contains("PS/2")) {
+    if (DeviceHelper::isPS2Device(m_Name, m_Interface)) {
         return "/proc/acpi/wakeup";
     } else {
         return QString("/sys") + m_SysPath.left(index) + QString("/power/wakeup");
--- a/deepin-devicemanager/src/WakeupControl/DBusWakeupInterface.cpp
+++ b/deepin-devicemanager/src/WakeupControl/DBusWakeupInterface.cpp
@@ -39,7 +39,7 @@ bool DBusWakeupInterface::setWakeupMachine(const QString &unique_id,
                                            const QString &interfaceType)
 {
     if (nullptr != mp_InputIface && mp_InputIface->isValid()) {
-        QStringList pathList = path.split("/", QString::SkipEmptyParts);
+        QStringList pathList = path.split("/", Qt::SkipEmptyParts);
         if (pathList.size() < 3)
             return false;
 
-        if (name.contains("PS/2") || interfaceType.contains("PS/2")) {
+        if (DeviceHelper::isPS2Device(name, interfaceType)) {
             // ps2设备无法通过/sys/devices/platform/i8042/serio1/power/wakeup控制,只能通过acpi的接口进行控制
             QDBusInterface interface(INPUT_SERVICE_NAME, INPUT_WAKEUP_SERVICE_PATH, INPUT_WAKEUP_PROPERTIES_INTERFACE, QDBusConnection::systemBus());

@tianming-1996

Copy link
Copy Markdown
Contributor Author

Closed per maintainer's decision (majiuping): proceeding with PR #726 (minimal fix). PMS 294489.

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