@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014, 2015 Canonical, Ltd.
33 *
44 * This program is free software: you can redistribute it and/or modify it under
55 * the terms of the GNU Lesser General Public License version 3, as published by
@@ -12,6 +12,10 @@
1212 *
1313 * You should have received a copy of the GNU Lesser General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Lukáš Tinkl <ltinkl@canonical.com>
17+ * Christopher Townsend <christopher.townsend@canonical.com>
18+ * Paul Liu <paul.liu@canonical.com>
1519 */
1620
1721// local
@@ -26,18 +30,27 @@
2630#include <QDebug>
2731#include <QDBusPendingCall>
2832#include <QDBusReply>
33+#include <QElapsedTimer>
2934
3035#define LOGIN1_SERVICE QStringLiteral("org.freedesktop.login1")
3136#define LOGIN1_PATH QStringLiteral("/org/freedesktop/login1")
3237#define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
3338#define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
3439
40+#define ACTIVE_KEY QStringLiteral("Active")
41+
3542class DBusUnitySessionServicePrivate: public QObject
3643{
44+ Q_OBJECT
3745public:
3846 QString logindSessionPath;
47+ bool isActive = true;
48+ QElapsedTimer screensaverActiveTimer;
3949
40− DBusUnitySessionServicePrivate(): QObject() { init(); }
50+ DBusUnitySessionServicePrivate(): QObject() {
51+ init();
52+ checkActive();
53+ }
4154
4255 void init()
4356 {
@@ -51,7 +64,11 @@ public:
5164 QDBusReply<QDBusObjectPath> reply = QDBusConnection::systemBus().asyncCall(msg);
5265 if (reply.isValid()) {
5366 logindSessionPath = reply.value().path();
54− qDebug() << "session path" << logindSessionPath;
67+ //qDebug() << "session path" << logindSessionPath;
68+
69+ // start watching the Active property
70+ QDBusConnection::systemBus().connect(LOGIN1_SERVICE, logindSessionPath, "org.freedesktop.DBus.Properties", "PropertiesChanged",
71+ this, SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
5572 } else {
5673 qWarning() << "Failed to get logind session path" << reply.error().message();
5774 }
@@ -74,11 +91,11 @@ public:
7491 QDBusConnection::systemBus().asyncCall(msg);
7592 }
7693
77− bool isActive() const
94+ void checkActive()
7895 {
7996 if (logindSessionPath.isEmpty()) {
8097 qWarning() << "Invalid session path";
81− return true; //assume active
98+ return;
8299 }
83100
84101 QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
@@ -86,17 +103,39 @@ public:
86103 "org.freedesktop.DBus.Properties",
87104 "Get");
88105 msg << LOGIN1_SESSION_IFACE;
89− msg << QStringLiteral("Active");
106+ msg << ACTIVE_KEY;
90107
91− QDBusReply<bool> reply = QDBusConnection::systemBus().asyncCall(msg);
108+ QDBusReply<QVariant> reply = QDBusConnection::systemBus().asyncCall(msg);
92109 if (reply.isValid()) {
93− return reply;
110+ isActive = reply.value().toBool();
111+ qDebug() << "Session" << logindSessionPath << "is active:" << isActive;
94112 } else {
95113 qWarning() << "Failed to get Active property" << reply.error().message();
96114 }
115+ }
97116
98− return true; // assume active
117+private Q_SLOTS:
118+ void onPropertiesChanged(const QString &iface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
119+ {
120+ Q_UNUSED(iface)
121+
122+ if (changedProps.contains(ACTIVE_KEY)) {
123+ isActive = changedProps.value(ACTIVE_KEY).toBool();
124+ } else if (invalidatedProps.contains(ACTIVE_KEY)) {
125+ checkActive();
126+ }
127+
128+ Q_EMIT screensaverActiveChanged(!isActive);
129+
130+ if (isActive) {
131+ screensaverActiveTimer.invalidate();
132+ } else {
133+ screensaverActiveTimer.start();
134+ }
99135 }
136+
137+Q_SIGNALS:
138+ void screensaverActiveChanged(bool active);
100139};
101140
102141Q_GLOBAL_STATIC(DBusUnitySessionServicePrivate, d)
@@ -219,7 +258,7 @@ void DBusUnitySessionService::Lock()
219258
220259bool DBusUnitySessionService::IsLocked() const
221260{
222− return !d->isActive();
261+ return !d->isActive;
223262}
224263
225264void DBusUnitySessionService::RequestLogout()
@@ -270,12 +309,8 @@ enum class Action : unsigned
270309 NONE
271310};
272311
273−DBusGnomeSessionManagerWrapper::DBusGnomeSessionManagerWrapper()
274− : UnityDBusObject("/org/gnome/SessionManager/EndSessionDialog", "com.canonical.Unity")
275−{
276−}
277312
278−void DBusGnomeSessionManagerWrapper::performAsyncCall(const QString &method)
313+void performAsyncUnityCall(const QString &method)
279314{
280315 const QDBusMessage msg = QDBusMessage::createMethodCall("com.canonical.Unity",
281316 "/com/canonical/Unity/Session",
@@ -284,29 +319,67 @@ void DBusGnomeSessionManagerWrapper::performAsyncCall(const QString &method)
284319 QDBusConnection::sessionBus().asyncCall(msg);
285320}
286321
322+DBusGnomeSessionManagerWrapper::DBusGnomeSessionManagerWrapper()
323+ : UnityDBusObject("/org/gnome/SessionManager/EndSessionDialog", "com.canonical.Unity")
324+{
325+}
326+
287327void DBusGnomeSessionManagerWrapper::Open(const unsigned type, const unsigned arg_1, const unsigned max_wait, const QList<QDBusObjectPath> &inhibitors)
288328{
289329 Q_UNUSED(arg_1);
290330 Q_UNUSED(max_wait);
291331 Q_UNUSED(inhibitors);
292332
293− const Action action = (Action)type;
294−
295− switch (action)
333+ switch (static_cast<Action>(type))
296334 {
297335 case Action::LOGOUT:
298− performAsyncCall("RequestLogout");
336+ performAsyncUnityCall("RequestLogout");
299337 break;
300338
301339 case Action::REBOOT:
302− performAsyncCall("RequestReboot");
340+ performAsyncUnityCall("RequestReboot");
303341 break;
304342
305343 case Action::SHUTDOWN:
306− performAsyncCall("RequestShutdown");
344+ performAsyncUnityCall("RequestShutdown");
307345 break;
308346
309347 default:
310348 break;
311349 }
312350}
351+
352+
353+DBusGnomeScreensaverWrapper::DBusGnomeScreensaverWrapper()
354+ : UnityDBusObject("/org/gnome/ScreenSaver", "org.gnome.ScreenSaver")
355+{
356+ connect(d, &DBusUnitySessionServicePrivate::screensaverActiveChanged, this, &DBusGnomeScreensaverWrapper::ActiveChanged);
357+}
358+
359+bool DBusGnomeScreensaverWrapper::GetActive() const
360+{
361+ return !d->isActive; // return whether the session is not active
362+}
363+
364+void DBusGnomeScreensaverWrapper::SetActive(bool lock)
365+{
366+ if (lock) {
367+ Lock();
368+ }
369+}
370+
371+void DBusGnomeScreensaverWrapper::Lock()
372+{
373+ performAsyncUnityCall("Lock");
374+}
375+
376+quint32 DBusGnomeScreensaverWrapper::GetActiveTime() const
377+{
378+ if (GetActive() && d->screensaverActiveTimer.isValid()) {
379+ return d->screensaverActiveTimer.elapsed() / 1000;
380+ }
381+
382+ return 0;
383+}
384+
385+#include "dbusunitysessionservice.moc"