kiran-session-manager/0001-feature-lockscreen-Add-LockScreenWhenHibernate-and-L.patch
tangjie02 8bc5a543cc feature(lockscreen): Add LockScreenWhenHibernate and LockScreenWhenSuspend functions
- 添加当计算机休眠/待机时是否锁屏功能

Relates #68459

Signed-off-by: tangjie02 <tangjie02@kylinsec.com.cn>
2023-05-11 08:51:01 +08:00

463 lines
16 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From b6ac29d2838bedab513d6cdfb21084b95da0a70c Mon Sep 17 00:00:00 2001
From: tangjie02 <tangjie02@kylinsec.com.cn>
Date: Tue, 9 May 2023 17:06:03 +0800
Subject: [PATCH] feature(lockscreen): Add LockScreenWhenHibernate and
LockScreenWhenSuspend functions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 添加当计算机休眠/待机时是否锁屏功能
Relates #68459
Signed-off-by: tangjie02 <tangjie02@kylinsec.com.cn>
---
...insec.kiran.session-manager.gschema.xml.in | 10 +++
data/org.gnome.SessionManager.xml | 40 +++++++++++
include/ksm-i.h | 12 ++--
lib/dbus/systemd-login1.cpp | 1 +
src/core/power.cpp | 68 +++++++++++++++++--
src/core/power.h | 7 ++
src/core/presence.cpp | 3 -
src/core/session-manager.cpp | 68 +++++++++++++++++++
src/core/session-manager.h | 15 ++++
9 files changed, 210 insertions(+), 14 deletions(-)
diff --git a/data/com.kylinsec.kiran.session-manager.gschema.xml.in b/data/com.kylinsec.kiran.session-manager.gschema.xml.in
index 6d2b361..b71dd3e 100644
--- a/data/com.kylinsec.kiran.session-manager.gschema.xml.in
+++ b/data/com.kylinsec.kiran.session-manager.gschema.xml.in
@@ -5,6 +5,16 @@
<summary>Time before session is considered idle</summary>
<description>The number of minutes of inactivity before the session is considered idle</description>
</key>
+
+ <key name="screen-locked-when-suspend" type="b">
+ <default>true</default>
+ <description>Whether lock screen when the computer is suspend.</description>
+ </key>
+
+ <key name="screen-locked-when-hibernate" type="b">
+ <default>true</default>
+ <description>Whether lock screen when the computer is hibernate.</description>
+ </key>
</schema>
</schemalist>
diff --git a/data/org.gnome.SessionManager.xml b/data/org.gnome.SessionManager.xml
index 9b4cec5..92ba554 100644
--- a/data/org.gnome.SessionManager.xml
+++ b/data/org.gnome.SessionManager.xml
@@ -72,6 +72,28 @@
<description>This gets a list of all the inhibitors that are currently known to the session manager.</description>
</method>
+ <method name="Suspend">
+ <description>Suspend computer.</description>
+ </method>
+
+ <method name="CanSuspend">
+ <arg name="is_available" direction="out" type="b">
+ <summary>True if suspend is available to the user, false otherwise.</summary>
+ </arg>
+ <description>Whether the user can suspend.</description>
+ </method>
+
+ <method name="Hibernate">
+ <description>Hibernate computer.</description>
+ </method>
+
+ <method name="CanHibernate">
+ <arg name="is_available" direction="out" type="b">
+ <summary>True if hibernate is available to the user, false otherwise.</summary>
+ </arg>
+ <description>Whether the user can hibernate.</description>
+ </method>
+
<method name="Shutdown">
<description>Shutdown the system.</description>
</method>
@@ -126,6 +148,14 @@
<description>Adds the variable name to the application launch environment with the specified value. May only be used during the Session Manager initialization phase.</description>
</method>
+ <property name="ScreenLockedWhenSuspend" type="b" access="readwrite">
+ <description>Whether lock screen when the computer is suspend.</description>
+ </property>
+
+ <property name="ScreenLockedWhenHibernate" type="b" access="readwrite">
+ <description>Whether lock screen when the computer is hibernate.</description>
+ </property>
+
<signal name="InhibitorAdded">
<arg name="cookie" type="u">
<summary>The inhibitor cookie.</summary>
@@ -145,5 +175,15 @@
<description>The stage where session manager is in.</description>
</signal>
+ <signal name="ScreenLockedWhenSuspendChanged">
+ <arg name="screen_locked_when_suspend" type="b" />
+ <description>Whether lock screen when the computer is suspend.</description>
+ </signal>
+
+ <signal name="ScreenLockedWhenHibernateChanged">
+ <arg name="screen_locked_when_hibernate" type="b" />
+ <description>Whether lock screen when the computer is hibernate.</description>
+ </signal>
+
</interface>
</node>
diff --git a/include/ksm-i.h b/include/ksm-i.h
index 71376dc..ca4bb86 100644
--- a/include/ksm-i.h
+++ b/include/ksm-i.h
@@ -21,6 +21,8 @@ extern "C"
#define DESKTOP_ENVIRONMENT "KIRAN"
+/* 为了保持跟第三方应用(firefox、pluma等)兼容暂时还是使用gnome名字。
+ 但后续版本有可能更名,所以最好使用宏定义,不要直接使用字符串常量。*/
#define KSM_DBUS_NAME "org.gnome.SessionManager"
#define KSM_DBUS_OBJECT_PATH "/org/gnome/SessionManager"
#define KSM_DBUS_INTERFACE_NAME "org.gnome.SessionManager"
@@ -34,10 +36,12 @@ extern "C"
#define KSM_IDLE_DBUS_OBJECT_PATH "/com/kylinsec/Kiran/SessionManager/IdleMonitor"
#define KSM_SCHEMA_ID "com.kylinsec.kiran.session-manager"
-#define KSM_SCHEMA_KEY_SESSION_DAEMONS "session-daemons"
-#define KSM_SCHEMA_KEY_WINDOW_MANAGER "window-manager"
-#define KSM_SCHEMA_KEY_PANEL "panel"
-#define KSM_SCHEMA_KEY_FILE_MANAGER "file-manager"
+// 计算机多久未操作视为空闲
+#define KSM_SCHEMA_KEY_IDLE_DELAY "idle-delay"
+// 待机时是否锁定屏幕
+#define KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND "screen-locked-when-suspend"
+// 休眠时是否锁定屏幕
+#define KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE "screen-locked-when-hibernate"
// JK: json key
#define KSM_INHIBITOR_JK_COOKIE "cookie"
diff --git a/lib/dbus/systemd-login1.cpp b/lib/dbus/systemd-login1.cpp
index dea49e8..e2416a3 100644
--- a/lib/dbus/systemd-login1.cpp
+++ b/lib/dbus/systemd-login1.cpp
@@ -188,6 +188,7 @@ bool SystemdLogin1::canDoMethod(const QString &methodName)
auto canResult = replyMessage.arguments().takeFirst().toString();
KLOG_DEBUG() << "Function " << methodName << " return " << canResult;
+ // TODO: 需要确认challenge状态是否可以执行电源动作
return (canResult == "yes" || canResult == "challenge");
}
diff --git a/src/core/power.cpp b/src/core/power.cpp
index 2bc3ac5..87200fb 100644
--- a/src/core/power.cpp
+++ b/src/core/power.cpp
@@ -13,6 +13,7 @@
*/
#include "src/core/power.h"
+#include <QGSettings>
#include "lib/base/base.h"
#include "lib/dbus/display-manager.h"
#include "lib/dbus/screensaver.h"
@@ -22,6 +23,7 @@ namespace Kiran
{
Power::Power(QObject *parent) : QObject(parent)
{
+ this->m_settings = new QGSettings(KSM_SCHEMA_ID, "", this);
}
void Power::init()
@@ -54,7 +56,7 @@ bool Power::canPowerAction(PowerAction powerAction)
bool Power::doPowerAction(PowerAction powerAction)
{
- KLOG_DEBUG() << "Power action: " << powerAction;
+ KLOG_DEBUG() << "Do power action: " << this->powerActionEnum2Str(powerAction);
switch (powerAction)
{
@@ -84,20 +86,50 @@ bool Power::switchUser()
bool Power::suspend()
{
+ uint32_t throttle = 0;
+
RETURN_VAL_IF_TRUE(!SystemdLogin1::getDefault()->canSuspend(), false);
- // 这里忽略锁屏失败的情况
- ScreenSaver::getDefault()->lock();
- return SystemdLogin1::getDefault()->suspend();
+ // 挂起之前判断是否锁定屏幕
+ auto lockscreen = this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND).toBool();
+ if (lockscreen)
+ {
+ throttle = ScreenSaver::getDefault()->lockAndThrottle("suspend");
+ }
+
+ auto retval = SystemdLogin1::getDefault()->suspend();
+
+ ScreenSaver::getDefault()->poke();
+ if (throttle)
+ {
+ ScreenSaver::getDefault()->removeThrottle(throttle);
+ }
+
+ return retval;
}
bool Power::hibernate()
{
+ uint32_t throttle = 0;
+
RETURN_VAL_IF_TRUE(!SystemdLogin1::getDefault()->canHibernate(), false);
- // 这里忽略锁屏失败的情况
- ScreenSaver::getDefault()->lock();
- return SystemdLogin1::getDefault()->hibernate();
+ // 休眠之前判断是否锁定屏幕
+ auto lockscreen = this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE).toBool();
+ if (lockscreen)
+ {
+ throttle = ScreenSaver::getDefault()->lockAndThrottle("hibernate");
+ }
+
+ auto retval = SystemdLogin1::getDefault()->hibernate();
+
+ ScreenSaver::getDefault()->poke();
+ if (throttle)
+ {
+ ScreenSaver::getDefault()->removeThrottle(throttle);
+ }
+
+ return retval;
}
bool Power::shutdown()
@@ -112,4 +144,26 @@ bool Power::reboot()
return SystemdLogin1::getDefault()->reboot();
}
+QString Power::powerActionEnum2Str(PowerAction powerAction)
+{
+ switch (powerAction)
+ {
+ case PowerAction::POWER_ACTION_SWITCH_USER:
+ return "switch user";
+ case PowerAction::POWER_ACTION_LOGOUT:
+ return "logout";
+ case PowerAction::POWER_ACTION_SUSPEND:
+ return "suspend";
+ case PowerAction::POWER_ACTION_HIBERNATE:
+ return "hibernate";
+ case PowerAction::POWER_ACTION_SHUTDOWN:
+ return "shutdown";
+ case PowerAction::POWER_ACTION_REBOOT:
+ return "reboot";
+ default:
+ break;
+ }
+ return "unknown";
+}
+
} // namespace Kiran
\ No newline at end of file
diff --git a/src/core/power.h b/src/core/power.h
index cbc2b21..14bcdda 100644
--- a/src/core/power.h
+++ b/src/core/power.h
@@ -17,6 +17,8 @@
#include <QObject>
#include "ksm-i.h"
+class QGSettings;
+
namespace Kiran
{
class Power : public QObject
@@ -44,5 +46,10 @@ private:
bool shutdown();
// 重启
bool reboot();
+
+ QString powerActionEnum2Str(PowerAction powerAction);
+
+private:
+ QGSettings *m_settings;
};
} // namespace Kiran
\ No newline at end of file
diff --git a/src/core/presence.cpp b/src/core/presence.cpp
index f41fa24..d7e73f3 100644
--- a/src/core/presence.cpp
+++ b/src/core/presence.cpp
@@ -22,9 +22,6 @@
namespace Kiran
{
-#define KSM_SCHEMA_ID "com.kylinsec.kiran.session-manager"
-#define KSM_SCHEMA_KEY_IDLE_DELAY "idleDelay"
-
Presence::Presence(QObject *parent) : QObject(parent),
m_idleMonitorProxy(nullptr),
m_enabledIdleTimeout(true),
diff --git a/src/core/session-manager.cpp b/src/core/session-manager.cpp
index 1f33db7..12dcc15 100644
--- a/src/core/session-manager.cpp
+++ b/src/core/session-manager.cpp
@@ -73,6 +73,39 @@ void SessionManager::start()
this->processPhase();
}
+bool SessionManager::screenLockedWhenHibernate()
+{
+ return this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE).toBool();
+}
+
+void SessionManager::setScreenLockedWhenHibernate(bool screenLockedWhenHibernate)
+{
+ if (screenLockedWhenHibernate != this->screenLockedWhenHibernate())
+ {
+ this->m_settings->set(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE, screenLockedWhenHibernate);
+ Q_EMIT this->ScreenLockedWhenHibernateChanged(screenLockedWhenHibernate);
+ }
+}
+
+bool SessionManager::screenLockedWhenSuspend()
+{
+ return this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND).toBool();
+}
+
+void SessionManager::setScreenLockedWhenSuspend(bool screenLockedWhenSuspend)
+{
+ if (screenLockedWhenSuspend != this->screenLockedWhenSuspend())
+ {
+ this->m_settings->set(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND, screenLockedWhenSuspend);
+ Q_EMIT this->ScreenLockedWhenSuspendChanged(screenLockedWhenSuspend);
+ }
+}
+
+bool SessionManager::CanHibernate()
+{
+ return this->m_power->canPowerAction(PowerAction::POWER_ACTION_HIBERNATE);
+}
+
bool SessionManager::CanLogout()
{
return true;
@@ -88,6 +121,11 @@ bool SessionManager::CanShutdown()
return this->m_power->canPowerAction(PowerAction::POWER_ACTION_SHUTDOWN);
}
+bool SessionManager::CanSuspend()
+{
+ return this->m_power->canPowerAction(PowerAction::POWER_ACTION_SUSPEND);
+}
+
QString SessionManager::GetInhibitor(uint cookie)
{
QJsonDocument jsonDoc;
@@ -133,6 +171,21 @@ QString SessionManager::GetInhibitors()
return QString(jsonDoc.toJson());
}
+void SessionManager::Hibernate()
+{
+ if (this->m_currentPhase > KSMPhase::KSM_PHASE_RUNNING)
+ {
+ DBUS_ERROR_REPLY_AND_RET(QDBusError::InvalidArgs, KSMErrorCode::ERROR_MANAGER_PHASE_INVALID);
+ }
+
+ if (!this->m_power->canPowerAction(PowerAction::POWER_ACTION_HIBERNATE))
+ {
+ DBUS_ERROR_REPLY_AND_RET(QDBusError::AccessDenied, KSMErrorCode::ERROR_MANAGER_POWER_ACTION_UNSUPPORTED);
+ }
+
+ this->m_power->doPowerAction(PowerAction::POWER_ACTION_HIBERNATE);
+}
+
uint SessionManager::SessionManager::Inhibit(const QString &appID,
uint toplevelXID,
const QString &reason,
@@ -246,6 +299,21 @@ void SessionManager::Shutdown()
this->startNextPhase();
}
+void SessionManager::Suspend()
+{
+ if (this->m_currentPhase > KSMPhase::KSM_PHASE_RUNNING)
+ {
+ DBUS_ERROR_REPLY_AND_RET(QDBusError::InvalidArgs, KSMErrorCode::ERROR_MANAGER_PHASE_INVALID);
+ }
+
+ if (!this->m_power->canPowerAction(PowerAction::POWER_ACTION_SUSPEND))
+ {
+ DBUS_ERROR_REPLY_AND_RET(QDBusError::AccessDenied, KSMErrorCode::ERROR_MANAGER_POWER_ACTION_UNSUPPORTED);
+ }
+
+ this->m_power->doPowerAction(PowerAction::POWER_ACTION_SUSPEND);
+}
+
void SessionManager::Uninhibit(uint inhibitCookie)
{
auto inhibitor = InhibitorManager::getInstance()->getInhibitor(inhibitCookie);
diff --git a/src/core/session-manager.h b/src/core/session-manager.h
index 8e6ffab..3d934e2 100644
--- a/src/core/session-manager.h
+++ b/src/core/session-manager.h
@@ -40,6 +40,9 @@ class SessionManager : public QObject,
protected QDBusContext
{
Q_OBJECT
+
+ Q_PROPERTY(bool ScreenLockedWhenHibernate READ screenLockedWhenHibernate WRITE setScreenLockedWhenHibernate)
+ Q_PROPERTY(bool ScreenLockedWhenSuspend READ screenLockedWhenSuspend WRITE setScreenLockedWhenSuspend)
public:
SessionManager(AppManager *appManager,
ClientManager *clientManager,
@@ -57,13 +60,22 @@ public:
// 会话开始
void start();
+ bool screenLockedWhenHibernate();
+ void setScreenLockedWhenHibernate(bool screenLockedWhenHibernate);
+
+ bool screenLockedWhenSuspend();
+ void setScreenLockedWhenSuspend(bool screenLockedWhenSuspend);
+
public Q_SLOTS: // METHODS
+ bool CanHibernate();
bool CanLogout();
bool CanReboot();
bool CanShutdown();
+ bool CanSuspend();
// 获取抑制器
QString GetInhibitor(uint cookie);
QString GetInhibitors();
+ void Hibernate();
// 添加抑制器
uint Inhibit(const QString &appID, uint toplevelXID, const QString &reason, uint flags);
// 判断指定flags的抑制器是否存在
@@ -76,12 +88,15 @@ public Q_SLOTS: // METHODS
// 添加会话程序的环境变量
void Setenv(const QString &name, const QString &value);
void Shutdown();
+ void Suspend();
// 删除抑制器
void Uninhibit(uint inhibitCookie);
Q_SIGNALS: // SIGNALS
void InhibitorAdded(uint cookie);
void InhibitorRemoved(uint cookie);
void PhaseChanged(int phase);
+ void ScreenLockedWhenHibernateChanged(bool screen_locked_when_hibernate);
+ void ScreenLockedWhenSuspendChanged(bool screen_locked_when_suspend);
public Q_SLOTS:
// 应用启动超时
--
2.36.1