Skip to content

Commit 25ceb10

Browse files
committed
feat: recover power mode after sleep/shutdown/reboot
When performing shutdown, reboot, hibernate or suspend operations, switch to performance mode before the operation, and restore the user's configured power mode upon wake or next startup. This ensures smooth transitions and optimal performance during these critical operations. Key changes: 1. Add `setTlpMode()` helper function to set power mode via D-Bus 2. Add `recoverySystemPowerMode()` to restore user's configured power mode after wake 3. Call `setTlpMode(Performance)` before shutdown, reboot, hibernate, and suspend 4. Connect to `PrepareForSleep` signal to restore mode after sleep wake 5. On startup, schedule recovery of power mode via timer Log: Optimized power management behavior during system suspend/ hibernate/reboot/shutdown Influence: 1. Test shutdown: verify system switches to performance mode before shutdown 2. Test reboot: verify performance mode is set before reboot 3. Test hibernate: verify performance mode is set before hibernation 4. Test suspend: verify performance mode is set before suspend 5. Test wake from sleep: verify user's original power mode is restored 6. Test startup: verify power mode is restored to user's configuration 7. Test with/without battery: verify low battery mode handling on battery ≤20% 8. Verify D-Bus communication with org.deepin.dde.Power1 service 9. Test error handling when D-Bus calls fail feat: 恢复休眠/关机/重启后的电源模式 在执行关机、重启、休眠或挂起操作前,先将系统切换到高性能模式,操作完成后 (唤醒或下次启动)再恢复为用户之前配置的电源模式。这确保了这些关键操作期 间的流畅过渡和最佳性能。 主要变更: 1. 添加 `setTlpMode()` 辅助函数,通过 D-Bus 设置电源模式 2. 添加 `recoverySystemPowerMode()` 恢复用户配置的电源模式 3. 在关机、重启、休眠和挂起前调用 `setTlpMode(Performance)` 4. 连接 `PrepareForSleep` 信号,在睡眠唤醒后恢复模式 5. 在启动时通过定时器调度恢复电源模式 Log: 优化系统挂起/休眠/重启/关机时的电源管理行为 Influence: 1. 测试关机:验证关机前是否切换为高性能模式 2. 测试重启:验证重启前是否设置为高性能模式 3. 测试休眠:验证休眠前是否设置为高性能模式 4. 测试挂起:验证挂起前是否设置为高性能模式 5. 测试从睡眠唤醒:验证是否恢复用户原始电源模式 6. 测试启动:验证电源模式是否恢复为用户配置 7. 测试有/无电池情况:验证电池电量≤20%时的低电量模式处理 8. 验证与 org.deepin.dde.Power1 服务的 D-Bus 通信 9. 测试 D-Bus 调用失败时的错误处理 PMS: TASK-389737 Change-Id: I30122c303b2b61a4912a554ccfb0d75dce3747a1
1 parent f832510 commit 25ceb10

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

src/dde-session/impl/sessionmanager.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@
1919
#include <QDBusPendingCallWatcher>
2020
#include <QSocketNotifier>
2121
#include <DConfig>
22+
#include <QTimer>
2223

2324
#include <unistd.h>
2425
#include <signal.h>
2526
#include <xcb/xcb.h>
2627

2728
using namespace Dtk::Core;
2829

30+
static const QString Performance = QStringLiteral("performance");
31+
static const QString PowerSave = QStringLiteral("powersave");
32+
static const QString LowBattery = QStringLiteral("lowBattery");
33+
2934
#define MASK_SERVICE(service) \
3035
{\
3136
auto reply = m_systemd1ManagerInter->MaskUnitFiles(QStringList() << service, true, true);\
@@ -126,6 +131,14 @@ void SessionManager::initConnections()
126131
const bool active = m_login1SessionInter->active();
127132
Q_UNUSED(active)
128133

134+
connect(m_login1ManagerInter, &org::freedesktop::login1::Manager::PrepareForSleep, [=](bool sleep) {
135+
qDebug() << "system is preparing for sleep: " << sleep;
136+
if (!sleep) {
137+
// 唤醒后恢复之前的电源模式
138+
recoverySystemPowerMode();
139+
}
140+
});
141+
129142
connect(m_login1SessionInter, &org::freedesktop::login1::Session::ActiveChanged, [=](bool active) {
130143
qDebug() << "session active status changed to:" << active;
131144
if (active) {
@@ -396,6 +409,7 @@ bool SessionManager::Register(const QString &id)
396409

397410
void SessionManager::RequestHibernate()
398411
{
412+
setTlpMode(Performance);
399413
QDBusPendingReply<> reply = m_login1ManagerInter->Hibernate(false);
400414
if (reply.isError()) {
401415
qWarning() << "failed to hibernate, error: " << reply.error().name();
@@ -439,11 +453,13 @@ void SessionManager::RequestLogout()
439453

440454
void SessionManager::RequestReboot()
441455
{
456+
setTlpMode(Performance);
442457
reboot(true);
443458
}
444459

445460
void SessionManager::RequestShutdown()
446461
{
462+
setTlpMode(Performance);
447463
shutdown(true);
448464
}
449465

@@ -455,6 +471,8 @@ void SessionManager::RequestSuspend()
455471
return;
456472
}
457473

474+
setTlpMode(Performance);
475+
458476
QDBusPendingReply<> reply = m_login1ManagerInter->Suspend(false);
459477
if (reply.isError()) {
460478
qWarning() << "failed to suspend, error:" << reply.error().name();
@@ -530,6 +548,10 @@ void SessionManager::init()
530548
if (!Utils::IS_WAYLAND_DISPLAY) {
531549
watchXConnection();
532550
}
551+
552+
QTimer::singleShot(0, this, [this] {
553+
recoverySystemPowerMode();
554+
});
533555

534556
qInfo() << "session manager init finished";
535557
}
@@ -845,6 +867,71 @@ void SessionManager::handleOSSignal()
845867
signal(SIGSEGV, sig_crash);
846868
}
847869

870+
void SessionManager::setTlpMode(const QString &mode)
871+
{
872+
qInfo() << "setTlpMode mode:" << mode;
873+
QDBusInterface inter("org.deepin.dde.Power1", "/org/deepin/dde/Power1", "org.deepin.dde.Power1", QDBusConnection::systemBus());
874+
inter.setTimeout(3000); // 3秒超时,防止关机流程被阻塞
875+
QDBusMessage reply = inter.call("SetTlpMode", mode);
876+
if (reply.type() == QDBusMessage::ErrorMessage) {
877+
qWarning() << "SetTlpMode failed:" << reply.errorMessage();
878+
}
879+
}
880+
881+
void SessionManager::recoverySystemPowerMode()
882+
{
883+
qInfo() << "recoverySystemPowerMode";
884+
QDBusInterface inter("org.deepin.dde.Power1", "/org/deepin/dde/Power1",
885+
"org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
886+
887+
// 获取 TlpMode
888+
QDBusMessage tlpMsg = inter.call("Get", "org.deepin.dde.Power1", "TlpMode");
889+
QString tlpMode;
890+
if (tlpMsg.type() == QDBusMessage::ReplyMessage) {
891+
tlpMode = tlpMsg.arguments().value(0).value<QDBusVariant>().variant().toString();
892+
} else {
893+
qWarning() << "Get DBus property TlpMode failed:" << tlpMsg.errorMessage();
894+
return;
895+
}
896+
897+
// 获取 Mode
898+
QDBusMessage modeMsg = inter.call("Get", "org.deepin.dde.Power1", "Mode");
899+
QString mode;
900+
if (modeMsg.type() == QDBusMessage::ReplyMessage) {
901+
mode = modeMsg.arguments().value(0).value<QDBusVariant>().variant().toString();
902+
} else {
903+
qWarning() << "Get DBus property Mode failed:" << modeMsg.errorMessage();
904+
return;
905+
}
906+
907+
qInfo() << "DBus property of TlpMode:" << tlpMode << ", Mode:" << mode;
908+
909+
if (mode == tlpMode)
910+
return;
911+
912+
// 如果目标是节能模式,检查电池状态决定是否需要切换到低电量模式
913+
if (mode == PowerSave) {
914+
QDBusMessage batteryMsg = inter.call("Get", "org.deepin.dde.Power1", "HasBattery");
915+
if (batteryMsg.type() == QDBusMessage::ReplyMessage) {
916+
bool hasBattery = batteryMsg.arguments().value(0).value<QDBusVariant>().variant().toBool();
917+
if (!hasBattery) {
918+
setTlpMode(mode);
919+
return;
920+
}
921+
922+
QDBusMessage capacityMsg = inter.call("Get", "org.deepin.dde.Power1", "BatteryCapacity");
923+
if (capacityMsg.type() == QDBusMessage::ReplyMessage) {
924+
double batteryCapacity = capacityMsg.arguments().value(0).value<QDBusVariant>().variant().toDouble();
925+
if (batteryCapacity <= 20.0) {
926+
mode = LowBattery;
927+
}
928+
}
929+
}
930+
}
931+
932+
setTlpMode(mode);
933+
}
934+
848935
void SessionManager::shutdown(bool force)
849936
{
850937
prepareShutdown(force);

src/dde-session/impl/sessionmanager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public Q_SLOTS:
102102
void watchXConnection();
103103

104104
void shutdown(bool force);
105+
void setTlpMode(const QString &mode);
106+
void recoverySystemPowerMode();
105107
void reboot(bool force);
106108

107109
// 主动触发DBus的PropertiesChanged信息,否则调用方无法监听属性变化

0 commit comments

Comments
 (0)