on xenial help sign in
implement Lock/Unlock and the respective signals

move the impl to a private (shared) class

commitba9d2784726ec98e2d831ab36d74328c63795df6 authorLukáš Tinkl <lukas.tinkl@canonical.com> dateTue 16 Jun 2015, 21:29 (11 years ago) parent649291d
3 files changed+121−28
plugins/Unity/Session/dbusunitysessionservice.cpp+96−27 plugins/Unity/Session/dbusunitysessionservice.h+19−1 tests/plugins/Unity/Session/sessionbackendtest.cpp+6
plugins/Unity/Session/dbusunitysessionservice.cpp+96−27
@@ -32,27 +32,87 @@
3232#define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
3333#define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
3434
35−bool checkLogin1Call(const QString &method)
35+class DBusUnitySessionServicePrivate: public QObject
3636{
37− QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
38− QDBusReply<QString> reply = QDBusConnection::systemBus().asyncCall(msg);
39− const QString retval = reply.value();
40− return (retval == QStringLiteral("yes") || retval == QStringLiteral("challenge"));
41−}
37+public:
38+ QString logindSessionPath;
4239
43−void makeLogin1Call(const QString &method, const QVariantList &args)
44−{
45− QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
46− LOGIN1_PATH,
47− LOGIN1_IFACE,
48− method);
49− msg.setArguments(args);
50− QDBusConnection::systemBus().asyncCall(msg);
51−}
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+
67+ void makeLogin1Call(const QString &method, const QVariantList &args)
68+ {
69+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
70+ LOGIN1_PATH,
71+ LOGIN1_IFACE,
72+ method);
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+
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();
96+ }
97+
98+ return true; // assume active
99+ }
100+};
101+
102+Q_GLOBAL_STATIC(DBusUnitySessionServicePrivate, d)
52103
53104DBusUnitySessionService::DBusUnitySessionService()
54105 : UnityDBusObject("/com/canonical/Unity/Session", "com.canonical.Unity")
55106{
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+ }
56116}
57117
58118void DBusUnitySessionService::Logout()
@@ -72,27 +132,27 @@ void DBusUnitySessionService::EndSession()
72132
73133bool DBusUnitySessionService::CanHibernate() const
74134{
75− return checkLogin1Call("CanHibernate");
135+ return d->checkLogin1Call("CanHibernate");
76136}
77137
78138bool DBusUnitySessionService::CanSuspend() const
79139{
80− return checkLogin1Call("CanSuspend");
140+ return d->checkLogin1Call("CanSuspend");
81141}
82142
83143bool DBusUnitySessionService::CanHybridSleep() const
84144{
85− return checkLogin1Call("CanHybridSleep");
145+ return d->checkLogin1Call("CanHybridSleep");
86146}
87147
88148bool DBusUnitySessionService::CanReboot() const
89149{
90− return checkLogin1Call("CanReboot");
150+ return d->checkLogin1Call("CanReboot");
91151}
92152
93153bool DBusUnitySessionService::CanShutdown() const
94154{
95− return checkLogin1Call("CanPowerOff");
155+ return d->checkLogin1Call("CanPowerOff");
96156}
97157
98158bool DBusUnitySessionService::CanLock() const
@@ -141,18 +201,27 @@ void DBusUnitySessionService::PromptLock()
141201
142202void DBusUnitySessionService::Lock()
143203{
144− const QString sessionId = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
204+ // lock the session using the org.freedesktop.DisplayManager system DBUS service
205+ const QString sessionPath = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
145206 QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DisplayManager",
146− sessionId,
207+ sessionPath,
147208 "org.freedesktop.DisplayManager.Session",
148209 "Lock");
149210 qDebug() << "Locking session" << msg.path();
150211 QDBusReply<void> reply = QDBusConnection::systemBus().asyncCall(msg);
151212 if (!reply.isValid()) {
152213 qWarning() << "Lock call failed" << reply.error().message();
214+ } else {
215+ // emit Locked when the call succeeds
216+ Q_EMIT Locked();
153217 }
154218}
155219
220+bool DBusUnitySessionService::IsLocked() const
221+{
222+ return !d->isActive();
223+}
224+
156225void DBusUnitySessionService::RequestLogout()
157226{
158227 Q_EMIT LogoutRequested(false);
@@ -160,7 +229,7 @@ void DBusUnitySessionService::RequestLogout()
160229
161230void DBusUnitySessionService::Reboot()
162231{
163− makeLogin1Call("Reboot", {false});
232+ d->makeLogin1Call("Reboot", {false});
164233}
165234
166235void DBusUnitySessionService::RequestReboot()
@@ -170,22 +239,22 @@ void DBusUnitySessionService::RequestReboot()
170239
171240void DBusUnitySessionService::Shutdown()
172241{
173− makeLogin1Call("PowerOff", {false});
242+ d->makeLogin1Call("PowerOff", {false});
174243}
175244
176245void DBusUnitySessionService::Suspend()
177246{
178− makeLogin1Call("Suspend", {false});
247+ d->makeLogin1Call("Suspend", {false});
179248}
180249
181250void DBusUnitySessionService::Hibernate()
182251{
183− makeLogin1Call("Hibernate", {false});
252+ d->makeLogin1Call("Hibernate", {false});
184253}
185254
186255void DBusUnitySessionService::HybridSleep()
187256{
188− makeLogin1Call("HybridSleep", {false});
257+ d->makeLogin1Call("HybridSleep", {false});
189258}
190259
191260void DBusUnitySessionService::RequestShutdown()
plugins/Unity/Session/dbusunitysessionservice.h+19−1
@@ -29,7 +29,7 @@ Q_DECLARE_METATYPE(QList<QDBusObjectPath>)
2929 * interface.
3030 *
3131 * 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.
3333 */
3434class DBusUnitySessionService : public UnityDBusObject
3535{
@@ -85,8 +85,21 @@ Q_SIGNALS:
8585 */
8686 Q_SCRIPTABLE void LogoutReady();
8787
88+ /**
89+ * Emitted as a result of calling PromptLock()
90+ */
8891 Q_SCRIPTABLE void LockRequested();
8992
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+
90103public Q_SLOTS:
91104 /**
92105 * Logout the system.
@@ -209,6 +222,9 @@ public Q_SLOTS:
209222 */
210223 Q_SCRIPTABLE bool CanLock() const;
211224
225+ /**
226+ * @return the login name of the current user
227+ */
212228 Q_SCRIPTABLE QString UserName() const;
213229
214230 /**
@@ -230,6 +246,8 @@ public Q_SLOTS:
230246 * Locks the session immediately
231247 */
232248 Q_SCRIPTABLE void Lock();
249+
250+ Q_SCRIPTABLE bool IsLocked() const;
233251};
234252
235253class DBusGnomeSessionManagerWrapper : public UnityDBusObject
tests/plugins/Unity/Session/sessionbackendtest.cpp+6
@@ -158,9 +158,15 @@ private Q_SLOTS:
158158
159159// void testLock() {
160160// DBusUnitySessionService dbusUnitySessionService;
161+// QDBusInterface login1face("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
161162// QCoreApplication::processEvents(); // to let the service register on DBus
162163// qDebug() << "Locking up...";
163164// 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+// }
164170// }
165171
166172private: