Merge lp:~lukas-kde/unity8/unity8DbusSessionService into lp:unity8

Proposed by Lukáš Tinkl on 2015-06-19
Status: Superseded
Proposed branch: lp:~lukas-kde/unity8/unity8DbusSessionService
Merge into: lp:unity8
Prerequisite: lp:~lukas-kde/unity8/highdpi-mousetouchadaptor
Diff against target: 1948 lines (+856/-302)
22 files modified
plugins/AccountsService/AccountsService.cpp (+32/-44)
plugins/AccountsService/AccountsService.h (+4/-3)
plugins/AccountsService/AccountsServiceDBusAdaptor.cpp (+13/-11)
plugins/AccountsService/AccountsServiceDBusAdaptor.h (+3/-2)
plugins/Lights/Lights.cpp (+1/-1)
plugins/Powerd/Powerd.cpp (+41/-36)
plugins/Powerd/Powerd.h (+4/-3)
plugins/Ubuntu/SystemImage/SystemImage.cpp (+7/-8)
plugins/Ubuntu/SystemImage/SystemImage.h (+1/-5)
plugins/Unity/Connectivity/Connectivity.cpp (+5/-5)
plugins/Unity/Connectivity/Connectivity.h (+1/-0)
plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h (+1/-1)
plugins/Unity/DashCommunicator/plugin.cpp (+1/-0)
plugins/Unity/Launcher/dbusinterface.cpp (+0/-4)
plugins/Unity/Launcher/dbusinterface.h (+1/-1)
plugins/Unity/Session/CMakeLists.txt (+1/-0)
plugins/Unity/Session/dbusunitysessionservice.cpp (+402/-62)
plugins/Unity/Session/dbusunitysessionservice.h (+199/-22)
plugins/Utils/relativetimeformatter.cpp (+1/-1)
plugins/Wizard/System.cpp (+13/-9)
tests/plugins/AccountsService/client.cpp (+10/-20)
tests/plugins/Unity/Session/sessionbackendtest.cpp (+115/-64)
To merge this branch: bzr merge lp:~lukas-kde/unity8/unity8DbusSessionService
Reviewer Review Type Date Requested Status
Albert Astals Cid (community) 2015-06-19 Abstain on 2015-06-22
PS Jenkins bot continuous-integration Needs Fixing on 2015-06-19
Review via email: mp+262439@code.launchpad.net

This proposal has been superseded by a proposal from 2015-06-22.

Commit Message

Provide DBUS compatibility with various session services (suspend/hibernate, lock/unlock, screensaver, etc)

Description of the Change

com.canonical.Unity currently lacks a lot of interfaces and methods in comparison with Unity 7 and other desktop environments.

Provide DBUS compatibility with various session services (suspend/hibernate, lock/unlock, screensaver, etc)

To post a comment you must log in.
Albert Astals Cid (aacid) wrote :

You have bad tags

review: Needs Fixing
Lukáš Tinkl (lukas-kde) wrote :

According to the script, it looks clean:

ltinkl@ltinkl-Inspiron-7548:~/bzr/unity8/asyncDbusCalls$ ~/bin/strip-u8-tags.py ~/bzr/unity8/asyncDbusCalls/
/home/ltinkl/bzr/unity8/asyncDbusCalls/: clean

Lukáš Tinkl (lukas-kde) wrote :

Should be ok now

Albert Astals Cid (aacid) wrote :

Tags are good now.

review: Abstain
1815. By Lukáš Tinkl on 2015-06-29

[ Albert Astals Cid ]
* Refactor QmlTest.cmake module so that all tests can go through it.
  Also a bit of cleanup around tests.
* Support fallback images for dash card and preview widgets (LP:
  #1324142)
[ CI Train Bot ]
* New rebuild forced.
* Resync trunk.
[ Daniel d'Andrada ]
* Fix Shell tests
[ Josh Arenson ]
* Refactor greeter emulator to unlock the greeter via dbus
[ Lukáš Tinkl ]
* respect target window's devicePixelRatio in MouseTouchAdaptor
[ Michael Zanetti ]
* Refactor QmlTest.cmake module so that all tests can go through it.
  Also a bit of cleanup around tests.
[ Michał Sawicz ]
* Refactor QmlTest.cmake module so that all tests can go through it.
  Also a bit of cleanup around tests.
[ handsome_feng ]
* Forbid closing apps during the edge gesture. (LP: #1445572)
* Removed the horizonal rule on pin unlock screen. (LP: #1368798)
[ handsome_feng<email address hidden> ]
* Forbid closing apps during the edge gesture. (LP: #1445572)

1816. By Lukáš Tinkl on 2015-06-29

address minor issues in MP 262575

1817. By Lukáš Tinkl on 2015-06-29

fix failing username and real name tests

1818. By Lukáš Tinkl on 2015-06-30

fix CI

1819. By Lukáš Tinkl on 2015-06-30

remove commented out debug

1820. By Lukáš Tinkl on 2015-07-01

register the screensaver wrappers too

1821. By Lukáš Tinkl on 2015-07-21

merge and resolve conflict

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/AccountsService/AccountsService.cpp'
2--- plugins/AccountsService/AccountsService.cpp 2015-04-17 16:39:32 +0000
3+++ plugins/AccountsService/AccountsService.cpp 2015-06-19 11:26:12 +0000
4@@ -23,10 +23,9 @@
5 #include <QStringList>
6 #include <QDebug>
7
8-AccountsService::AccountsService(QObject* parent)
9- : QObject(parent),
10+AccountsService::AccountsService(QObject* parent, const QString &user)
11+ : QObject(parent),
12 m_service(new AccountsServiceDBusAdaptor(this)),
13- m_user(""),
14 m_demoEdges(false),
15 m_enableLauncherWhileLocked(false),
16 m_enableIndicatorsWhileLocked(false),
17@@ -36,12 +35,10 @@
18 m_hereEnabled(false),
19 m_hereLicensePath() // null means not set yet
20 {
21- connect(m_service, SIGNAL(propertiesChanged(const QString &, const QString &, const QStringList &)),
22- this, SLOT(propertiesChanged(const QString &, const QString &, const QStringList &)));
23- connect(m_service, SIGNAL(maybeChanged(const QString &)),
24- this, SLOT(maybeChanged(const QString &)));
25+ connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
26+ connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
27
28- setUser(qgetenv("USER"));
29+ setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
30 }
31
32 QString AccountsService::user() const
33@@ -144,9 +141,9 @@
34 this, [this](QDBusPendingCallWatcher* watcher) {
35
36 QDBusPendingReply<QDBusVariant> reply = *watcher;
37+ watcher->deleteLater();
38 if (reply.isError()) {
39 qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
40- watcher->deleteLater();
41 return;
42 }
43
44@@ -155,7 +152,6 @@
45 m_demoEdges = demoEdges;
46 Q_EMIT demoEdgesChanged();
47 }
48- watcher->deleteLater();
49 });
50 if (!async) {
51 watcher->waitForFinished();
52@@ -173,19 +169,18 @@
53 connect(watcher, &QDBusPendingCallWatcher::finished,
54 this, [this](QDBusPendingCallWatcher* watcher) {
55
56- QDBusPendingReply<QDBusVariant> reply = *watcher;
57+ QDBusPendingReply<QVariant> reply = *watcher;
58+ watcher->deleteLater();
59 if (reply.isError()) {
60 qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
61- watcher->deleteLater();
62 return;
63 }
64
65- auto enableLauncherWhileLocked = reply.value().variant().toBool();
66+ const bool enableLauncherWhileLocked = reply.value().toBool();
67 if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
68 m_enableLauncherWhileLocked = enableLauncherWhileLocked;
69 Q_EMIT enableLauncherWhileLockedChanged();
70 }
71- watcher->deleteLater();
72 });
73 if (!async) {
74 watcher->waitForFinished();
75@@ -203,19 +198,18 @@
76 connect(watcher, &QDBusPendingCallWatcher::finished,
77 this, [this](QDBusPendingCallWatcher* watcher) {
78
79- QDBusPendingReply<QDBusVariant> reply = *watcher;
80+ QDBusPendingReply<QVariant> reply = *watcher;
81+ watcher->deleteLater();
82 if (reply.isError()) {
83 qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
84- watcher->deleteLater();
85 return;
86 }
87
88- auto enableIndicatorsWhileLocked = reply.value().variant().toBool();
89+ const bool enableIndicatorsWhileLocked = reply.value().toBool();
90 if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
91 m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
92 Q_EMIT enableIndicatorsWhileLockedChanged();
93 }
94- watcher->deleteLater();
95 });
96 if (!async) {
97 watcher->waitForFinished();
98@@ -233,19 +227,18 @@
99 connect(watcher, &QDBusPendingCallWatcher::finished,
100 this, [this](QDBusPendingCallWatcher* watcher) {
101
102- QDBusPendingReply<QDBusVariant> reply = *watcher;
103+ QDBusPendingReply<QVariant> reply = *watcher;
104+ watcher->deleteLater();
105 if (reply.isError()) {
106 qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
107- watcher->deleteLater();
108 return;
109 }
110
111- auto backgroundFile = reply.value().variant().toString();
112+ const QString backgroundFile = reply.value().toString();
113 if (m_backgroundFile != backgroundFile) {
114 m_backgroundFile = backgroundFile;
115 Q_EMIT backgroundFileChanged();
116 }
117- watcher->deleteLater();
118 });
119 if (!async) {
120 watcher->waitForFinished();
121@@ -263,19 +256,18 @@
122 connect(watcher, &QDBusPendingCallWatcher::finished,
123 this, [this](QDBusPendingCallWatcher* watcher) {
124
125- QDBusPendingReply<QDBusVariant> reply = *watcher;
126+ QDBusPendingReply<QVariant> reply = *watcher;
127+ watcher->deleteLater();
128 if (reply.isError()) {
129 qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
130- watcher->deleteLater();
131 return;
132 }
133
134- auto statsWelcomeScreen = reply.value().variant().toBool();
135+ const bool statsWelcomeScreen = reply.value().toBool();
136 if (m_statsWelcomeScreen != statsWelcomeScreen) {
137 m_statsWelcomeScreen = statsWelcomeScreen;
138 Q_EMIT statsWelcomeScreenChanged();
139 }
140- watcher->deleteLater();
141 });
142 if (!async) {
143 watcher->waitForFinished();
144@@ -293,19 +285,18 @@
145 connect(watcher, &QDBusPendingCallWatcher::finished,
146 this, [this](QDBusPendingCallWatcher* watcher) {
147
148- QDBusPendingReply<QDBusVariant> reply = *watcher;
149+ QDBusPendingReply<QVariant> reply = *watcher;
150+ watcher->deleteLater();
151 if (reply.isError()) {
152 qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
153- watcher->deleteLater();
154 return;
155 }
156
157- PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().variant().toInt();
158+ const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt();
159 if (m_passwordDisplayHint != passwordDisplayHint) {
160 m_passwordDisplayHint = passwordDisplayHint;
161 Q_EMIT passwordDisplayHintChanged();
162 }
163- watcher->deleteLater();
164 });
165 if (!async) {
166 watcher->waitForFinished();
167@@ -323,19 +314,18 @@
168 connect(watcher, &QDBusPendingCallWatcher::finished,
169 this, [this](QDBusPendingCallWatcher* watcher) {
170
171- QDBusPendingReply<QDBusVariant> reply = *watcher;
172+ QDBusPendingReply<QVariant> reply = *watcher;
173+ watcher->deleteLater();
174 if (reply.isError()) {
175 qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
176- watcher->deleteLater();
177 return;
178 }
179
180- uint failedLogins = reply.value().variant().toUInt();
181+ const uint failedLogins = reply.value().toUInt();
182 if (m_failedLogins != failedLogins) {
183 m_failedLogins = failedLogins;
184 Q_EMIT failedLoginsChanged();
185 }
186- watcher->deleteLater();
187 });
188 if (!async) {
189 watcher->waitForFinished();
190@@ -353,19 +343,18 @@
191 connect(watcher, &QDBusPendingCallWatcher::finished,
192 this, [this](QDBusPendingCallWatcher* watcher) {
193
194- QDBusPendingReply<QDBusVariant> reply = *watcher;
195+ QDBusPendingReply<QVariant> reply = *watcher;
196+ watcher->deleteLater();
197 if (reply.isError()) {
198 qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
199- watcher->deleteLater();
200 return;
201 }
202
203- auto hereEnabled = reply.value().variant().toBool();
204+ const bool hereEnabled = reply.value().toBool();
205 if (m_hereEnabled != hereEnabled) {
206 m_hereEnabled = hereEnabled;
207 Q_EMIT hereEnabledChanged();
208 }
209- watcher->deleteLater();
210 });
211 if (!async) {
212 watcher->waitForFinished();
213@@ -383,14 +372,14 @@
214 connect(watcher, &QDBusPendingCallWatcher::finished,
215 this, [this](QDBusPendingCallWatcher* watcher) {
216
217- QDBusPendingReply<QDBusVariant> reply = *watcher;
218+ QDBusPendingReply<QVariant> reply = *watcher;
219+ watcher->deleteLater();
220 if (reply.isError()) {
221 qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
222- watcher->deleteLater();
223 return;
224 }
225
226- auto hereLicensePath = reply.value().variant().toString();
227+ QString hereLicensePath = reply.value().toString();
228 if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
229 hereLicensePath = "";
230
231@@ -398,7 +387,6 @@
232 m_hereLicensePath = hereLicensePath;
233 Q_EMIT hereLicensePathChanged();
234 }
235- watcher->deleteLater();
236 });
237 if (!async) {
238 watcher->waitForFinished();
239@@ -421,7 +409,7 @@
240 }
241 }
242
243-void AccountsService::propertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
244+void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
245 {
246 if (m_user != user) {
247 return;
248@@ -459,7 +447,7 @@
249 }
250 }
251
252-void AccountsService::maybeChanged(const QString &user)
253+void AccountsService::onMaybeChanged(const QString &user)
254 {
255 if (m_user != user) {
256 return;
257
258=== modified file 'plugins/AccountsService/AccountsService.h'
259--- plugins/AccountsService/AccountsService.h 2015-04-09 16:20:15 +0000
260+++ plugins/AccountsService/AccountsService.h 2015-06-19 11:26:12 +0000
261@@ -72,7 +72,8 @@
262 Numeric,
263 };
264
265- explicit AccountsService(QObject *parent = 0);
266+ explicit AccountsService(QObject *parent = 0, const QString & user = QString());
267+ ~AccountsService() = default;
268
269 QString user() const;
270 void setUser(const QString &user);
271@@ -103,8 +104,8 @@
272 void hereLicensePathChanged();
273
274 private Q_SLOTS:
275- void propertiesChanged(const QString &user, const QString &interface, const QStringList &changed);
276- void maybeChanged(const QString &user);
277+ void onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed);
278+ void onMaybeChanged(const QString &user);
279
280 private:
281 void updateDemoEdges(bool async = true);
282
283=== modified file 'plugins/AccountsService/AccountsServiceDBusAdaptor.cpp'
284--- plugins/AccountsService/AccountsServiceDBusAdaptor.cpp 2015-04-10 10:22:18 +0000
285+++ plugins/AccountsService/AccountsServiceDBusAdaptor.cpp 2015-06-19 11:26:12 +0000
286@@ -21,35 +21,35 @@
287 #include <QDBusConnectionInterface>
288 #include <QDBusMessage>
289 #include <QDBusVariant>
290+#include <QDebug>
291
292 AccountsServiceDBusAdaptor::AccountsServiceDBusAdaptor(QObject* parent)
293 : QObject(parent),
294 m_accountsManager(nullptr),
295- m_users(),
296 m_ignoreNextChanged(false)
297 {
298 QDBusConnection connection = QDBusConnection::SM_BUSNAME();
299 QDBusConnectionInterface *interface = connection.interface();
300 interface->startService("org.freedesktop.Accounts");
301 m_accountsManager = new QDBusInterface("org.freedesktop.Accounts",
302- "/org/freedesktop/Accounts",
303- "org.freedesktop.Accounts",
304- connection, this);
305+ "/org/freedesktop/Accounts",
306+ "org.freedesktop.Accounts",
307+ connection, this);
308 }
309
310 QVariant AccountsServiceDBusAdaptor::getUserProperty(const QString &user, const QString &interface, const QString &property)
311 {
312 QDBusInterface *iface = getUserInterface(user);
313 if (iface != nullptr && iface->isValid()) {
314- QDBusMessage answer = iface->call("Get", interface, property);
315- if (answer.type() == QDBusMessage::ReplyMessage) {
316- return answer.arguments()[0].value<QDBusVariant>().variant();
317+ QDBusReply<QVariant> answer = iface->call("Get", interface, property);
318+ if (answer.isValid()) {
319+ return answer;
320 }
321 }
322 return QVariant();
323 }
324
325-QDBusPendingReply<QDBusVariant> AccountsServiceDBusAdaptor::getUserPropertyAsync(const QString &user, const QString &interface, const QString &property)
326+QDBusPendingReply<QVariant> AccountsServiceDBusAdaptor::getUserPropertyAsync(const QString &user, const QString &interface, const QString &property)
327 {
328 QDBusInterface *iface = getUserInterface(user);
329 if (iface != nullptr && iface->isValid()) {
330@@ -116,9 +116,9 @@
331 {
332 QDBusInterface *iface = m_users.value(user);
333 if (iface == nullptr && m_accountsManager->isValid()) {
334- QDBusMessage answer = m_accountsManager->call("FindUserByName", user);
335- if (answer.type() == QDBusMessage::ReplyMessage) {
336- QString path = answer.arguments()[0].value<QDBusObjectPath>().path();
337+ QDBusReply<QDBusObjectPath> answer = m_accountsManager->asyncCall("FindUserByName", user);
338+ if (answer.isValid()) {
339+ const QString path = answer.value().path();
340
341 iface = new QDBusInterface("org.freedesktop.Accounts",
342 path,
343@@ -148,6 +148,8 @@
344 SLOT(propertiesChangedSlot(QString, QVariantMap, QStringList)));
345
346 m_users.insert(user, iface);
347+ } else {
348+ qWarning() << "Couldn't get user interface" << answer.error().name() << answer.error().message();
349 }
350 }
351 return iface;
352
353=== modified file 'plugins/AccountsService/AccountsServiceDBusAdaptor.h'
354--- plugins/AccountsService/AccountsServiceDBusAdaptor.h 2015-04-10 10:22:18 +0000
355+++ plugins/AccountsService/AccountsServiceDBusAdaptor.h 2015-06-19 11:26:12 +0000
356@@ -33,13 +33,14 @@
357
358 public:
359 explicit AccountsServiceDBusAdaptor(QObject *parent = 0);
360+ ~AccountsServiceDBusAdaptor() = default;
361
362 Q_INVOKABLE QVariant getUserProperty(const QString &user, const QString &interface, const QString &property);
363- Q_INVOKABLE QDBusPendingReply<QDBusVariant> getUserPropertyAsync(const QString &user, const QString &interface, const QString &property);
364+ Q_INVOKABLE QDBusPendingReply<QVariant> getUserPropertyAsync(const QString &user, const QString &interface, const QString &property);
365
366 template <typename T>
367 inline T getUserProperty(const QString &user, const QString &interface, const QString &property) {
368- QVariant variant = getUserProperty(user, interface, property);
369+ const QVariant variant = getUserProperty(user, interface, property);
370 if (variant.isValid() && variant.canConvert<QDBusArgument>()) {
371 return qdbus_cast<T>(variant.value<QDBusArgument>());
372 }
373
374=== modified file 'plugins/Lights/Lights.cpp'
375--- plugins/Lights/Lights.cpp 2014-12-12 14:16:10 +0000
376+++ plugins/Lights/Lights.cpp 2015-06-19 11:26:12 +0000
377@@ -71,7 +71,7 @@
378 if (m_color != color) {
379 m_color = color;
380 Q_EMIT colorChanged(m_color);
381- // FIXME: update the collor if the light is already on
382+ // FIXME: update the color if the light is already on
383 }
384 }
385
386
387=== modified file 'plugins/Powerd/Powerd.cpp'
388--- plugins/Powerd/Powerd.cpp 2014-08-28 12:31:50 +0000
389+++ plugins/Powerd/Powerd.cpp 2015-06-19 11:26:12 +0000
390@@ -18,54 +18,49 @@
391
392 #include "Powerd.h"
393 #include <QDBusPendingCall>
394-
395-void autoBrightnessChanged(GSettings *settings, const gchar *key, QDBusInterface *unityScreen)
396-{
397- bool value = g_settings_get_boolean(settings, key);
398- unityScreen->asyncCall("userAutobrightnessEnable", QVariant(value));
399-}
400-
401-void activityTimeoutChanged(GSettings *settings, const gchar *key, QDBusInterface *unityScreen)
402-{
403- int value = g_settings_get_uint(settings, key);
404- unityScreen->asyncCall("setInactivityTimeouts", QVariant(value), QVariant(-1));
405-}
406-
407-void dimTimeoutChanged(GSettings *settings, const gchar *key, QDBusInterface *unityScreen)
408-{
409- int value = g_settings_get_uint(settings, key);
410- unityScreen->asyncCall("setInactivityTimeouts", QVariant(-1), QVariant(value));
411+#include <QDBusConnection>
412+
413+void autoBrightnessChanged(GSettings *settings, const gchar *key, Powerd * instance)
414+{
415+ const bool value = g_settings_get_boolean(settings, key);
416+ instance->performAsyncCall("userAutobrightnessEnable", {value});
417+}
418+
419+void activityTimeoutChanged(GSettings *settings, const gchar *key, Powerd * instance)
420+{
421+ const int value = g_settings_get_int(settings, key);
422+ instance->performAsyncCall("setInactivityTimeouts", {value, -1});
423+}
424+
425+void dimTimeoutChanged(GSettings *settings, const gchar *key, Powerd * instance)
426+{
427+ const int value = g_settings_get_int(settings, key);
428+ instance->performAsyncCall("setInactivityTimeouts", {-1, value});
429 }
430
431 Powerd::Powerd(QObject* parent)
432 : QObject(parent),
433- unityScreen(nullptr),
434 cachedStatus(Status::On)
435 {
436- unityScreen = new QDBusInterface("com.canonical.Unity.Screen",
437- "/com/canonical/Unity/Screen",
438- "com.canonical.Unity.Screen",
439- QDBusConnection::SM_BUSNAME(), this);
440-
441- unityScreen->connection().connect("com.canonical.Unity.Screen",
442- "/com/canonical/Unity/Screen",
443- "com.canonical.Unity.Screen",
444- "DisplayPowerStateChange",
445- this,
446- SLOT(handleDisplayPowerStateChange(int, int)));
447+ QDBusConnection::SM_BUSNAME().connect("com.canonical.Unity.Screen",
448+ "/com/canonical/Unity/Screen",
449+ "com.canonical.Unity.Screen",
450+ "DisplayPowerStateChange",
451+ this,
452+ SLOT(handleDisplayPowerStateChange(int, int)));
453
454 systemSettings = g_settings_new("com.ubuntu.touch.system");
455- g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), unityScreen);
456- g_signal_connect(systemSettings, "changed::activity-timeout", G_CALLBACK(activityTimeoutChanged), unityScreen);
457- g_signal_connect(systemSettings, "changed::dim-timeout", G_CALLBACK(dimTimeoutChanged), unityScreen);
458- autoBrightnessChanged(systemSettings, "auto-brightness", unityScreen);
459- activityTimeoutChanged(systemSettings, "activity-timeout", unityScreen);
460- dimTimeoutChanged(systemSettings, "dim-timeout", unityScreen);
461+ g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), this);
462+ g_signal_connect(systemSettings, "changed::activity-timeout", G_CALLBACK(activityTimeoutChanged), this);
463+ g_signal_connect(systemSettings, "changed::dim-timeout", G_CALLBACK(dimTimeoutChanged), this);
464+ autoBrightnessChanged(systemSettings, "auto-brightness", this);
465+ activityTimeoutChanged(systemSettings, "activity-timeout", this);
466+ dimTimeoutChanged(systemSettings, "dim-timeout", this);
467 }
468
469 Powerd::~Powerd()
470 {
471- g_signal_handlers_disconnect_by_data(systemSettings, unityScreen);
472+ g_signal_handlers_disconnect_by_data(systemSettings, this);
473 g_object_unref(systemSettings);
474 }
475
476@@ -81,3 +76,13 @@
477 Q_EMIT statusChanged((DisplayStateChangeReason)reason);
478 }
479 }
480+
481+void Powerd::performAsyncCall(const QString &method, const QVariantList &args)
482+{
483+ QDBusMessage msg = QDBusMessage::createMethodCall("com.canonical.Unity.Screen",
484+ "/com/canonical/Unity/Screen",
485+ "com.canonical.Unity.Screen",
486+ method);
487+ msg.setArguments(args);
488+ QDBusConnection::SM_BUSNAME().asyncCall(msg);
489+}
490
491=== modified file 'plugins/Powerd/Powerd.h'
492--- plugins/Powerd/Powerd.h 2014-07-23 21:18:57 +0000
493+++ plugins/Powerd/Powerd.h 2015-06-19 11:26:12 +0000
494@@ -21,8 +21,7 @@
495 #define UNITY_POWERD_H
496
497 #include <gio/gio.h>
498-#include <QtCore/QObject>
499-#include <QtDBus/QDBusInterface>
500+#include <QObject>
501
502 class Powerd: public QObject
503 {
504@@ -30,6 +29,7 @@
505 Q_ENUMS(Status)
506 Q_ENUMS(DisplayStateChangeReason)
507 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
508+ Q_DISABLE_COPY(Powerd)
509
510 public:
511 enum DisplayStateChangeReason {
512@@ -49,6 +49,8 @@
513
514 Status status() const;
515
516+ void performAsyncCall(const QString &method, const QVariantList &args);
517+
518 Q_SIGNALS:
519 void statusChanged(DisplayStateChangeReason reason);
520
521@@ -56,7 +58,6 @@
522 void handleDisplayPowerStateChange(int status, int reason);
523
524 private:
525- QDBusInterface *unityScreen;
526 GSettings *systemSettings;
527 Status cachedStatus;
528 };
529
530=== modified file 'plugins/Ubuntu/SystemImage/SystemImage.cpp'
531--- plugins/Ubuntu/SystemImage/SystemImage.cpp 2014-07-30 11:08:29 +0000
532+++ plugins/Ubuntu/SystemImage/SystemImage.cpp 2015-06-19 11:26:12 +0000
533@@ -16,19 +16,18 @@
534
535 #include "SystemImage.h"
536 #include <QDBusConnection>
537-#include <QDBusInterface>
538+#include <QDBusPendingCall>
539
540 SystemImage::SystemImage(QObject *parent)
541- : QObject(parent),
542- m_interface(new QDBusInterface("com.canonical.SystemImage",
543- "/Service",
544- "com.canonical.SystemImage",
545- QDBusConnection::systemBus(),
546- this))
547+ : QObject(parent)
548 {
549 }
550
551 void SystemImage::factoryReset()
552 {
553- m_interface->call("FactoryReset");
554+ const QDBusMessage msg = QDBusMessage::createMethodCall("com.canonical.SystemImage",
555+ "/Service",
556+ "com.canonical.SystemImage",
557+ "FactoryReset");
558+ QDBusConnection::systemBus().asyncCall(msg);
559 }
560
561=== modified file 'plugins/Ubuntu/SystemImage/SystemImage.h'
562--- plugins/Ubuntu/SystemImage/SystemImage.h 2014-07-30 11:08:29 +0000
563+++ plugins/Ubuntu/SystemImage/SystemImage.h 2015-06-19 11:26:12 +0000
564@@ -19,8 +19,6 @@
565
566 #include <QObject>
567
568-class QDBusInterface;
569-
570 class SystemImage : public QObject
571 {
572 Q_OBJECT
573@@ -28,11 +26,9 @@
574
575 public:
576 explicit SystemImage(QObject *parent = 0);
577+ ~SystemImage() = default;
578
579 Q_INVOKABLE void factoryReset();
580-
581-private:
582- QDBusInterface *m_interface;
583 };
584
585 #endif // SYSTEMIMAGE_H
586
587=== modified file 'plugins/Unity/Connectivity/Connectivity.cpp'
588--- plugins/Unity/Connectivity/Connectivity.cpp 2014-08-20 17:14:55 +0000
589+++ plugins/Unity/Connectivity/Connectivity.cpp 2015-06-19 11:26:12 +0000
590@@ -16,7 +16,6 @@
591
592 #include "Connectivity.h"
593 #include <QDBusConnection>
594-#include <QDBusInterface>
595 #include <QDBusPendingCall>
596
597 Connectivity::Connectivity(QObject *parent)
598@@ -26,8 +25,9 @@
599
600 void Connectivity::unlockAllModems()
601 {
602- QDBusInterface iface("com.ubuntu.connectivity1",
603- "/com/ubuntu/connectivity1/Private",
604- "com.ubuntu.connectivity1.Private");
605- iface.asyncCall("UnlockAllModems");
606+ const QDBusMessage msg = QDBusMessage::createMethodCall("com.ubuntu.connectivity1",
607+ "/com/ubuntu/connectivity1/Private",
608+ "com.ubuntu.connectivity1.Private",
609+ "UnlockAllModems");
610+ QDBusConnection::sessionBus().asyncCall(msg);
611 }
612
613=== modified file 'plugins/Unity/Connectivity/Connectivity.h'
614--- plugins/Unity/Connectivity/Connectivity.h 2014-08-20 17:14:55 +0000
615+++ plugins/Unity/Connectivity/Connectivity.h 2015-06-19 11:26:12 +0000
616@@ -26,6 +26,7 @@
617
618 public:
619 explicit Connectivity(QObject *parent = 0);
620+ ~Connectivity() = default;
621
622 Q_INVOKABLE void unlockAllModems();
623 };
624
625=== modified file 'plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h'
626--- plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h 2014-10-30 21:43:18 +0000
627+++ plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h 2015-06-19 11:26:12 +0000
628@@ -36,4 +36,4 @@
629
630 };
631
632-#endif // DBUSUNITYSESSIONSERVICE_H
633+#endif // DBUSDASHCOMMUNICATORSERVICE_H
634
635=== modified file 'plugins/Unity/DashCommunicator/plugin.cpp'
636--- plugins/Unity/DashCommunicator/plugin.cpp 2014-07-24 16:02:27 +0000
637+++ plugins/Unity/DashCommunicator/plugin.cpp 2015-06-19 11:26:12 +0000
638@@ -25,6 +25,7 @@
639
640 void DashCommunicatorPlugin::registerTypes(const char *uri)
641 {
642+ // @uri Unity.DashCommunicator
643 Q_ASSERT(uri == QStringLiteral("Unity.DashCommunicator"));
644 qmlRegisterType<DashCommunicatorService>(uri, 0, 1, "DashCommunicatorService");
645 qmlRegisterType<DashCommunicator>(uri, 0, 1, "DashCommunicator");
646
647=== modified file 'plugins/Unity/Launcher/dbusinterface.cpp'
648--- plugins/Unity/Launcher/dbusinterface.cpp 2014-11-04 12:53:23 +0000
649+++ plugins/Unity/Launcher/dbusinterface.cpp 2015-06-19 11:26:12 +0000
650@@ -32,10 +32,6 @@
651 {
652 }
653
654-DBusInterface::~DBusInterface()
655-{
656-}
657-
658 QString DBusInterface::introspect(const QString &path) const
659 {
660 /* This case we should just list the nodes */
661
662=== modified file 'plugins/Unity/Launcher/dbusinterface.h'
663--- plugins/Unity/Launcher/dbusinterface.h 2014-10-09 15:00:32 +0000
664+++ plugins/Unity/Launcher/dbusinterface.h 2015-06-19 11:26:12 +0000
665@@ -27,7 +27,7 @@
666 Q_OBJECT
667 public:
668 DBusInterface(LauncherModel *parent);
669- ~DBusInterface();
670+ ~DBusInterface() = default;
671
672 // QDBusVirtualObject implementaition
673 QString introspect (const QString &path) const override;
674
675=== modified file 'plugins/Unity/Session/CMakeLists.txt'
676--- plugins/Unity/Session/CMakeLists.txt 2015-02-03 12:17:50 +0000
677+++ plugins/Unity/Session/CMakeLists.txt 2015-06-19 11:26:12 +0000
678@@ -2,6 +2,7 @@
679
680 include_directories(
681 ${CMAKE_CURRENT_SOURCE_DIR}
682+ ${CMAKE_CURRENT_BINARY_DIR}
683 ${GIO_INCLUDE_DIRS}
684 ${libunity8-private_SOURCE_DIR}
685 )
686
687=== modified file 'plugins/Unity/Session/dbusunitysessionservice.cpp'
688--- plugins/Unity/Session/dbusunitysessionservice.cpp 2015-03-02 12:11:03 +0000
689+++ plugins/Unity/Session/dbusunitysessionservice.cpp 2015-06-19 11:26:12 +0000
690@@ -1,5 +1,5 @@
691 /*
692- * Copyright (C) 2014 Canonical, Ltd.
693+ * Copyright (C) 2014, 2015 Canonical, Ltd.
694 *
695 * This program is free software: you can redistribute it and/or modify it under
696 * the terms of the GNU Lesser General Public License version 3, as published by
697@@ -12,122 +12,462 @@
698 *
699 * You should have received a copy of the GNU Lesser General Public License
700 * along with this program. If not, see <http://www.gnu.org/licenses/>.
701+ *
702+ * Authors: Lukáš Tinkl <ltinkl@canonical.com>
703+ * Christopher Townsend <christopher.townsend@canonical.com>
704+ * Ying-Chun Liu (PaulLiu) <paul.liu@canonical.com>
705 */
706
707 // local
708 #include "dbusunitysessionservice.h"
709
710+// system
711+#include <sys/types.h>
712+#include <unistd.h>
713+#include <pwd.h>
714+
715 // Qt
716-#include <QDBusConnection>
717-#include <QDBusInterface>
718+#include <QDebug>
719+#include <QDBusPendingCall>
720+#include <QDBusReply>
721+#include <QElapsedTimer>
722+#include <QDateTime>
723+
724+#define LOGIN1_SERVICE QStringLiteral("org.freedesktop.login1")
725+#define LOGIN1_PATH QStringLiteral("/org/freedesktop/login1")
726+#define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
727+#define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
728+
729+#define ACTIVE_KEY QStringLiteral("Active")
730+#define IDLE_SINCE_KEY QStringLiteral("IdleSinceHint")
731+
732+class DBusUnitySessionServicePrivate: public QObject
733+{
734+ Q_OBJECT
735+public:
736+ QString logindSessionPath;
737+ bool isSessionActive = true;
738+ QElapsedTimer screensaverActiveTimer;
739+
740+ DBusUnitySessionServicePrivate(): QObject() {
741+ init();
742+ checkActive();
743+ }
744+
745+ void init()
746+ {
747+ // get our logind session path
748+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
749+ LOGIN1_PATH,
750+ LOGIN1_IFACE,
751+ "GetSessionByPID");
752+ msg << (quint32) getpid();
753+
754+ QDBusReply<QDBusObjectPath> reply = QDBusConnection::systemBus().asyncCall(msg);
755+ if (reply.isValid()) {
756+ logindSessionPath = reply.value().path();
757+ //qDebug() << "session path" << logindSessionPath;
758+
759+ // start watching the Active property
760+ QDBusConnection::systemBus().connect(LOGIN1_SERVICE, logindSessionPath, "org.freedesktop.DBus.Properties", "PropertiesChanged",
761+ this, SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
762+ } else {
763+ qWarning() << "Failed to get logind session path" << reply.error().message();
764+ }
765+ }
766+
767+ bool checkLogin1Call(const QString &method) const
768+ {
769+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
770+ QDBusReply<QString> reply = QDBusConnection::systemBus().asyncCall(msg);
771+ return reply.isValid() && (reply == QStringLiteral("yes") || reply == QStringLiteral("challenge"));
772+ }
773+
774+ void makeLogin1Call(const QString &method, const QVariantList &args)
775+ {
776+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
777+ LOGIN1_PATH,
778+ LOGIN1_IFACE,
779+ method);
780+ msg.setArguments(args);
781+ QDBusConnection::systemBus().asyncCall(msg);
782+ }
783+
784+ void checkActive()
785+ {
786+ if (logindSessionPath.isEmpty()) {
787+ qWarning() << "Invalid session path";
788+ return;
789+ }
790+
791+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
792+ logindSessionPath,
793+ "org.freedesktop.DBus.Properties",
794+ "Get");
795+ msg << LOGIN1_SESSION_IFACE;
796+ msg << ACTIVE_KEY;
797+
798+ QDBusReply<QVariant> reply = QDBusConnection::systemBus().asyncCall(msg);
799+ if (reply.isValid()) {
800+ isSessionActive = reply.value().toBool();
801+ qDebug() << "Session" << logindSessionPath << "is active:" << isSessionActive;
802+ } else {
803+ qWarning() << "Failed to get Active property" << reply.error().message();
804+ }
805+ }
806+
807+ quint32 screensaverActiveTime() const
808+ {
809+ if (!isSessionActive && screensaverActiveTimer.isValid()) {
810+ return screensaverActiveTimer.elapsed() / 1000;
811+ }
812+
813+ return 0;
814+ }
815+
816+ quint64 idleSinceUSecTimestamp() const
817+ {
818+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
819+ logindSessionPath,
820+ "org.freedesktop.DBus.Properties",
821+ "Get");
822+ msg << LOGIN1_SESSION_IFACE;
823+ msg << IDLE_SINCE_KEY;
824+
825+ QDBusReply<QVariant> reply = QDBusConnection::systemBus().asyncCall(msg);
826+ if (reply.isValid()) {
827+ return reply.value().value<quint64>();
828+ } else {
829+ qWarning() << "Failed to get IdleSinceHint property" << reply.error().message();
830+ }
831+
832+ return 0;
833+ }
834+
835+ void setIdleHint(bool idle)
836+ {
837+ QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
838+ logindSessionPath,
839+ LOGIN1_SESSION_IFACE,
840+ "SetIdleHint");
841+ msg << idle;
842+ QDBusConnection::systemBus().asyncCall(msg);
843+ }
844+
845+private Q_SLOTS:
846+ void onPropertiesChanged(const QString &iface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
847+ {
848+ Q_UNUSED(iface)
849+
850+ if (changedProps.contains(ACTIVE_KEY) || invalidatedProps.contains(ACTIVE_KEY)) {
851+ if (changedProps.value(ACTIVE_KEY).isValid()) {
852+ isSessionActive = changedProps.value(ACTIVE_KEY).toBool();
853+ } else {
854+ checkActive();
855+ }
856+
857+ Q_EMIT screensaverActiveChanged(!isSessionActive);
858+
859+ if (isSessionActive) {
860+ screensaverActiveTimer.invalidate();
861+ setIdleHint(false);
862+ } else {
863+ screensaverActiveTimer.start();
864+ setIdleHint(true);
865+ }
866+ }
867+ }
868+
869+Q_SIGNALS:
870+ void screensaverActiveChanged(bool active);
871+};
872+
873+Q_GLOBAL_STATIC(DBusUnitySessionServicePrivate, d)
874
875 DBusUnitySessionService::DBusUnitySessionService()
876 : UnityDBusObject("/com/canonical/Unity/Session", "com.canonical.Unity")
877 {
878-}
879-
880-DBusUnitySessionService::~DBusUnitySessionService()
881-{
882+ if (!d->logindSessionPath.isEmpty()) {
883+ // connect our Lock() slot to the logind's session Lock() signal
884+ QDBusConnection::systemBus().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, "Lock", this, SLOT(Lock()));
885+ // ... and our Unlocked() signal to the logind's session Unlock() signal
886+ // (lightdm handles the unlocking by calling logind's Unlock method which in turn emits this signal we connect to)
887+ QDBusConnection::systemBus().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, "Unlock", this, SIGNAL(Unlocked()));
888+ } else {
889+ qWarning() << "Failed to connect to logind's session Lock/Unlock signals";
890+ }
891 }
892
893 void DBusUnitySessionService::Logout()
894 {
895- Q_EMIT logoutReady();
896+ // TODO ask the apps to quit and then emit the signal
897+ Q_EMIT LogoutReady();
898 }
899
900 void DBusUnitySessionService::EndSession()
901 {
902- QDBusConnection connection = QDBusConnection::sessionBus();
903- QDBusInterface iface1 ("com.ubuntu.Upstart",
904- "/com/ubuntu/Upstart",
905- "com.ubuntu.Upstart0_6",
906- connection);
907-
908- iface1.call("EndSession");
909+ const QDBusMessage msg = QDBusMessage::createMethodCall("com.ubuntu.Upstart",
910+ "/com/ubuntu/Upstart",
911+ "com.ubuntu.Upstart0_6",
912+ "EndSession");
913+ QDBusConnection::sessionBus().asyncCall(msg);
914+}
915+
916+bool DBusUnitySessionService::CanHibernate() const
917+{
918+ return d->checkLogin1Call("CanHibernate");
919+}
920+
921+bool DBusUnitySessionService::CanSuspend() const
922+{
923+ return d->checkLogin1Call("CanSuspend");
924+}
925+
926+bool DBusUnitySessionService::CanHybridSleep() const
927+{
928+ return d->checkLogin1Call("CanHybridSleep");
929+}
930+
931+bool DBusUnitySessionService::CanReboot() const
932+{
933+ return d->checkLogin1Call("CanReboot");
934+}
935+
936+bool DBusUnitySessionService::CanShutdown() const
937+{
938+ return d->checkLogin1Call("CanPowerOff");
939+}
940+
941+bool DBusUnitySessionService::CanLock() const
942+{
943+ return true; // FIXME
944+}
945+
946+QString DBusUnitySessionService::UserName() const
947+{
948+ struct passwd *p = getpwuid(getuid());
949+ if (p) {
950+ return QString::fromUtf8(p->pw_name);
951+ }
952+
953+ return QString();
954+}
955+
956+QString DBusUnitySessionService::RealName() const
957+{
958+ struct passwd *p = getpwuid(getuid());
959+ if (p) {
960+ const QString gecos = QString::fromLocal8Bit(p->pw_gecos);
961+ if (!gecos.isEmpty()) {
962+ return gecos.split(QLatin1Char(',')).first();
963+ }
964+ }
965+
966+ return QString();
967+}
968+
969+QString DBusUnitySessionService::HostName() const
970+{
971+ char hostName[512];
972+ if (gethostname(hostName, sizeof(hostName)) == -1) {
973+ qWarning() << "Could not determine local hostname";
974+ return QString();
975+ }
976+ hostName[sizeof(hostName) - 1] = '\0';
977+ return QString::fromLocal8Bit(hostName);
978+}
979+
980+void DBusUnitySessionService::PromptLock()
981+{
982+ Q_EMIT LockRequested();
983+}
984+
985+void DBusUnitySessionService::Lock()
986+{
987+ // lock the session using the org.freedesktop.DisplayManager system DBUS service
988+ const QString sessionPath = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
989+ QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DisplayManager",
990+ sessionPath,
991+ "org.freedesktop.DisplayManager.Session",
992+ "Lock");
993+ qDebug() << "Locking session" << msg.path();
994+ QDBusReply<void> reply = QDBusConnection::systemBus().asyncCall(msg);
995+ if (!reply.isValid()) {
996+ qWarning() << "Lock call failed" << reply.error().message();
997+ } else {
998+ // emit Locked when the call succeeds
999+ Q_EMIT Locked();
1000+ }
1001+}
1002+
1003+bool DBusUnitySessionService::IsLocked() const
1004+{
1005+ return !d->isSessionActive;
1006 }
1007
1008 void DBusUnitySessionService::RequestLogout()
1009 {
1010- Q_EMIT logoutRequested(false);
1011+ Q_EMIT LogoutRequested(false);
1012 }
1013
1014 void DBusUnitySessionService::Reboot()
1015 {
1016- QDBusConnection connection = QDBusConnection::systemBus();
1017- QDBusInterface iface1 ("org.freedesktop.login1",
1018- "/org/freedesktop/login1",
1019- "org.freedesktop.login1.Manager",
1020- connection);
1021-
1022- iface1.call("Reboot", false);
1023+ d->makeLogin1Call("Reboot", {false});
1024 }
1025
1026 void DBusUnitySessionService::RequestReboot()
1027 {
1028- Q_EMIT rebootRequested(false);
1029+ Q_EMIT RebootRequested(false);
1030 }
1031
1032 void DBusUnitySessionService::Shutdown()
1033 {
1034- QDBusConnection connection = QDBusConnection::systemBus();
1035- QDBusInterface iface1 ("org.freedesktop.login1",
1036- "/org/freedesktop/login1",
1037- "org.freedesktop.login1.Manager",
1038- connection);
1039-
1040- iface1.call("PowerOff", false);
1041+ d->makeLogin1Call("PowerOff", {false});
1042+}
1043+
1044+void DBusUnitySessionService::Suspend()
1045+{
1046+ d->makeLogin1Call("Suspend", {false});
1047+}
1048+
1049+void DBusUnitySessionService::Hibernate()
1050+{
1051+ d->makeLogin1Call("Hibernate", {false});
1052+}
1053+
1054+void DBusUnitySessionService::HybridSleep()
1055+{
1056+ d->makeLogin1Call("HybridSleep", {false});
1057 }
1058
1059 void DBusUnitySessionService::RequestShutdown()
1060 {
1061- Q_EMIT shutdownRequested(false);
1062+ Q_EMIT ShutdownRequested(false);
1063 }
1064
1065 enum class Action : unsigned
1066 {
1067- LOGOUT = 0,
1068- SHUTDOWN,
1069- REBOOT,
1070- NONE
1071+ LOGOUT = 0,
1072+ SHUTDOWN,
1073+ REBOOT,
1074+ NONE
1075 };
1076
1077+
1078+void performAsyncUnityCall(const QString &method)
1079+{
1080+ const QDBusMessage msg = QDBusMessage::createMethodCall("com.canonical.Unity",
1081+ "/com/canonical/Unity/Session",
1082+ "com.canonical.Unity.Session",
1083+ method);
1084+ QDBusConnection::sessionBus().asyncCall(msg);
1085+}
1086+
1087+
1088 DBusGnomeSessionManagerWrapper::DBusGnomeSessionManagerWrapper()
1089 : UnityDBusObject("/org/gnome/SessionManager/EndSessionDialog", "com.canonical.Unity")
1090 {
1091 }
1092
1093-DBusGnomeSessionManagerWrapper::~DBusGnomeSessionManagerWrapper()
1094-{
1095-}
1096-
1097 void DBusGnomeSessionManagerWrapper::Open(const unsigned type, const unsigned arg_1, const unsigned max_wait, const QList<QDBusObjectPath> &inhibitors)
1098 {
1099- Q_UNUSED(arg_1);
1100- Q_UNUSED(max_wait);
1101- Q_UNUSED(inhibitors);
1102-
1103- QDBusConnection connection = QDBusConnection::sessionBus();
1104- QDBusInterface iface1 ("com.canonical.Unity",
1105- "/com/canonical/Unity/Session",
1106- "com.canonical.Unity.Session",
1107- connection);
1108-
1109- Action action = (Action)type;
1110-
1111- switch (action)
1112- {
1113+ Q_UNUSED(arg_1);
1114+ Q_UNUSED(max_wait);
1115+ Q_UNUSED(inhibitors);
1116+
1117+ switch (static_cast<Action>(type))
1118+ {
1119 case Action::LOGOUT:
1120- iface1.call("RequestLogout");
1121- break;
1122+ performAsyncUnityCall("RequestLogout");
1123+ break;
1124
1125 case Action::REBOOT:
1126- iface1.call("RequestShutdown");
1127- break;
1128+ performAsyncUnityCall("RequestReboot");
1129+ break;
1130
1131 case Action::SHUTDOWN:
1132- break;
1133+ performAsyncUnityCall("RequestShutdown");
1134+ break;
1135
1136 default:
1137- break;
1138- }
1139-}
1140+ break;
1141+ }
1142+}
1143+
1144+
1145+DBusGnomeScreensaverWrapper::DBusGnomeScreensaverWrapper()
1146+ : UnityDBusObject("/org/gnome/ScreenSaver", "org.gnome.ScreenSaver")
1147+{
1148+ connect(d, &DBusUnitySessionServicePrivate::screensaverActiveChanged, this, &DBusGnomeScreensaverWrapper::ActiveChanged);
1149+}
1150+
1151+bool DBusGnomeScreensaverWrapper::GetActive() const
1152+{
1153+ return !d->isSessionActive; // return whether the session is not active
1154+}
1155+
1156+void DBusGnomeScreensaverWrapper::SetActive(bool lock)
1157+{
1158+ if (lock) {
1159+ Lock();
1160+ }
1161+}
1162+
1163+void DBusGnomeScreensaverWrapper::Lock()
1164+{
1165+ performAsyncUnityCall("Lock");
1166+}
1167+
1168+quint32 DBusGnomeScreensaverWrapper::GetActiveTime() const
1169+{
1170+ return d->screensaverActiveTime();
1171+}
1172+
1173+void DBusGnomeScreensaverWrapper::SimulateUserActivity()
1174+{
1175+ d->setIdleHint(false);
1176+}
1177+
1178+
1179+DBusScreensaverWrapper::DBusScreensaverWrapper()
1180+ : UnityDBusObject("/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver")
1181+{
1182+ QDBusConnection::sessionBus().registerObject("/ScreenSaver", this, QDBusConnection::ExportScriptableContents); // compat path, also register here
1183+ connect(d, &DBusUnitySessionServicePrivate::screensaverActiveChanged, this, &DBusScreensaverWrapper::ActiveChanged);
1184+}
1185+
1186+bool DBusScreensaverWrapper::GetActive() const
1187+{
1188+ return !d->isSessionActive; // return whether the session is not active
1189+}
1190+
1191+bool DBusScreensaverWrapper::SetActive(bool lock)
1192+{
1193+ if (lock) {
1194+ Lock();
1195+ return true;
1196+ }
1197+ return false;
1198+}
1199+
1200+void DBusScreensaverWrapper::Lock()
1201+{
1202+ performAsyncUnityCall("Lock");
1203+}
1204+
1205+quint32 DBusScreensaverWrapper::GetActiveTime() const
1206+{
1207+ return d->screensaverActiveTime();
1208+}
1209+
1210+quint32 DBusScreensaverWrapper::GetSessionIdleTime() const
1211+{
1212+ return QDateTime::fromMSecsSinceEpoch(d->idleSinceUSecTimestamp()/1000).secsTo(QDateTime::currentDateTime());
1213+}
1214+
1215+void DBusScreensaverWrapper::SimulateUserActivity()
1216+{
1217+ d->setIdleHint(false);
1218+}
1219+
1220+#include "dbusunitysessionservice.moc"
1221
1222=== modified file 'plugins/Unity/Session/dbusunitysessionservice.h'
1223--- plugins/Unity/Session/dbusunitysessionservice.h 2015-03-02 12:11:03 +0000
1224+++ plugins/Unity/Session/dbusunitysessionservice.h 2015-06-19 11:26:12 +0000
1225@@ -1,5 +1,5 @@
1226-/*
1227- * Copyright (C) 2014 Canonical, Ltd.
1228+/*
1229+ * Copyright (C) 2014, 2015 Canonical, Ltd.
1230 *
1231 * This program is free software: you can redistribute it and/or modify it under
1232 * the terms of the GNU Lesser General Public License version 3, as published by
1233@@ -29,7 +29,7 @@
1234 * interface.
1235 *
1236 * com.canonical.Unity.Session interface provides public methods
1237- * and signals to handle Logout/Reboot/Shutdown.
1238+ * and signals to handle eg. Logout/Reboot/Shutdown.
1239 */
1240 class DBusUnitySessionService : public UnityDBusObject
1241 {
1242@@ -38,7 +38,7 @@
1243
1244 public:
1245 DBusUnitySessionService();
1246- ~DBusUnitySessionService();
1247+ ~DBusUnitySessionService() = default;
1248
1249 // For use in QML. Javascript doesn't accept functions beginning with capital letters
1250 Q_INVOKABLE void logout() { Logout(); }
1251@@ -48,49 +48,63 @@
1252
1253 Q_SIGNALS:
1254 /**
1255- * logoutRequested signal
1256+ * LogoutRequested signal
1257 *
1258 * This signal is emitted when some applications request the system to
1259 * logout.
1260 * @param have_inhibitors if there are any special running applications
1261 * which inhibit the logout.
1262 */
1263- Q_SCRIPTABLE void logoutRequested(bool have_inhibitors);
1264+ Q_SCRIPTABLE void LogoutRequested(bool have_inhibitors);
1265
1266 /**
1267- * rebootRequested signal
1268+ * RebootRequested signal
1269 *
1270 * This signal is emitted when some applications request the system to
1271 * reboot.
1272 * @param have_inhibitors if there are any special running applications
1273 * which inhibit the reboot.
1274 */
1275- Q_SCRIPTABLE void rebootRequested(bool have_inhibitors);
1276+ Q_SCRIPTABLE void RebootRequested(bool have_inhibitors);
1277
1278 /**
1279- * shutdownRequested signal
1280+ * ShutdownRequested signal
1281 *
1282 * This signal is emitted when some applications request the system to
1283 * shutdown.
1284 * @param have_inhibitors if there are any special running applications
1285 * which inhibit the shutdown.
1286 */
1287- Q_SCRIPTABLE void shutdownRequested(bool have_inhibitors);
1288-
1289+ Q_SCRIPTABLE void ShutdownRequested(bool have_inhibitors);
1290
1291 /**
1292- * logoutReady signal
1293+ * LogoutReady signal
1294 *
1295 * This signal is emitted when all the apps are closed. And the system
1296 * is safe to logout.
1297 */
1298- void logoutReady();
1299+ Q_SCRIPTABLE void LogoutReady();
1300+
1301+ /**
1302+ * Emitted as a result of calling PromptLock()
1303+ */
1304+ Q_SCRIPTABLE void LockRequested();
1305+
1306+ /**
1307+ * Emitted after the session has been locked.
1308+ */
1309+ Q_SCRIPTABLE void Locked();
1310+
1311+ /**
1312+ * Emitted after the session has been unlocked.
1313+ */
1314+ Q_SCRIPTABLE void Unlocked();
1315
1316 public Q_SLOTS:
1317 /**
1318 * Logout the system.
1319 *
1320- * This method directly logout the system without user's confirmation.
1321+ * This method directly logs out the system without user's confirmation.
1322 * Ordinary applications should avoid calling this method. Please call
1323 * RequestLogout() to ask the user to decide logout or not.
1324 */
1325@@ -99,7 +113,7 @@
1326 /**
1327 * Reboot the system.
1328 *
1329- * This method directly reboot the system without user's confirmation.
1330+ * This method directly reboots the system without user's confirmation.
1331 * Ordinary applications should avoid calling this method. Please call
1332 * RequestReboot() to ask the user to decide reboot or not.
1333 */
1334@@ -108,16 +122,39 @@
1335 /**
1336 * Shutdown the system.
1337 *
1338- * This method directly shutdown the system without user's confirmation.
1339+ * This method directly shuts down the system without user's confirmation.
1340 * Ordinary applications should avoid calling this method. Please call
1341 * RequestShutdown() to ask the user to decide shutdown or not.
1342 */
1343 Q_SCRIPTABLE void Shutdown();
1344
1345 /**
1346+ * Suspend the system
1347+ *
1348+ * This method puts the system into sleep without user's confirmation.
1349+ */
1350+ Q_SCRIPTABLE void Suspend();
1351+
1352+ /**
1353+ * Hibernate the system
1354+ *
1355+ * This method puts the system into hibernation without user's confirmation.
1356+ */
1357+ Q_SCRIPTABLE void Hibernate();
1358+
1359+ /**
1360+ * Hybrid sleep
1361+ *
1362+ * This method puts the system into hybrid sleep without user's confirmation.
1363+ *
1364+ * @since unity8
1365+ */
1366+ Q_SCRIPTABLE void HybridSleep();
1367+
1368+ /**
1369 * Issue a logout request.
1370 *
1371- * This method emit the logoutRequested signal to the shell with a boolean
1372+ * This method emits the LogoutRequested signal to the shell with a boolean
1373 * which indicates if there's any inhibitors. The shell should receive
1374 * this signal and display a dialog to ask the user to confirm the logout
1375 * action. If confirmed, shell can call Logout() method to logout.
1376@@ -127,21 +164,21 @@
1377 /**
1378 * Issue a reboot request.
1379 *
1380- * This method emit the rebootRequested signal to the shell with a boolean
1381+ * This method emits the RebootRequested signal to the shell with a boolean
1382 * which indicates if there's any inhibitors. The shell should receive
1383 * this signal and display a dialog to ask the user to confirm the reboot
1384- * action. If confirmed, shell can call Reboot() method to reboot
1385+ * action. If confirmed, shell can call Reboot() method to reboot.
1386 */
1387 Q_SCRIPTABLE void RequestReboot();
1388
1389 /**
1390 * Issue a shutdown request.
1391 *
1392- * This method emit the shutdownRequested signal to the shell with a
1393+ * This method emits the ShutdownRequested signal to the shell with a
1394 * boolean which indicates if there's any inhibitors.
1395 * The shell should receive
1396 * this signal and display a dialog to ask the user to confirm the reboot
1397- * action. If confirmed, shell can call Shutdown() method to reboot
1398+ * action. If confirmed, shell can call Shutdown() method to shutdown.
1399 */
1400 Q_SCRIPTABLE void RequestShutdown();
1401
1402@@ -152,6 +189,68 @@
1403 * current DBus session bus.
1404 */
1405 Q_SCRIPTABLE void EndSession();
1406+
1407+ /**
1408+ * @return whether the system is capable of hibernating
1409+ */
1410+ Q_SCRIPTABLE bool CanHibernate() const;
1411+
1412+ /**
1413+ * @return whether the system is capable of suspending
1414+ */
1415+ Q_SCRIPTABLE bool CanSuspend() const;
1416+
1417+ /**
1418+ * @return whether the system is capable of hybrid sleep
1419+ * @since unity8
1420+ */
1421+ Q_SCRIPTABLE bool CanHybridSleep() const;
1422+
1423+ /**
1424+ * @return whether the system is capable of rebooting
1425+ * @since unity8
1426+ */
1427+ Q_SCRIPTABLE bool CanReboot() const;
1428+
1429+ /**
1430+ * @return whether the system is capable of shutting down
1431+ */
1432+ Q_SCRIPTABLE bool CanShutdown() const;
1433+
1434+ /**
1435+ * @return whether the system is capable of locking the session
1436+ */
1437+ Q_SCRIPTABLE bool CanLock() const;
1438+
1439+ /**
1440+ * @return the login name of the current user
1441+ */
1442+ Q_SCRIPTABLE QString UserName() const;
1443+
1444+ /**
1445+ * @return the real name of the current user
1446+ */
1447+ Q_SCRIPTABLE QString RealName() const;
1448+
1449+ /**
1450+ * @return the local hostname
1451+ */
1452+ Q_SCRIPTABLE QString HostName() const;
1453+
1454+ /**
1455+ * Request that the session get locked, emits signal LockRequested()
1456+ */
1457+ Q_SCRIPTABLE void PromptLock();
1458+
1459+ /**
1460+ * Locks the session immediately
1461+ */
1462+ Q_SCRIPTABLE void Lock();
1463+
1464+ /**
1465+ * @return whether the session is currently locked
1466+ */
1467+ Q_SCRIPTABLE bool IsLocked() const;
1468 };
1469
1470 class DBusGnomeSessionManagerWrapper : public UnityDBusObject
1471@@ -161,9 +260,87 @@
1472
1473 public:
1474 DBusGnomeSessionManagerWrapper();
1475- ~DBusGnomeSessionManagerWrapper();
1476+ ~DBusGnomeSessionManagerWrapper() = default;
1477
1478 public Q_SLOTS:
1479 Q_SCRIPTABLE void Open(const unsigned int type, const unsigned int arg_1, const unsigned int max_wait, const QList<QDBusObjectPath> &inhibitors);
1480 };
1481+
1482+class DBusGnomeScreensaverWrapper: public UnityDBusObject
1483+{
1484+ Q_OBJECT
1485+ Q_CLASSINFO("D-Bus Interface", "org.gnome.ScreenSaver")
1486+
1487+public:
1488+ DBusGnomeScreensaverWrapper();
1489+ ~DBusGnomeScreensaverWrapper() = default;
1490+
1491+public Q_SLOTS:
1492+ /**
1493+ * @return whether the session is currently locked (screensaver is on)
1494+ */
1495+ Q_SCRIPTABLE bool GetActive() const;
1496+
1497+ /**
1498+ * Locks the session immediately if @p lock is true
1499+ */
1500+ Q_SCRIPTABLE void SetActive(bool lock);
1501+
1502+ /**
1503+ * Locks the session immediately
1504+ */
1505+ Q_SCRIPTABLE void Lock();
1506+
1507+ /**
1508+ * @return the number of seconds elapsed since the screensaver had been active
1509+ */
1510+ Q_SCRIPTABLE quint32 GetActiveTime() const;
1511+
1512+ Q_SCRIPTABLE void SimulateUserActivity();
1513+
1514+Q_SIGNALS:
1515+ void ActiveChanged(bool active);
1516+};
1517+
1518+class DBusScreensaverWrapper: public UnityDBusObject
1519+{
1520+ Q_OBJECT
1521+ Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver")
1522+
1523+public:
1524+ DBusScreensaverWrapper();
1525+ ~DBusScreensaverWrapper() = default;
1526+
1527+public Q_SLOTS:
1528+ /**
1529+ * @return whether the session is currently locked (screensaver is on)
1530+ */
1531+ Q_SCRIPTABLE bool GetActive() const;
1532+
1533+ /**
1534+ * Locks the session immediately if @p lock is true
1535+ */
1536+ Q_SCRIPTABLE bool SetActive(bool lock);
1537+
1538+ /**
1539+ * Locks the session immediately
1540+ */
1541+ Q_SCRIPTABLE void Lock();
1542+
1543+ /**
1544+ * @return the number of seconds elapsed since the screensaver had been active
1545+ */
1546+ Q_SCRIPTABLE quint32 GetActiveTime() const;
1547+
1548+ /**
1549+ * @return the number of seconds that this session has been idle
1550+ */
1551+ Q_SCRIPTABLE quint32 GetSessionIdleTime() const;
1552+
1553+ Q_SCRIPTABLE void SimulateUserActivity();
1554+
1555+Q_SIGNALS:
1556+ void ActiveChanged(bool active);
1557+};
1558+
1559 #endif // DBUSUNITYSESSIONSERVICE_H
1560
1561=== modified file 'plugins/Utils/relativetimeformatter.cpp'
1562--- plugins/Utils/relativetimeformatter.cpp 2014-10-21 19:28:01 +0000
1563+++ plugins/Utils/relativetimeformatter.cpp 2015-06-19 11:26:12 +0000
1564@@ -121,7 +121,7 @@
1565 const char*
1566 dgettext_datetime(const char *text)
1567 {
1568- return dgettext("indicator-datetime", text);
1569+ return dgettext("unity8", text);
1570 }
1571
1572 /**
1573
1574=== modified file 'plugins/Wizard/System.cpp'
1575--- plugins/Wizard/System.cpp 2014-11-19 17:43:09 +0000
1576+++ plugins/Wizard/System.cpp 2015-06-19 11:26:12 +0000
1577@@ -16,7 +16,9 @@
1578
1579 #include "System.h"
1580
1581-#include <QDBusInterface>
1582+#include <QDBusPendingCall>
1583+#include <QDBusMessage>
1584+#include <QDBusConnection>
1585 #include <QDBusMetaType>
1586 #include <QDir>
1587 #include <QFile>
1588@@ -65,21 +67,23 @@
1589 void System::setSessionVariable(const QString &variable, const QString &value)
1590 {
1591 // We need to update both upstart's and DBus's environment
1592- QProcess::execute(QString("initctl set-env --global %1=%2").arg(variable, value));
1593-
1594- QDBusInterface iface("org.freedesktop.DBus",
1595- "/org/freedesktop/DBus",
1596- "org.freedesktop.DBus",
1597- QDBusConnection::sessionBus());
1598+ QProcess::startDetached(QStringLiteral("initctl set-env --global %1=%2").arg(variable, value));
1599
1600 QMap<QString,QString> valueMap;
1601 valueMap.insert(variable, value);
1602- iface.call("UpdateActivationEnvironment", QVariant::fromValue(valueMap));
1603+
1604+ QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus",
1605+ "/org/freedesktop/DBus",
1606+ "org.freedesktop.DBus",
1607+ "UpdateActivationEnvironment");
1608+
1609+ msg << QVariant::fromValue(valueMap);
1610+ QDBusConnection::sessionBus().asyncCall(msg);
1611 }
1612
1613 void System::updateSessionLanguage(const QString &locale)
1614 {
1615- QString language = locale.split(".")[0];
1616+ const QString language = locale.split(".")[0];
1617
1618 setSessionVariable("LANGUAGE", language);
1619 setSessionVariable("LANG", locale);
1620
1621=== modified file 'tests/plugins/AccountsService/client.cpp'
1622--- tests/plugins/AccountsService/client.cpp 2015-04-17 16:44:28 +0000
1623+++ tests/plugins/AccountsService/client.cpp 2015-06-19 11:26:12 +0000
1624@@ -94,8 +94,7 @@
1625
1626 void testGetSetService()
1627 {
1628- AccountsService session;
1629- session.setUser(QTest::currentTestFunction());
1630+ AccountsService session(this, QTest::currentTestFunction());
1631
1632 QCOMPARE(session.demoEdges(), false);
1633 session.setDemoEdges(true);
1634@@ -112,8 +111,7 @@
1635
1636 void testAsynchornousChangeForDemoEdges()
1637 {
1638- AccountsService session;
1639- session.setUser(QTest::currentTestFunction());
1640+ AccountsService session(this, QTest::currentTestFunction());
1641
1642 QCOMPARE(session.demoEdges(), false);
1643 ASSERT_DBUS_CALL(m_userInterface->call("Set",
1644@@ -125,8 +123,7 @@
1645
1646 void testAsynchornousChangeForFailedLogins()
1647 {
1648- AccountsService session;
1649- session.setUser(QTest::currentTestFunction());
1650+ AccountsService session(this, QTest::currentTestFunction());
1651
1652 QCOMPARE(session.failedLogins(), (uint)0);
1653 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1654@@ -138,8 +135,7 @@
1655
1656 void testAsynchornousChangeForStatsWelcomeScreen()
1657 {
1658- AccountsService session;
1659- session.setUser(QTest::currentTestFunction());
1660+ AccountsService session(this, QTest::currentTestFunction());
1661
1662 QCOMPARE(session.statsWelcomeScreen(), true);
1663 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1664@@ -151,8 +147,7 @@
1665
1666 void testAsynchornousChangeForStatsEnableLauncherWhileLocked()
1667 {
1668- AccountsService session;
1669- session.setUser(QTest::currentTestFunction());
1670+ AccountsService session(this, QTest::currentTestFunction());
1671
1672 QCOMPARE(session.enableLauncherWhileLocked(), true);
1673 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1674@@ -164,8 +159,7 @@
1675
1676 void testAsynchornousChangeForStatsEnableIndicatorsWhileLocked()
1677 {
1678- AccountsService session;
1679- session.setUser(QTest::currentTestFunction());
1680+ AccountsService session(this, QTest::currentTestFunction());
1681
1682 QCOMPARE(session.enableIndicatorsWhileLocked(), true);
1683 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1684@@ -177,8 +171,7 @@
1685
1686 void testAsynchornousChangeForStatsPasswordDisplayHint()
1687 {
1688- AccountsService session;
1689- session.setUser(QTest::currentTestFunction());
1690+ AccountsService session(this, QTest::currentTestFunction());
1691
1692 QCOMPARE(session.passwordDisplayHint(), AccountsService::Keyboard);
1693 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1694@@ -190,8 +183,7 @@
1695
1696 void testAsynchornousChangeForStatsLicenseAccepted()
1697 {
1698- AccountsService session;
1699- session.setUser(QTest::currentTestFunction());
1700+ AccountsService session(this, QTest::currentTestFunction());
1701
1702 QCOMPARE(session.hereEnabled(), false);
1703 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1704@@ -203,8 +195,7 @@
1705
1706 void testAsynchornousChangeForLicenseBasePath()
1707 {
1708- AccountsService session;
1709- session.setUser(QTest::currentTestFunction());
1710+ AccountsService session(this, QTest::currentTestFunction());
1711
1712 QCOMPARE(session.hereLicensePath(), QString());
1713 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1714@@ -216,8 +207,7 @@
1715
1716 void testAsynchornousChangeForStatsBackgroundFile()
1717 {
1718- AccountsService session;
1719- session.setUser(QTest::currentTestFunction());
1720+ AccountsService session(this, QTest::currentTestFunction());
1721
1722 QCOMPARE(session.backgroundFile(), QString());
1723 ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set",
1724
1725=== modified file 'tests/plugins/Unity/Session/sessionbackendtest.cpp'
1726--- tests/plugins/Unity/Session/sessionbackendtest.cpp 2015-02-03 10:52:07 +0000
1727+++ tests/plugins/Unity/Session/sessionbackendtest.cpp 2015-06-19 11:26:12 +0000
1728@@ -1,5 +1,5 @@
1729 /*
1730- * Copyright 2013 Canonical Ltd.
1731+ * Copyright 2013-2015 Canonical Ltd.
1732 *
1733 * This program is free software; you can redistribute it and/or modify
1734 * it under the terms of the GNU Lesser General Public License as published by
1735@@ -15,6 +15,7 @@
1736 *
1737 * Authors:
1738 * Ying-Chun Liu (PaulLiu) <paul.liu@canonical.com>
1739+ * Lukáš Tinkl <lukas.tinkl@canonical.com>
1740 */
1741
1742 #include <QtTest>
1743@@ -23,6 +24,11 @@
1744 #include <QDBusInterface>
1745 #include <QDBusReply>
1746 #include <QDBusVariant>
1747+#include <QDebug>
1748+#include <QDBusObjectPath>
1749+
1750+#include <unistd.h>
1751+#include <sys/types.h>
1752
1753 #include "dbusunitysessionservice.h"
1754
1755@@ -49,17 +55,23 @@
1756
1757 void testUnitySessionLogoutRequested_data() {
1758 QTest::addColumn<QString>("method");
1759+ QTest::addColumn<QString>("signal");
1760
1761- QTest::newRow("Logout") << "RequestLogout";
1762+ QTest::newRow("Logout") << "RequestLogout" << "LogoutRequested(bool)";
1763+ QTest::newRow("Reboot") << "RequestReboot" << "RebootRequested(bool)";
1764+ QTest::newRow("Shutdown") << "RequestShutdown" << "ShutdownRequested(bool)";
1765+ QTest::newRow("PromptLock") << "PromptLock" << "LockRequested()";
1766 }
1767
1768 void testUnitySessionLogoutRequested() {
1769 QFETCH(QString, method);
1770+ QFETCH(QString, signal);
1771
1772 DBusUnitySessionService dbusUnitySessionService;
1773 QCoreApplication::processEvents(); // to let the service register on DBus
1774
1775- QSignalSpy spy(&dbusUnitySessionService, SIGNAL(logoutRequested(bool)));
1776+ // .. because QSignalSpy checks the signal signature like this: "if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE)"
1777+ QSignalSpy spy(&dbusUnitySessionService, qPrintable(signal.prepend(QSIGNAL_CODE)));
1778
1779 QDBusReply<void> reply = dbusUnitySession->call(method);
1780 QCOMPARE(reply.isValid(), true);
1781@@ -67,67 +79,106 @@
1782 QCOMPARE(spy.count(), 1);
1783 }
1784
1785- void testGnomeSessionWrapperLogoutRequested() {
1786- DBusUnitySessionService dbusUnitySessionService;
1787- QCoreApplication::processEvents(); // to let the service register on DBus
1788-
1789- // Spy on the logoutRequested signal on the /com/canonical/Unity/Session object
1790- // as proof we are actually calling the actual method.
1791- QSignalSpy spy(&dbusUnitySessionService, SIGNAL(logoutRequested(bool)));
1792-
1793- DBusGnomeSessionManagerWrapper dbusGnomeSessionManagerWrapper;
1794- QCoreApplication::processEvents(); // to let the service register on DBus
1795-
1796- QDBusInterface dbusGnomeSessionWrapper ("com.canonical.Unity",
1797- "/org/gnome/SessionManager/EndSessionDialog",
1798- "org.gnome.SessionManager.EndSessionDialog",
1799- QDBusConnection::sessionBus());
1800-
1801- QCOMPARE(dbusGnomeSessionWrapper.isValid(), true);
1802-
1803- // Set the QVariant as a QList<QDBusObjectPath> type
1804- QDbusList var;
1805- QVariant inhibitors;
1806- inhibitors.setValue(var);
1807-
1808- QDBusReply<void> reply = dbusGnomeSessionWrapper.call("Open", (unsigned)Action::LOGOUT, (unsigned)0, (unsigned)0, inhibitors);
1809- QCOMPARE(reply.isValid(), true);
1810-
1811- // Make sure we see the signal being emitted.
1812- QCOMPARE(spy.count(), 1);
1813- }
1814-
1815- void testGnomeSessionWrapperShutdownRequested() {
1816- DBusUnitySessionService dbusUnitySessionService;
1817- QCoreApplication::processEvents(); // to let the service register on DBus
1818-
1819- // Spy on the shutdownRequested signal on the /com/canonical/Unity/Session object
1820- // as proof we are actually calling the actual method.
1821- QSignalSpy spy(&dbusUnitySessionService, SIGNAL(shutdownRequested(bool)));
1822-
1823- DBusGnomeSessionManagerWrapper dbusGnomeSessionManagerWrapper;
1824- QCoreApplication::processEvents(); // to let the service register on DBus
1825-
1826- QDBusInterface dbusGnomeSessionWrapper ("com.canonical.Unity",
1827- "/org/gnome/SessionManager/EndSessionDialog",
1828- "org.gnome.SessionManager.EndSessionDialog",
1829- QDBusConnection::sessionBus());
1830-
1831- QCOMPARE(dbusGnomeSessionWrapper.isValid(), true);
1832-
1833- // Set the QVariant as a QList<QDBusObjectPath> type
1834- QDbusList var;
1835- QVariant inhibitors;
1836- inhibitors.setValue(var);
1837-
1838- // * Reboot action translates to the shutdown signal due to some weird idiosyncracy
1839- // in the indicator-session/Unity interaction. *
1840- QDBusReply<void> reply = dbusGnomeSessionWrapper.call("Open", (unsigned)Action::REBOOT, (unsigned)0, (unsigned)0, inhibitors);
1841- QCOMPARE(reply.isValid(), true);
1842-
1843- // Make sure we see the signal being emitted.
1844- QCOMPARE(spy.count(), 1);
1845- }
1846+ void testGnomeSessionWrapper_data() {
1847+ QTest::addColumn<uint>("method");
1848+ QTest::addColumn<QString>("signal");
1849+
1850+ QTest::newRow("Logout") << (uint)Action::LOGOUT << "LogoutRequested(bool)";
1851+ QTest::newRow("Shutdown") << (uint)Action::SHUTDOWN << "ShutdownRequested(bool)";
1852+ QTest::newRow("Reboot") << (uint)Action::REBOOT << "RebootRequested(bool)";
1853+ }
1854+
1855+ void testGnomeSessionWrapper() {
1856+ QFETCH(uint, method);
1857+ QFETCH(QString, signal);
1858+
1859+ DBusUnitySessionService dbusUnitySessionService;
1860+ QCoreApplication::processEvents(); // to let the service register on DBus
1861+
1862+ // Spy on the given signal on the /com/canonical/Unity/Session object
1863+ // as proof we are actually calling the actual method.
1864+ // .. because QSignalSpy checks the signal signature like this: "if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE)"
1865+ QSignalSpy spy(&dbusUnitySessionService, qPrintable(signal.prepend(QSIGNAL_CODE)));
1866+
1867+ DBusGnomeSessionManagerWrapper dbusGnomeSessionManagerWrapper;
1868+ QCoreApplication::processEvents(); // to let the service register on DBus
1869+
1870+ QDBusInterface dbusGnomeSessionWrapper("com.canonical.Unity",
1871+ "/org/gnome/SessionManager/EndSessionDialog",
1872+ "org.gnome.SessionManager.EndSessionDialog",
1873+ QDBusConnection::sessionBus());
1874+
1875+ QCOMPARE(dbusGnomeSessionWrapper.isValid(), true);
1876+
1877+ // Set the QVariant as a QList<QDBusObjectPath> type
1878+ QDbusList var;
1879+ QVariant inhibitors;
1880+ inhibitors.setValue(var);
1881+
1882+ QDBusReply<void> reply = dbusGnomeSessionWrapper.call("Open", method, (unsigned)0, (unsigned)0, inhibitors);
1883+ QCOMPARE(reply.isValid(), true);
1884+
1885+ // Make sure we see the signal being emitted.
1886+ QCOMPARE(spy.count(), 1);
1887+ }
1888+
1889+ void testUserName() {
1890+ DBusUnitySessionService dbusUnitySessionService;
1891+ QCoreApplication::processEvents(); // to let the service register on DBus
1892+
1893+ QCOMPARE(dbusUnitySessionService.UserName(), QString::fromUtf8(qgetenv("USER")));
1894+ }
1895+
1896+ void testRealName() {
1897+ DBusUnitySessionService dbusUnitySessionService;
1898+ QCoreApplication::processEvents(); // to let the service register on DBus
1899+
1900+ QDBusInterface accIface("org.freedesktop.Accounts", "/org/freedesktop/Accounts", "org.freedesktop.Accounts", QDBusConnection::systemBus());
1901+ QVERIFY(accIface.isValid());
1902+ QDBusReply<QDBusObjectPath> userPath = accIface.asyncCall("FindUserById", static_cast<qint64>(geteuid()));
1903+ if (!userPath.isValid()) {
1904+ QFAIL("Could not get user path in Account Service");
1905+ }
1906+
1907+ QDBusInterface userAccIface("org.freedesktop.Accounts", userPath.value().path(), "org.freedesktop.Accounts.User", QDBusConnection::systemBus());
1908+ QCOMPARE(dbusUnitySessionService.RealName(), userAccIface.property("RealName").toString());
1909+ }
1910+
1911+ void testLogin1Capabilities() {
1912+ DBusUnitySessionService dbusUnitySessionService;
1913+ QDBusInterface login1face("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
1914+ QCoreApplication::processEvents(); // to let the services register on DBus
1915+
1916+ QCOMPARE(dbusUnitySessionService.CanHibernate(), (login1face.call("CanHibernate").arguments().first().toString() != "no"));
1917+ QCOMPARE(dbusUnitySessionService.CanSuspend(), (login1face.call("CanSuspend").arguments().first().toString() != "no"));
1918+ QCOMPARE(dbusUnitySessionService.CanReboot(), (login1face.call("CanReboot").arguments().first().toString() != "no"));
1919+ QCOMPARE(dbusUnitySessionService.CanShutdown(), (login1face.call("CanPowerOff").arguments().first().toString() != "no"));
1920+ QCOMPARE(dbusUnitySessionService.CanHybridSleep(), (login1face.call("CanHybridSleep").arguments().first().toString() != "no"));
1921+ }
1922+
1923+// void testLock() {
1924+// DBusUnitySessionService dbusUnitySessionService;
1925+// DBusScreensaverWrapper saverIface;
1926+// QDBusInterface saverCompatIface("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", QDBusConnection::sessionBus());
1927+// QSignalSpy spy(&saverIface, &DBusScreensaverWrapper::ActiveChanged);
1928+// QCoreApplication::processEvents(); // to let the service register on DBus
1929+
1930+// QTRY_COMPARE(saverCompatIface.isValid(), true);
1931+
1932+// qDebug() << "Locking up...";
1933+// dbusUnitySessionService.Lock();
1934+
1935+// QTRY_COMPARE(spy.count(), 1);
1936+// QList<QVariant> arguments = spy.takeFirst(); // take the first signal
1937+// QVERIFY(arguments.at(0).toBool() == true); // verify the first argument
1938+
1939+// // verify the session is locked
1940+// QCOMPARE(saverIface.GetActive(), true);
1941+
1942+// sleep(5);
1943+// qDebug() << "Screensaver has been active for" << saverIface.GetActiveTime() << "seconds";
1944+// qDebug() << "Session has been idle for" << saverIface.GetSessionIdleTime() << "seconds";
1945+// }
1946
1947 private:
1948 QDBusInterface *dbusUnitySession;

Subscribers

People subscribed via source and target branches