on xenial help sign in
implement Lock/Unlock and the respective signals
ba9d278Lukáš Tinkl
plugins/Unity/Session/dbusunitysessionservice.cpp+96−27
@@ -32,27 +32,87 @@
32#define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
32#define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
33#define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
33#define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
34
34
35−bool checkLogin1Call(const QString &method)
35+class DBusUnitySessionServicePrivate: public QObject
36{
36{
37− QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
37+public:
38− QDBusReply<QString> reply = QDBusConnection::systemBus().asyncCall(msg);
38+ QString logindSessionPath;
39− const QString retval = reply.value();
40− return (retval == QStringLiteral("yes") || retval == QStringLiteral("challenge"));
41−}
42
39
40+ DBusUnitySessionServicePrivate(): QObject() { init(); }
41+
42+ void init()
43+ {
44+ // get our logind session path
45+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
46+ LOGIN1_PATH,
47+ LOGIN1_IFACE,
48+ "GetSessionByPID");
49+ msg << (quint32) getpid();
50+
51+ QDBusReply<QDBusObjectPath> reply = QDBusConnection::systemBus().asyncCall(msg);
52+ if (reply.isValid()) {
53+ logindSessionPath = reply.value().path();
54+ qDebug() << "session path" << logindSessionPath;
55+ } else {
56+ qWarning() << "Failed to get logind session path" << reply.error().message();
57+ }
58+ }
59+
60+ bool checkLogin1Call(const QString &method) const
61+ {
62+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
63+ QDBusReply<QString> reply = QDBusConnection::systemBus().asyncCall(msg);
64+ return reply.isValid() && (reply == QStringLiteral("yes") || reply == QStringLiteral("challenge"));
65+ }
66+
43−void makeLogin1Call(const QString &method, const QVariantList &args)
67+ void makeLogin1Call(const QString &method, const QVariantList &args)
44−{
68+ {
45− QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
69+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
46− LOGIN1_PATH,
70+ LOGIN1_PATH,
47− LOGIN1_IFACE,
71+ LOGIN1_IFACE,
48− method);
72+ method);
49− msg.setArguments(args);
73+ msg.setArguments(args);
74+ QDBusConnection::systemBus().asyncCall(msg);
75+ }
76+
77+ bool isActive() const
78+ {
79+ if (logindSessionPath.isEmpty()) {
80+ qWarning() << "Invalid session path";
81+ return true; //assume active
82+ }
83+
84+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
85+ logindSessionPath,
86+ "org.freedesktop.DBus.Properties",
87+ "Get");
88+ msg << LOGIN1_SESSION_IFACE;
89+ msg << QStringLiteral("Active");
90+
50− QDBusConnection::systemBus().asyncCall(msg);
91+ QDBusReply<bool> reply = QDBusConnection::systemBus().asyncCall(msg);
92+ if (reply.isValid()) {
93+ return reply;
94+ } else {
95+ qWarning() << "Failed to get Active property" << reply.error().message();
51−}
96+ }
97+
98+ return true; // assume active
99+ }
100+};
101+
102+Q_GLOBAL_STATIC(DBusUnitySessionServicePrivate, d)
52
103
53DBusUnitySessionService::DBusUnitySessionService()
104DBusUnitySessionService::DBusUnitySessionService()
54 : UnityDBusObject("/com/canonical/Unity/Session", "com.canonical.Unity")
105 : UnityDBusObject("/com/canonical/Unity/Session", "com.canonical.Unity")
55{
106{
107+ if (!d->logindSessionPath.isEmpty()) {
108+ // connect our Lock() slot to the logind's session Lock() signal
109+ QDBusConnection::systemBus().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, "Lock", this, SLOT(Lock()));
110+ // ... and our Unlocked() signal to the logind's session Unlock() signal
111+ // (lightdm handles the unlocking by calling logind's Unlock method which in turn emits this signal we connect to)
112+ QDBusConnection::systemBus().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, "Unlock", this, SIGNAL(Unlocked()));
113+ } else {
114+ qWarning() << "Failed to connect to logind's session Lock/Unlock signals";
115+ }
56}
116}
57
117
58void DBusUnitySessionService::Logout()
118void DBusUnitySessionService::Logout()
@@ -72,27 +132,27 @@ void DBusUnitySessionService::EndSession()
72
132
73bool DBusUnitySessionService::CanHibernate() const
133bool DBusUnitySessionService::CanHibernate() const
74{
134{
75− return checkLogin1Call("CanHibernate");
135+ return d->checkLogin1Call("CanHibernate");
76}
136}
77
137
78bool DBusUnitySessionService::CanSuspend() const
138bool DBusUnitySessionService::CanSuspend() const
79{
139{
80− return checkLogin1Call("CanSuspend");
140+ return d->checkLogin1Call("CanSuspend");
81}
141}
82
142
83bool DBusUnitySessionService::CanHybridSleep() const
143bool DBusUnitySessionService::CanHybridSleep() const
84{
144{
85− return checkLogin1Call("CanHybridSleep");
145+ return d->checkLogin1Call("CanHybridSleep");
86}
146}
87
147
88bool DBusUnitySessionService::CanReboot() const
148bool DBusUnitySessionService::CanReboot() const
89{
149{
90− return checkLogin1Call("CanReboot");
150+ return d->checkLogin1Call("CanReboot");
91}
151}
92
152
93bool DBusUnitySessionService::CanShutdown() const
153bool DBusUnitySessionService::CanShutdown() const
94{
154{
95− return checkLogin1Call("CanPowerOff");
155+ return d->checkLogin1Call("CanPowerOff");
96}
156}
97
157
98bool DBusUnitySessionService::CanLock() const
158bool DBusUnitySessionService::CanLock() const
@@ -141,18 +201,27 @@ void DBusUnitySessionService::PromptLock()
141
201
142void DBusUnitySessionService::Lock()
202void DBusUnitySessionService::Lock()
143{
203{
204+ // lock the session using the org.freedesktop.DisplayManager system DBUS service
144− const QString sessionId = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
205+ const QString sessionPath = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
145 QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DisplayManager",
206 QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DisplayManager",
146− sessionId,
207+ sessionPath,
147 "org.freedesktop.DisplayManager.Session",
208 "org.freedesktop.DisplayManager.Session",
148 "Lock");
209 "Lock");
149 qDebug() << "Locking session" << msg.path();
210 qDebug() << "Locking session" << msg.path();
150 QDBusReply<void> reply = QDBusConnection::systemBus().asyncCall(msg);
211 QDBusReply<void> reply = QDBusConnection::systemBus().asyncCall(msg);
151 if (!reply.isValid()) {
212 if (!reply.isValid()) {
152 qWarning() << "Lock call failed" << reply.error().message();
213 qWarning() << "Lock call failed" << reply.error().message();
214+ } else {
215+ // emit Locked when the call succeeds
216+ Q_EMIT Locked();
153 }
217 }
154}
218}
155
219
220+bool DBusUnitySessionService::IsLocked() const
221+{
222+ return !d->isActive();
223+}
224+
156void DBusUnitySessionService::RequestLogout()
225void DBusUnitySessionService::RequestLogout()
157{
226{
158 Q_EMIT LogoutRequested(false);
227 Q_EMIT LogoutRequested(false);
@@ -160,7 +229,7 @@ void DBusUnitySessionService::RequestLogout()
160
229
161void DBusUnitySessionService::Reboot()
230void DBusUnitySessionService::Reboot()
162{
231{
163− makeLogin1Call("Reboot", {false});
232+ d->makeLogin1Call("Reboot", {false});
164}
233}
165
234
166void DBusUnitySessionService::RequestReboot()
235void DBusUnitySessionService::RequestReboot()
@@ -170,22 +239,22 @@ void DBusUnitySessionService::RequestReboot()
170
239
171void DBusUnitySessionService::Shutdown()
240void DBusUnitySessionService::Shutdown()
172{
241{
173− makeLogin1Call("PowerOff", {false});
242+ d->makeLogin1Call("PowerOff", {false});
174}
243}
175
244
176void DBusUnitySessionService::Suspend()
245void DBusUnitySessionService::Suspend()
177{
246{
178− makeLogin1Call("Suspend", {false});
247+ d->makeLogin1Call("Suspend", {false});
179}
248}
180
249
181void DBusUnitySessionService::Hibernate()
250void DBusUnitySessionService::Hibernate()
182{
251{
183− makeLogin1Call("Hibernate", {false});
252+ d->makeLogin1Call("Hibernate", {false});
184}
253}
185
254
186void DBusUnitySessionService::HybridSleep()
255void DBusUnitySessionService::HybridSleep()
187{
256{
188− makeLogin1Call("HybridSleep", {false});
257+ d->makeLogin1Call("HybridSleep", {false});
189}
258}
190
259
191void DBusUnitySessionService::RequestShutdown()
260void DBusUnitySessionService::RequestShutdown()
plugins/Unity/Session/dbusunitysessionservice.h+19−1
@@ -29,7 +29,7 @@ Q_DECLARE_METATYPE(QList<QDBusObjectPath>)
29 * interface.
29 * interface.
30 *
30 *
31 * com.canonical.Unity.Session interface provides public methods
31 * com.canonical.Unity.Session interface provides public methods
32− * and signals to handle Logout/Reboot/Shutdown.
32+ * and signals to handle eg. Logout/Reboot/Shutdown.
33 */
33 */
34class DBusUnitySessionService : public UnityDBusObject
34class DBusUnitySessionService : public UnityDBusObject
35{
35{
@@ -85,8 +85,21 @@ Q_SIGNALS:
85 */
85 */
86 Q_SCRIPTABLE void LogoutReady();
86 Q_SCRIPTABLE void LogoutReady();
87
87
88+ /**
89+ * Emitted as a result of calling PromptLock()
90+ */
88 Q_SCRIPTABLE void LockRequested();
91 Q_SCRIPTABLE void LockRequested();
89
92
93+ /**
94+ * Emitted after the session has been locked.
95+ */
96+ Q_SCRIPTABLE void Locked();
97+
98+ /**
99+ * Emitted after the session has been unlocked.
100+ */
101+ Q_SCRIPTABLE void Unlocked();
102+
90public Q_SLOTS:
103public Q_SLOTS:
91 /**
104 /**
92 * Logout the system.
105 * Logout the system.
@@ -209,6 +222,9 @@ public Q_SLOTS:
209 */
222 */
210 Q_SCRIPTABLE bool CanLock() const;
223 Q_SCRIPTABLE bool CanLock() const;
211
224
225+ /**
226+ * @return the login name of the current user
227+ */
212 Q_SCRIPTABLE QString UserName() const;
228 Q_SCRIPTABLE QString UserName() const;
213
229
214 /**
230 /**
@@ -230,6 +246,8 @@ public Q_SLOTS:
230 * Locks the session immediately
246 * Locks the session immediately
231 */
247 */
232 Q_SCRIPTABLE void Lock();
248 Q_SCRIPTABLE void Lock();
249+
250+ Q_SCRIPTABLE bool IsLocked() const;
233};
251};
234
252
235class DBusGnomeSessionManagerWrapper : public UnityDBusObject
253class DBusGnomeSessionManagerWrapper : public UnityDBusObject
tests/plugins/Unity/Session/sessionbackendtest.cpp+6
@@ -158,9 +158,15 @@ private Q_SLOTS:
158
158
159// void testLock() {
159// void testLock() {
160// DBusUnitySessionService dbusUnitySessionService;
160// DBusUnitySessionService dbusUnitySessionService;
161+// QDBusInterface login1face("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
161// QCoreApplication::processEvents(); // to let the service register on DBus
162// QCoreApplication::processEvents(); // to let the service register on DBus
162// qDebug() << "Locking up...";
163// qDebug() << "Locking up...";
163// dbusUnitySessionService.Lock();
164// dbusUnitySessionService.Lock();
165+// qDebug() << "Unlocking...";
166+// QDBusReply<void> unlockReply = login1face.call("UnlockSessions");
167+// if (!unlockReply.isValid()) {
168+// qWarning() << "Failed to unlock sessions" << unlockReply.error().message();
169+// }
164// }
170// }
165
171
166private:
172private: