Skip to content

Commit 286299b

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 31f0297 commit 286299b

2 files changed

Lines changed: 86 additions & 0 deletions

File tree

src/dde-session/impl/sessionmanager.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919
#include <QDBusPendingCall>
2020
#include <QDBusPendingCallWatcher>
2121
#include <QSocketNotifier>
22+
#include <QTimer>
2223

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

28+
static const QString Performance = QStringLiteral("performance");
29+
static const QString PowerSave = QStringLiteral("powersave");
30+
static const QString LowBattery = QStringLiteral("lowBattery");
31+
2732
#define MASK_SERVICE(service) \
2833
{\
2934
auto reply = m_systemd1ManagerInter->MaskUnitFiles(QStringList() << service, true, true);\
@@ -124,6 +129,14 @@ void SessionManager::initConnections()
124129
const bool active = m_login1SessionInter->active();
125130
Q_UNUSED(active)
126131

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

405418
void SessionManager::RequestHibernate()
406419
{
420+
setTlpMode(Performance);
407421
QDBusPendingReply<> reply = m_login1ManagerInter->Hibernate(false);
408422
if (reply.isError()) {
409423
qWarning() << "failed to hibernate, error: " << reply.error().name();
@@ -447,11 +461,13 @@ void SessionManager::RequestLogout()
447461

448462
void SessionManager::RequestReboot()
449463
{
464+
setTlpMode(Performance);
450465
reboot(true);
451466
}
452467

453468
void SessionManager::RequestShutdown()
454469
{
470+
setTlpMode(Performance);
455471
shutdown(true);
456472
}
457473

@@ -463,6 +479,8 @@ void SessionManager::RequestSuspend()
463479
return;
464480
}
465481

482+
setTlpMode(Performance);
483+
466484
// 使用窗管接口进行黑屏处理
467485
if (Dconf::SetValue("com.deepin.dde.startdde", "", "quick-black-screen", QVariant(false))) {
468486
QDBusInterface inter("org.kde.KWin", "/BlackScreen", "org.kde.kwin.BlackScreen", QDBusConnection::sessionBus(), this);
@@ -546,6 +564,10 @@ void SessionManager::init()
546564
if (!Utils::IS_WAYLAND_DISPLAY) {
547565
watchXConnection();
548566
}
567+
568+
QTimer::singleShot(0, this, [this] {
569+
recoverySystemPowerMode();
570+
});
549571

550572
qInfo() << "session manager init finished";
551573
}
@@ -860,6 +882,68 @@ void SessionManager::handleOSSignal()
860882
signal(SIGSEGV, sig_crash);
861883
}
862884

885+
void SessionManager::setTlpMode(const QString &mode)
886+
{
887+
qInfo() << "setTlpMode mode:" << mode;
888+
QDBusInterface inter("org.deepin.dde.Power1", "/org/deepin/dde/Power1", "org.deepin.dde.Power1", QDBusConnection::systemBus());
889+
QDBusPendingReply<> reply = inter.asyncCall("SetTlpMode", mode);
890+
Q_UNUSED(reply)
891+
}
892+
893+
void SessionManager::recoverySystemPowerMode()
894+
{
895+
qInfo() << "recoverySystemPowerMode";
896+
QDBusInterface inter("org.deepin.dde.Power1", "/org/deepin/dde/Power1",
897+
"org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
898+
899+
// 获取 TlpMode
900+
QDBusMessage tlpMsg = inter.call("Get", "org.deepin.dde.Power1", "TlpMode");
901+
QString tlpMode;
902+
if (tlpMsg.type() == QDBusMessage::ReplyMessage) {
903+
tlpMode = tlpMsg.arguments().value(0).value<QDBusVariant>().variant().toString();
904+
} else {
905+
qWarning() << "Get DBus property TlpMode failed:" << tlpMsg.errorMessage();
906+
return;
907+
}
908+
909+
// 获取 Mode
910+
QDBusMessage modeMsg = inter.call("Get", "org.deepin.dde.Power1", "Mode");
911+
QString mode;
912+
if (modeMsg.type() == QDBusMessage::ReplyMessage) {
913+
mode = modeMsg.arguments().value(0).value<QDBusVariant>().variant().toString();
914+
} else {
915+
qWarning() << "Get DBus property Mode failed:" << modeMsg.errorMessage();
916+
return;
917+
}
918+
919+
qInfo() << "DBus property of TlpMode:" << tlpMode << ", Mode:" << mode;
920+
921+
if (mode == tlpMode)
922+
return;
923+
924+
// 如果目标是节能模式,检查电池状态决定是否需要切换到低电量模式
925+
if (mode == PowerSave) {
926+
QDBusMessage batteryMsg = inter.call("Get", "org.deepin.dde.Power1", "HasBattery");
927+
if (batteryMsg.type() == QDBusMessage::ReplyMessage) {
928+
bool hasBattery = batteryMsg.arguments().value(0).value<QDBusVariant>().variant().toBool();
929+
if (!hasBattery) {
930+
setTlpMode(mode);
931+
return;
932+
}
933+
934+
QDBusMessage capacityMsg = inter.call("Get", "org.deepin.dde.Power1", "BatteryCapacity");
935+
if (capacityMsg.type() == QDBusMessage::ReplyMessage) {
936+
double batteryCapacity = capacityMsg.arguments().value(0).value<QDBusVariant>().variant().toDouble();
937+
if (batteryCapacity <= 20.0) {
938+
mode = LowBattery;
939+
}
940+
}
941+
}
942+
}
943+
944+
setTlpMode(mode);
945+
}
946+
863947
void SessionManager::shutdown(bool force)
864948
{
865949
prepareShutdown(force);

src/dde-session/impl/sessionmanager.h

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

105105
void shutdown(bool force);
106+
void setTlpMode(const QString &mode);
107+
void recoverySystemPowerMode();
106108
void reboot(bool force);
107109

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

0 commit comments

Comments
 (0)