Skip to content

feat(power): add session power management plugin#70

Open
mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:treeland/power
Open

feat(power): add session power management plugin#70
mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:treeland/power

Conversation

@mhduiy
Copy link
Copy Markdown
Contributor

@mhduiy mhduiy commented May 26, 2026

  1. Add new session-level power management plugin with org.deepin.dde.Power1 DBus service
  2. Implement power save plan management with balance, performance, and power saver modes
  3. Add low power notification and auto-sleep with configurable percentage and time thresholds
  4. Implement idle detection (Wayland + X11), screen dimming/off/turn-off control
  5. Add lid switch handler and sleep inhibitor mechanism for active operations
  6. Include 20+ language translations and DBus service configuration files
  7. Add qt6-tools-dev-tools and libudev-dev build dependencies

Log: Add session-level power management plugin with DBus service, power save plans, low power management, idle detection, and screen control

feat(power): 添加会话级电源管理插件

  1. 新增会话级电源管理插件,提供 org.deepin.dde.Power1 DBus 服务接口
  2. 实现电源节能方案管理,支持平衡、高性能、节能三种模式
  3. 添加低电量通知与自动休眠功能,支持百分比和时间阈值配置
  4. 实现空闲检测(Wayland 和 X11),支持屏幕调暗、熄屏、关闭显示器控制
  5. 添加合盖事件处理和活跃操作防休眠机制
  6. 包含 20+ 语言翻译文件及 DBus 服务配置文件
  7. 新增 qt6-tools-dev-tools 和 libudev-dev 编译依赖

Log: 添加会话级电源管理插件,包含 DBus 服务、节能方案、低电量管理、空闲检测及屏幕控制
PMS: BUG-346597
PMS: BUG-346589
PMS: BUG-346575

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.

Sorry @mhduiy, your pull request is larger than the review limit of 150000 diff characters

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy

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

@mhduiy mhduiy force-pushed the treeland/power branch 3 times, most recently from 03b4d33 to b366fc3 Compare May 26, 2026 12:44
@mhduiy
Copy link
Copy Markdown
Contributor Author

mhduiy commented May 26, 2026

/test all

@mhduiy mhduiy force-pushed the treeland/power branch 2 times, most recently from d8b02df to c71fe7c Compare May 28, 2026 09:17
@18202781743 18202781743 requested a review from Copilot May 28, 2026 09:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Qt-based power management plugin under src/plugin-qt/power/, exposing org.deepin.dde.Power1 and implementing session-level power/idle/screen control (Wayland-focused), plus scaffolding for a system-side implementation.

Changes:

  • Introduce a session power manager with idle detection (Wayland), screen power/brightness control, low-power policy handling, lid switch actions, and scheduled shutdown.
  • Add Wayland protocol client integrations (ext-idle-notify, wlr output power management, treeland brightness) and translation resources.
  • Add D-Bus/systemd service descriptors and update build/install wiring (plus new Debian build-deps).

Reviewed changes

Copilot reviewed 61 out of 61 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/plugin-qt/power/system/systemdbusproxy.h Add small system-bus proxy API (chassis/lid queries).
src/plugin-qt/power/system/systemdbusproxy.cpp Implement hostname1/UPower property reads.
src/plugin-qt/power/system/powermanager.h Add system-side org.deepin.dde.Power1 manager interface (battery/lid/mode properties).
src/plugin-qt/power/system/powermanager.cpp Implement system-side D-Bus object registration and mode/lid/battery wiring.
src/plugin-qt/power/system/plugin-power-system.cpp Add DSM plugin entrypoints for system plugin.
src/plugin-qt/power/system/misc/plugin-power-system.json Add system plugin descriptor for deepin-service-manager.
src/plugin-qt/power/system/misc/org.deepin.dde.Power1.service Add systemd unit for system D-Bus service.
src/plugin-qt/power/system/misc/dbus/org.deepin.dde.Power1.service Add system D-Bus activation service file.
src/plugin-qt/power/system/CMakeLists.txt Add build/install rules for system plugin (currently not enabled by parent CMake).
src/plugin-qt/power/system/batterymanager.h Add udev/sysfs battery monitoring interface.
src/plugin-qt/power/system/batterymanager.cpp Implement sysfs battery polling + udev monitoring.
src/plugin-qt/power/session/translations/plugin-power-session_az.ts Add session plugin translation file (az).
src/plugin-qt/power/session/translations/plugin-power-session_bo.ts Add session plugin translation file (bo).
src/plugin-qt/power/session/translations/plugin-power-session_ca.ts Add session plugin translation file (ca).
src/plugin-qt/power/session/translations/plugin-power-session_en.ts Add session plugin translation file (en).
src/plugin-qt/power/session/translations/plugin-power-session_en_US.ts Add session plugin translation file (en_US).
src/plugin-qt/power/session/translations/plugin-power-session_es.ts Add session plugin translation file (es).
src/plugin-qt/power/session/translations/plugin-power-session_fi.ts Add session plugin translation file (fi).
src/plugin-qt/power/session/translations/plugin-power-session_fr.ts Add session plugin translation file (fr).
src/plugin-qt/power/session/translations/plugin-power-session_hu.ts Add session plugin translation file (hu).
src/plugin-qt/power/session/translations/plugin-power-session_it.ts Add session plugin translation file (it).
src/plugin-qt/power/session/translations/plugin-power-session_ja.ts Add session plugin translation file (ja).
src/plugin-qt/power/session/translations/plugin-power-session_ko.ts Add session plugin translation file (ko).
src/plugin-qt/power/session/translations/plugin-power-session_nb_NO.ts Add session plugin translation file (nb_NO).
src/plugin-qt/power/session/translations/plugin-power-session_pl.ts Add session plugin translation file (pl).
src/plugin-qt/power/session/translations/plugin-power-session_pt_BR.ts Add session plugin translation file (pt_BR).
src/plugin-qt/power/session/translations/plugin-power-session_ru.ts Add session plugin translation file (ru).
src/plugin-qt/power/session/translations/plugin-power-session_uk.ts Add session plugin translation file (uk).
src/plugin-qt/power/session/translations/plugin-power-session_zh_CN.ts Add session plugin translation file (zh_CN).
src/plugin-qt/power/session/translations/plugin-power-session_zh_HK.ts Add session plugin translation file (zh_HK).
src/plugin-qt/power/session/translations/plugin-power-session_zh_TW.ts Add session plugin translation file (zh_TW).
src/plugin-qt/power/session/sleepinhibitor.h Add logind inhibitor helper interface.
src/plugin-qt/power/session/sleepinhibitor.cpp Implement logind sleep inhibition + sleep/wake signals.
src/plugin-qt/power/session/sessiondbusproxy.h Add session/system bus proxy wrapper for dependent services.
src/plugin-qt/power/session/sessiondbusproxy.cpp Implement D-Bus proxy calls/signals for power/session/notify/display/etc.
src/plugin-qt/power/session/screen/screencontroller.h Add abstract screen power/brightness control interface.
src/plugin-qt/power/session/screen/screencontroller.cpp Implement shared helpers (setAllModes/isAllOff).
src/plugin-qt/power/session/screen/screencontroller_x11.cpp Add X11 backend stub (not yet implemented).
src/plugin-qt/power/session/screen/screencontroller_wl.h Add Wayland backend declarations for DPMS + treeland brightness.
src/plugin-qt/power/session/screen/screencontroller_wl.cpp Implement Wayland output discovery, power control, brightness animation.
src/plugin-qt/power/session/powersaveplan.h Add idle-driven task planner (screensaver/lock/black/sleep + brightness drop).
src/plugin-qt/power/session/powersaveplan.cpp Implement idle task scheduling and brightness-drop logic.
src/plugin-qt/power/session/powermanager.h Add session-level org.deepin.dde.Power1 manager API and state.
src/plugin-qt/power/session/powermanager.cpp Implement session power logic: DConfig bindings, idle/screen/lid/low-power, scheduled shutdown.
src/plugin-qt/power/session/plugin-power-session.cpp Add DSM plugin entrypoints + translation loading (Wayland-only runtime enable).
src/plugin-qt/power/session/misc/plugin-power-session.json Add user-session plugin descriptor.
src/plugin-qt/power/session/misc/org.deepin.dde.Power1.service Add session systemd unit for D-Bus service.
src/plugin-qt/power/session/misc/dbus/org.deepin.dde.Power1.service Add session D-Bus activation service file.
src/plugin-qt/power/session/lowpowermanager.h Add low power policy manager interface.
src/plugin-qt/power/session/lowpowermanager.cpp Implement low power notification/lock/UI + auto sleep/hibernate.
src/plugin-qt/power/session/lidswitchhandler.h Add lid switch handler interface.
src/plugin-qt/power/session/lidswitchhandler.cpp Implement lid close/open actions with debounce and DPMS/black-screen handling.
src/plugin-qt/power/session/idle/idlewatcher.h Add abstract idle watcher interface.
src/plugin-qt/power/session/idle/idlewatcher_x11.cpp Add X11 backend stub (not yet implemented).
src/plugin-qt/power/session/idle/idlewatcher_wl.h Add Wayland idle-notify backend declarations.
src/plugin-qt/power/session/idle/idlewatcher_wl.cpp Implement Wayland idle notification setup and caching.
src/plugin-qt/power/session/CMakeLists.txt Add build rules for session plugin, Wayland protocol generation, and translations.
src/plugin-qt/power/powerconstants.h Add shared DConfig keys, D-Bus constants, and filesystem paths.
src/plugin-qt/power/CMakeLists.txt Add power plugin subtree (session enabled; system commented out).
src/plugin-qt/CMakeLists.txt Wire power plugin into plugin-qt build.
debian/control Add Qt Wayland/protocol and tools build dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/plugin-qt/power/session/powersaveplan.cpp
Comment thread src/plugin-qt/power/session/screen/screencontroller_wl.h
Comment thread src/plugin-qt/power/session/screen/screencontroller_wl.cpp
Comment thread src/plugin-qt/power/session/idle/idlewatcher_wl.cpp
Comment thread src/plugin-qt/power/system/batterymanager.cpp
Comment thread src/plugin-qt/power/session/screen/screencontroller_wl.cpp Outdated
Comment thread src/plugin-qt/power/session/sessiondbusproxy.cpp Outdated
Comment thread debian/control Outdated
@mhduiy mhduiy force-pushed the treeland/power branch 2 times, most recently from 701efd4 to d65fb61 Compare May 28, 2026 12:29
1. Add new session-level power management plugin with org.deepin.dde.Power1 DBus service
2. Implement power save plan management with balance, performance, and power saver modes
3. Add low power notification and auto-sleep with configurable percentage and time thresholds
4. Implement idle detection (Wayland + X11), screen dimming/off/turn-off control
5. Add lid switch handler and sleep inhibitor mechanism for active operations
6. Include 20+ language translations and DBus service configuration files
7. Add qt6-tools-dev-tools and libudev-dev build dependencies

Log: Add session-level power management plugin with DBus service, power save plans, low power management, idle detection, and screen control

feat(power): 添加会话级电源管理插件

1. 新增会话级电源管理插件,提供 org.deepin.dde.Power1 DBus 服务接口
2. 实现电源节能方案管理,支持平衡、高性能、节能三种模式
3. 添加低电量通知与自动休眠功能,支持百分比和时间阈值配置
4. 实现空闲检测(Wayland 和 X11),支持屏幕调暗、熄屏、关闭显示器控制
5. 添加合盖事件处理和活跃操作防休眠机制
6. 包含 20+ 语言翻译文件及 DBus 服务配置文件
7. 新增 qt6-tools-dev-tools 和 libudev-dev 编译依赖

Log: 添加会话级电源管理插件,包含 DBus 服务、节能方案、低电量管理、空闲检测及屏幕控制
PMS: BUG-346597
PMS: BUG-346589
PMS: BUG-346575
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这份代码实现了一个功能丰富的 DDE 电源管理模块,涵盖了 Wayland/X11 的空闲检测、屏幕控制、电池监控、低电量处理、定时关机以及 CPU 调度策略等功能。整体架构清晰,模块划分合理。

但在语法逻辑、代码质量、性能和安全性方面,存在一些需要改进和注意的地方。以下是详细的审查意见:

一、 语法与逻辑问题

  1. C++ 标准库容器缺失哈希函数导致潜在编译错误

    • 位置: idlewatcher_wl.h 第 25 行
    • 代码: std::unordered_map<uint32_t, std::unique_ptr<IdleNotification>> m_notificationCache;
    • 问题: std::unique_ptr 默认不支持拷贝,且 std::unordered_mapemplace 在某些旧版本编译器或特定标准下可能引发编译错误。更重要的是,idlewatcher_wl.cpp 第 104 行使用了 m_notificationCache.emplace(timeoutSec, std::move(notif)),并解引用返回的迭代器 it->second.get()
    • 建议: 确保编译器完全支持 C++14 或 C++17(emplace 返回 pair<iterator, bool> 是 C++14 特性)。更稳妥的做法是使用 inserttry_emplace(C++17):
      auto [it, success] = m_notificationCache.try_emplace(timeoutSec, std::move(notif));
      m_activeNotification = it->second.get();
  2. 定时器 Lambda 捕获值导致倒计时失效

    • 位置: powermanager.cpp 第 670 行
    • 代码: connect(m_countdownTimer, &QTimer::timeout, this, [this, remaining]() mutable { remaining--; ... });
    • 问题: remaining 是按值捕获的,虽然使用了 mutable,但每次触发 timeout 时,remaining 只是在 Lambda 闭包内部递减,不会影响外部的任何状态。如果后续逻辑依赖外部的 remaining 变量,将产生逻辑错误。
    • 建议: 如果只是用于内部倒计时,当前逻辑可运行;但如果需要记录剩余时间,应将其提升为类成员变量 m_shutdownRemaining,在 Lambda 中修改成员变量。
  3. 未使用的变量与无效的分支判断

    • 位置: powersaveplan.cpp 第 166 行
    • 代码: if (t.delay < min || min == 0)
    • 问题: min 初始化为 0,且 t.delay 也是正数,min == 0 始终为真,导致前半部分 t.delay < min 永远不会被评估到。
    • 建议: 修正逻辑,应将 min 初始化为 INT_MAX,或修改判断条件:
      int min = INT_MAX;
      for (const auto &t : m_metaTasks) {
          if (t.delay < min) min = t.delay;
      }
      if (min == INT_MAX) min = 0; // 如果没有任务,回退为0
  4. X11 空实现导致空指针崩溃风险

    • 位置: powermanager.cpp 第 432 行
    • 代码: return m_useWayland ? new WaylandIdleWatcher(this) : nullptr;
    • 问题: 当运行在 X11 环境下,createIdleWatcher() 返回 nullptr。但在 PowerManager::initialize() 中,直接有 connect(m_idleWatcher, ...) 的调用,没有进行空指针判断,X11 下会引发段错误。
    • 建议: 增加 nullptr 检查,或者像 X11ScreenController 一样提供一个 X11 的空实现类 X11IdleWatcher(虽然当前是空类,但可以避免空指针):
      if (m_idleWatcher) {
          connect(m_idleWatcher, &IdleWatcher::idled, ...);
      }
  5. D-Bus 属性变更通知逻辑缺陷

    • 位置: powermanager.cpp notifyPropertyChanged
    • 问题: 遍历所有 Q_PROPERTY 寻找触发信号,时间复杂度为 O(N)。更严重的是,如果两个属性的 NOTIFY 信号相同(或者一个信号触发多次),此逻辑可能失效或产生冗余信号。
    • 建议: Qt 的 QDBusAbstractAdaptor 自动处理属性变更通知。如果不使用 Adaptor,建议使用 QMetaMethod::fromSignal 缓存映射关系,或者在 setter 中直接发送特定属性的变更信号,避免全局遍历。

二、 代码质量与可维护性

  1. 宏定义的 Setter 过于隐晦

    • 位置: powermanager.cpp DEF_SETTER_PERSIST
    • 问题: 大量使用宏生成 Setter 函数。这严重降低了代码的可读性,IDE 无法进行代码跳转和智能提示,且调试时难以定位。
    • 建议: 建议手写 Setter,或者如果一定要用宏,请确保有详细的文档说明。对于 DConfig 这种强绑定逻辑,手写更能体现业务语义。
  2. 硬编码的魔法数字

    • 位置: 多处,如 lowpowermanager.cpp 中的 3, 4, 5lidswitchhandler.cpp 中的 1500powermanager.cpp 中的 500, 200
    • 问题: 缺乏语义,难以理解其含义。
    • 建议: 抽取为具名常量或枚举。例如:
      static constexpr int LOCK_BEFORE_SUSPEND_DELAY_S = 3;
      static constexpr int SHOW_LOW_POWER_DELAY_S = 4;
  3. 重复的 D-Bus 接口硬编码

    • 位置: systemdbusproxy.cpp
    • 问题: QDBusInterface iface(kUPowerService, kUPowerPath, kUPowerService, ...) 中,接口名使用了 kUPowerService (org.freedesktop.UPower),这是不规范的,UPower 的接口名通常也是这个,但最好定义一个专门的 kUPowerInterface 常量,以区分服务名和接口名。
  4. 缺少 override 关键字

    • 位置: sessiondbusproxy.h 等头文件中的属性读取函数(如 onBattery() 等)。
    • 问题: 继承自某种基类(或预期被继承)时,虚函数未加 override
    • 建议: 严格使用 override 关键字,防止因签名不匹配导致的隐蔽 Bug。

三、 性能问题

  1. 高频 D-Bus 同步调用阻塞主线程

    • 位置: lowpowermanager.cpp lockWaitShow
    • 代码:
      QDBusInterface sm(...);
      if (sm.isValid() && sm.property("Locked").toBool()) { ... }
    • 问题: 在 300ms 的定时器中,使用同步的 property() 调用获取 D-Bus 属性。这会导致事件循环阻塞,严重影响 UI 流畅度。
    • 建议: 改为异步获取,或者监听 D-Bus 的 PropertiesChanged 信号来获取锁定状态,而不是轮询。
  2. sysfs 电池状态的频繁轮询

    • 位置: batterymanager.cpp pollBattery
    • 问题: 每分钟通过读取 /sys/class/power_supply/ 下的多个文件来轮询电池状态,且在 AC 变化时触发多达 14 次的延迟轮询(1s, 3s... 60s)。频繁的文件 I/O 和字符串解析(readAll().trimmed().toInt())会消耗资源。
    • 建议: 既然已经使用了 udev 监听,应完全依赖 udev 的事件驱动机制,取消 1 分钟的定时器轮询。如果必须轮询,应减少轮询频率,或在检测到电池状态稳定后停止轮询。
  3. Wayland 协议对象的重复创建

    • 位置: screencontroller_wl.cpp discoverOutputs
    • 问题: 每次 discoverOutputs 被调用时,都会重新创建 OutputPowerOutputColorControl 对象,但没有清理旧对象的逻辑(如果被多次调用)。
    • 建议: 确保 discoverOutputs 仅在初始化时调用一次,或者在重新发现时,先销毁旧的 Wayland 对象。

四、 安全性问题

  1. 硬编码的临时文件路径与符号链接攻击

    • 位置: powermanager.cpp setDPMSModeOff / powerconstants.h
    • 代码: const auto dpmsPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + QStringLiteral("/dpms-state");
    • 问题: /tmp/dpms-state(在 Linux 下 RuntimeLocation 通常是 /run/user/UID,但常量定义的是 /tmp/dpms-state)存在安全隐患。如果 /tmp 目录全局可写,恶意用户可以创建符号链接指向敏感文件(如 /etc/passwd),当程序以高权限写入 "1" 时,会覆盖目标文件。
    • 建议:
      1. 绝对不要使用 /tmp 作为状态文件路径,应使用 QStandardPaths::RuntimeLocation(即 /run/user/UID/)。
      2. 修改 powerconstants.h 中的 kDpmsStateFile,去掉 /tmp 硬编码。
      3. 在写入文件前,检查文件是否为符号链接,或使用 QFile::open 时的安全标志。
  2. D-Bus Inhibit FD 泄漏与重复关闭

    • 位置: powermanager.cpp initLogindInhibitonLogin1OwnerChanged
    • 代码: m_inhibitFd = fd.isValid() ? dup(fd.fileDescriptor()) : -1;
    • 问题: QDBusUnixFileDescriptor 本身会管理文件描述符的生命周期。这里使用 dup() 复制了一个 FD,如果 onLogin1OwnerChanged 触发,会调用 ::close(m_inhibitFd)。但如果 m_inhibitFd 由于某些异常未被正确重置,可能会关闭已经被分配给其他资源的 FD(FD 重用攻击/误操作)。
    • 建议: 使用 QScopedFileDescriptor 来管理 dup 出来的 FD,确保异常路径下也能正确关闭,且不会重复 close。
  3. 外部命令执行的安全性

    • 位置: lowpowermanager.cpp playBatterySoundsystem/powermanager.cpp setMode
    • 代码: QProcess::startDetached("paplay", ...)QProcess::startDetached("/usr/sbin/deepin-power-control", ...)
    • 问题: 如果环境变量 PATH 被恶意篡改,可能执行伪造的 paplay 程序。
    • 建议: 始终使用绝对路径(当前代码中 paplay 没有使用绝对路径,而 deepin-power-control 使用了),并确保运行环境的安全。
  4. X11 环境下的权限提升风险

    • 位置: system/powermanager.cpp initCpuGovernor
    • 问题: 直接读写 /sys/devices/system/cpu/... 需要极高权限。如果该系统服务以 root 运行,而 X11 客户端可以通过某种方式触发此逻辑,可能引发 DoS(通过频繁写入 sysfs)。
    • 建议: 确保写 sysfs 的操作仅限于系统 D-Bus 调用,且增加频率限制。

总结建议

  1. 优先修复空指针问题:X11 下 m_idleWatchernullptr 导致的崩溃是阻断性 Bug。
  2. 重构 D-Bus 同步调用lockWaitShow 中的轮询必须改为信号驱动,否则会引发界面卡顿。
  3. 消除安全隐患:修复 /tmp/dpms-state 的写入问题,改用安全目录。
  4. 优化电池轮询逻辑:减少不必要的文件读取,充分发挥 udev 的作用。
  5. 清理魔法数字与宏:提升代码可读性与长期可维护性。

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