Lomiri
dbuslomirisessionservice.cpp
1 /*
2  * Copyright (C) 2014, 2015 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License version 3, as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10  * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 // local
18 #include "dbuslomirisessionservice.h"
19 
20 // system
21 #include <grp.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <pwd.h>
25 
26 // Qt
27 #include <QDebug>
28 #include <QDBusPendingCall>
29 #include <QDBusReply>
30 #include <QElapsedTimer>
31 #include <QDateTime>
32 #include <QDBusUnixFileDescriptor>
33 
34 // Glib
35 #include <glib.h>
36 
37 #define LOGIN1_SERVICE QStringLiteral("org.freedesktop.login1")
38 #define LOGIN1_PATH QStringLiteral("/org/freedesktop/login1")
39 #define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
40 #define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
41 
42 #define ACTIVE_KEY QStringLiteral("Active")
43 #define IDLE_SINCE_KEY QStringLiteral("IdleSinceHint")
44 
45 // TODO: migrate defines to constant variables in the future.
46 static const QString LOGIN1_USER_SELF_PATH =
47  QStringLiteral("/org/freedesktop/login1/user/self");
48 static const QString LOGIN1_USER_IFACE =
49  QStringLiteral("org.freedesktop.login1.User");
50 static const QString DBUS_PROPERTIES_IFACE =
51  QStringLiteral("org.freedesktop.DBus.Properties");
52 
53 static const QString DISPLAY_KEY = QStringLiteral("Display");
54 
55 class DBusLomiriSessionServicePrivate: public QObject
56 {
57  Q_OBJECT
58 public:
59  QString logindSessionPath;
60  bool isSessionActive = true;
61  QElapsedTimer screensaverActiveTimer;
62  QDBusUnixFileDescriptor m_systemdInhibitFd;
63 
64  DBusLomiriSessionServicePrivate(): QObject() {
65  init();
66  checkActive();
67  }
68 
69  QString determineLogindSessionPath() {
70  // Simple case: environment variable.
71  auto sessionEnv = qgetenv("XDG_SESSION_ID");
72  if (!sessionEnv.isEmpty()) {
73  QDBusMessage msg = QDBusMessage::createMethodCall(
74  LOGIN1_SERVICE,
75  LOGIN1_PATH,
76  LOGIN1_IFACE,
77  QStringLiteral("GetSession"));
78  // Can't use QByteArray as-is; QDbus will interpret it as 'ay'
79  msg << QString::fromLocal8Bit(sessionEnv);
80  QDBusReply<QDBusObjectPath> reply = QDBusConnection::SM_BUSNAME().call(msg);
81 
82  if (reply.isValid()) {
83  return reply.value().path();
84  } else {
85  qWarning() << "Failed to get logind session path for"
86  << sessionEnv << ":"
87  << reply.error().message();
88  }
89  }
90 
91  // We're not under the session. If we're running as a systemd user unit,
92  // use the user's Display session, which is what gnome-shell does.
93  // Care must be taken to check if this is actually the case, otherwise
94  // any invocation of Lomiri will become session-like.
95 
96  if (qEnvironmentVariableIsSet("LOMIRI_AS_SYSTEMD_UNIT")) {
97  QDBusMessage msg = QDBusMessage::createMethodCall(
98  LOGIN1_SERVICE,
99  LOGIN1_USER_SELF_PATH,
100  DBUS_PROPERTIES_IFACE,
101  QStringLiteral("Get"));
102  msg << LOGIN1_USER_IFACE;
103  msg << DISPLAY_KEY;
104 
105  // org.freedesktop.DBus.Properties.Get returns DBus variant.
106  QDBusReply<QDBusVariant> reply = QDBusConnection::SM_BUSNAME().call(msg);
107 
108  if (reply.isValid()) {
109  // We're the only callsite, so it's not worth writing full
110  // C++ struct (un-)marshaling. Let's just un-marshall here.
111  QString sessionName;
112  QDBusObjectPath sessionPath;
113 
114  QVariant variant = reply.value().variant();
115  const QDBusArgument arg = variant.value<QDBusArgument>();
116 
117  arg.beginStructure();
118  arg >> sessionName >> sessionPath;
119  arg.endStructure();
120 
121  return sessionPath.path();
122  } else {
123  qWarning() << "Failed to get user's Display session:"
124  << reply.error().message();
125  }
126  }
127 
128  // Can't find anything, return empty QString.
129  return QString();
130  }
131 
132  void init()
133  {
134  // get our logind session path
135  logindSessionPath = determineLogindSessionPath();
136 
137  if (!logindSessionPath.isEmpty()) {
138  // start watching the Active property
139  QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, logindSessionPath, QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("PropertiesChanged"),
140  this, SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
141 
142  setupSystemdInhibition();
143 
144  // re-enable the inhibition upon resume from sleep
145  QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, QStringLiteral("PrepareForSleep"),
146  this, SLOT(onResuming(bool)));
147  }
148  }
149 
150  void setupSystemdInhibition()
151  {
152  if (m_systemdInhibitFd.isValid())
153  return;
154 
155  // inhibit systemd handling of power/sleep/hibernate buttons
156  // http://www.freedesktop.org/wiki/Software/systemd/inhibit
157 
158  QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, QStringLiteral("Inhibit"));
159  msg << "handle-power-key:handle-suspend-key:handle-hibernate-key"; // what
160  msg << "Lomiri"; // who
161  msg << "Lomiri handles power events"; // why
162  msg << "block"; // mode
163 
164  QDBusPendingCall pendingCall = QDBusConnection::SM_BUSNAME().asyncCall(msg);
165  QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
166  connect(watcher, &QDBusPendingCallWatcher::finished,
167  this, [this](QDBusPendingCallWatcher* watcher) {
168  QDBusPendingReply<QDBusUnixFileDescriptor> reply = *watcher;
169  watcher->deleteLater();
170  if (reply.isError()) {
171  qWarning() << "Failed to inhibit systemd powersave handling" << reply.error().message();
172  return;
173  }
174 
175  m_systemdInhibitFd = reply.value();
176  });
177  }
178 
179  bool checkLogin1Call(const QString &method) const
180  {
181  QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
182  QDBusReply<QString> reply = QDBusConnection::SM_BUSNAME().call(msg);
183  return reply.isValid() && (reply == QStringLiteral("yes") || reply == QStringLiteral("challenge"));
184  }
185 
186  void makeLogin1Call(const QString &method, const QVariantList &args)
187  {
188  QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
189  LOGIN1_PATH,
190  LOGIN1_IFACE,
191  method);
192  msg.setArguments(args);
193  QDBusConnection::SM_BUSNAME().asyncCall(msg);
194  }
195 
196  void setActive(bool active)
197  {
198  isSessionActive = active;
199 
200  Q_EMIT screensaverActiveChanged(!isSessionActive);
201 
202  if (isSessionActive) {
203  screensaverActiveTimer.invalidate();
204  setIdleHint(false);
205  } else {
206  screensaverActiveTimer.start();
207  setIdleHint(true);
208  }
209  }
210 
211  void checkActive()
212  {
213  if (logindSessionPath.isEmpty()) {
214  qWarning() << "Invalid session path";
215  return;
216  }
217 
218  QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
219  logindSessionPath,
220  QStringLiteral("org.freedesktop.DBus.Properties"),
221  QStringLiteral("Get"));
222  msg << LOGIN1_SESSION_IFACE;
223  msg << ACTIVE_KEY;
224 
225  QDBusPendingCall pendingCall = QDBusConnection::SM_BUSNAME().asyncCall(msg);
226  QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
227  connect(watcher, &QDBusPendingCallWatcher::finished,
228  this, [this](QDBusPendingCallWatcher* watcher) {
229 
230  QDBusPendingReply<QVariant> reply = *watcher;
231  watcher->deleteLater();
232  if (reply.isError()) {
233  qWarning() << "Failed to get Active property" << reply.error().message();
234  return;
235  }
236 
237  setActive(reply.value().toBool());
238  });
239  }
240 
241  quint32 screensaverActiveTime() const
242  {
243  if (!isSessionActive && screensaverActiveTimer.isValid()) {
244  return screensaverActiveTimer.elapsed() / 1000;
245  }
246 
247  return 0;
248  }
249 
250  quint64 idleSinceUSecTimestamp() const
251  {
252  QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
253  logindSessionPath,
254  QStringLiteral("org.freedesktop.DBus.Properties"),
255  QStringLiteral("Get"));
256  msg << LOGIN1_SESSION_IFACE;
257  msg << IDLE_SINCE_KEY;
258 
259  QDBusReply<QVariant> reply = QDBusConnection::SM_BUSNAME().call(msg);
260  if (reply.isValid()) {
261  return reply.value().value<quint64>();
262  } else {
263  qWarning() << "Failed to get IdleSinceHint property" << reply.error().message();
264  }
265 
266  return 0;
267  }
268 
269  void setIdleHint(bool idle)
270  {
271  QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
272  logindSessionPath,
273  LOGIN1_SESSION_IFACE,
274  QStringLiteral("SetIdleHint"));
275  msg << idle;
276  QDBusConnection::SM_BUSNAME().asyncCall(msg);
277  }
278 
279  bool isUserInGroup(const QString &user, const QString &groupName) const
280  {
281  auto group = getgrnam(groupName.toUtf8().data());
282 
283  if (group && group->gr_mem)
284  {
285  for (int i = 0; group->gr_mem[i]; ++i)
286  {
287  if (g_strcmp0(group->gr_mem[i], user.toUtf8().data()) == 0) {
288  return true;
289  }
290  }
291  }
292 
293  return false;
294  }
295 
296 private Q_SLOTS:
297  void onPropertiesChanged(const QString &iface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
298  {
299  Q_UNUSED(iface)
300 
301  if (changedProps.contains(ACTIVE_KEY)) {
302  setActive(changedProps.value(ACTIVE_KEY).toBool());
303  } else if (invalidatedProps.contains(ACTIVE_KEY)) {
304  checkActive();
305  }
306  }
307 
308  void onResuming(bool active)
309  {
310  if (!active) {
311  setupSystemdInhibition();
312  } else {
313  Q_EMIT prepareForSleep();
314  }
315  }
316 
317 Q_SIGNALS:
318  void screensaverActiveChanged(bool active);
319  void prepareForSleep();
320 };
321 
322 Q_GLOBAL_STATIC(DBusLomiriSessionServicePrivate, d)
323 
324 DBusLomiriSessionService::DBusLomiriSessionService()
325  : LomiriDBusObject(QStringLiteral("/com/lomiri/Shell/Session"), QStringLiteral("com.lomiri.Shell"))
326 {
327  if (!d->logindSessionPath.isEmpty()) {
328  // connect our PromptLock() slot to the logind's session Lock() signal
329  QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, QStringLiteral("Lock"), this, SLOT(PromptLock()));
330  // ... and our Unlocked() signal to the logind's session Unlock() signal
331  // (lightdm handles the unlocking by calling logind's Unlock method which in turn emits this signal we connect to)
332  QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, QStringLiteral("Unlock"), this, SLOT(doUnlock()));
333  connect(d, &DBusLomiriSessionServicePrivate::prepareForSleep, this, &DBusLomiriSessionService::PromptLock);
334  } else {
335  qWarning() << "Failed to connect to logind's session Lock/Unlock signals";
336  }
337 }
338 
340 {
341  // TODO ask the apps to quit and then emit the signal
342  Q_EMIT LogoutReady();
343  Q_EMIT logoutReady();
344 }
345 
347 {
348  const QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("com.lomiri.Upstart"),
349  QStringLiteral("/com/lomiri/Upstart"),
350  QStringLiteral("com.lomiri.Upstart0_6"),
351  QStringLiteral("EndSession"));
352  QDBusConnection::sessionBus().asyncCall(msg);
353 }
354 
356 {
357  return d->checkLogin1Call(QStringLiteral("CanHibernate"));
358 }
359 
361 {
362  return d->checkLogin1Call(QStringLiteral("CanSuspend"));
363 }
364 
366 {
367  return d->checkLogin1Call(QStringLiteral("CanHybridSleep"));
368 }
369 
371 {
372  return d->checkLogin1Call(QStringLiteral("CanReboot"));
373 }
374 
376 {
377  return d->checkLogin1Call(QStringLiteral("CanPowerOff"));
378 }
379 
381 {
382  auto user = UserName();
383  if (user.startsWith(QStringLiteral("guest-")) ||
384  d->isUserInGroup(user, QStringLiteral("nopasswdlogin"))) {
385  return false;
386  } else {
387  return true;
388  }
389 }
390 
392 {
393  return QString::fromUtf8(g_get_user_name());
394 }
395 
397 {
398  struct passwd *p = getpwuid(geteuid());
399  if (p) {
400  const QString gecos = QString::fromLocal8Bit(p->pw_gecos);
401  if (!gecos.isEmpty()) {
402  const QStringList splitGecos = gecos.split(QLatin1Char(','));
403  return splitGecos.first();
404  }
405  }
406 
407  return QString();
408 }
409 
411 {
412  char hostName[512];
413  if (gethostname(hostName, sizeof(hostName)) == -1) {
414  qWarning() << "Could not determine local hostname";
415  return QString();
416  }
417  hostName[sizeof(hostName) - 1] = '\0';
418  return QString::fromLocal8Bit(hostName);
419 }
420 
422 {
423  // Prompt as in quick. No locking animation needed. Usually used by
424  // indicator-session in combination with a switch to greeter or other
425  // user session.
426  if (CanLock()) {
427  Q_EMIT LockRequested();
428  Q_EMIT lockRequested();
429  }
430 }
431 
433 {
434  // Normal lock (with animation, as compared to PromptLock above). Usually
435  // used by indicator-session to lock the session in place.
436  //
437  // FIXME: We also -- as a bit of a hack around indicator-session not fully
438  // supporting a phone profile -- switch to greeter here. The lomiri7 flow is
439  // that the user chooses "Lock/Switch" from the indicator, and then can go
440  // to greeter by selecting "Switch" again from the indicator, which is now
441  // exposed by the desktop_lockscreen profile. But since in lomiri, we try
442  // to expose most things all the time, we don't use the separate lockscreen
443  // profile. Instead, we just go directly to the greeter the first time
444  // a user presses "Lock/Switch". This isn't what this DBus call is
445  // supposed to do, but we can live with it for now.
446  //
447  // Here's a bug about indicator-session growing a converged Touch profile:
448  // https://launchpad.net/bugs/1557716
449  //
450  // We only do this here in the animated-lock call because that's the only
451  // time the indicator locks without also asking the display manager to
452  // switch sessions on us. And since we are switching screens, we also
453  // don't bother respecting the animate request, simply doing a PromptLock.
454  PromptLock();
455  switchToGreeter();
456 }
457 
458 void DBusLomiriSessionService::switchToGreeter()
459 {
460  // lock the session using the org.freedesktop.DisplayManager system DBUS service
461  const QString sessionPath = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
462  QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DisplayManager"),
463  sessionPath,
464  QStringLiteral("org.freedesktop.DisplayManager.Session"),
465  QStringLiteral("Lock"));
466 
467  QDBusPendingCall pendingCall = QDBusConnection::SM_BUSNAME().asyncCall(msg);
468  QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
469  connect(watcher, &QDBusPendingCallWatcher::finished,
470  this, [this](QDBusPendingCallWatcher* watcher) {
471 
472  QDBusPendingReply<void> reply = *watcher;
473  watcher->deleteLater();
474  if (reply.isError()) {
475  qWarning() << "Lock call failed" << reply.error().message();
476  return;
477  }
478 
479  // emit Locked when the call succeeds
480  Q_EMIT Locked();
481  });
482 }
483 
484 void DBusLomiriSessionService::doUnlock()
485 {
486  Q_EMIT Unlocked();
487  Q_EMIT unlocked();
488 }
489 
491 {
492  return !d->isSessionActive;
493 }
494 
496 {
497  Q_EMIT LogoutRequested(false);
498  Q_EMIT logoutRequested(false);
499 }
500 
502 {
503  d->makeLogin1Call(QStringLiteral("Reboot"), {false});
504 }
505 
507 {
508  Q_EMIT RebootRequested(false);
509  Q_EMIT rebootRequested(false);
510 }
511 
513 {
514  d->makeLogin1Call(QStringLiteral("PowerOff"), {false});
515 }
516 
518 {
519  PromptLock();
520  d->makeLogin1Call(QStringLiteral("Suspend"), {false});
521 }
522 
524 {
525  PromptLock();
526  d->makeLogin1Call(QStringLiteral("Hibernate"), {false});
527 }
528 
530 {
531  PromptLock();
532  d->makeLogin1Call(QStringLiteral("HybridSleep"), {false});
533 }
534 
536 {
537  Q_EMIT ShutdownRequested(false);
538  Q_EMIT shutdownRequested(false);
539 }
540 
541 enum class Action : unsigned
542 {
543  LOGOUT = 0,
544  SHUTDOWN,
545  REBOOT,
546  NONE
547 };
548 
549 
550 void performAsyncLomiriCall(const QString &method)
551 {
552  const QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("com.lomiri.Shell"),
553  QStringLiteral("/com/lomiri/Shell/Session"),
554  QStringLiteral("com.lomiri.Shell.Session"),
555  method);
556  QDBusConnection::sessionBus().asyncCall(msg);
557 }
558 
559 
560 DBusGnomeSessionManagerWrapper::DBusGnomeSessionManagerWrapper()
561  : LomiriDBusObject(QStringLiteral("/org/gnome/SessionManager"), QStringLiteral("org.gnome.SessionManager"))
562 {
563 }
564 
565 void DBusGnomeSessionManagerWrapper::Logout(quint32 mode)
566 {
567  auto call = QStringLiteral("RequestLogout");
568 
569  // These modes are documented as bitwise flags, not an enum, even though
570  // they only ever seem to be used as enums.
571 
572  if (mode & 1) // without dialog
573  call = QStringLiteral("Logout");
574  if (mode & 2) // without dialog, ignoring inhibitors (which we don't have)
575  call = QStringLiteral("Logout");
576 
577  performAsyncLomiriCall(call);
578 }
579 
580 void DBusGnomeSessionManagerWrapper::Reboot()
581 {
582  // GNOME's Reboot means with dialog (they use Request differently than us).
583  performAsyncLomiriCall(QStringLiteral("RequestReboot"));
584 }
585 
586 void DBusGnomeSessionManagerWrapper::RequestReboot()
587 {
588  // GNOME's RequestReboot means no dialog (they use Request differently than us).
589  performAsyncLomiriCall(QStringLiteral("Reboot"));
590 }
591 
592 void DBusGnomeSessionManagerWrapper::RequestShutdown()
593 {
594  // GNOME's RequestShutdown means no dialog (they use Request differently than us).
595  performAsyncLomiriCall(QStringLiteral("Shutdown"));
596 }
597 
598 void DBusGnomeSessionManagerWrapper::Shutdown()
599 {
600  // GNOME's Shutdown means with dialog (they use Request differently than us).
601  performAsyncLomiriCall(QStringLiteral("RequestShutdown"));
602 }
603 
604 
605 DBusGnomeSessionManagerDialogWrapper::DBusGnomeSessionManagerDialogWrapper()
606  : LomiriDBusObject(QStringLiteral("/org/gnome/SessionManager/EndSessionDialog"), QStringLiteral("com.lomiri.Shell"))
607 {
608 }
609 
610 void DBusGnomeSessionManagerDialogWrapper::Open(const unsigned type, const unsigned arg_1, const unsigned max_wait, const QList<QDBusObjectPath> &inhibitors)
611 {
612  Q_UNUSED(arg_1);
613  Q_UNUSED(max_wait);
614  Q_UNUSED(inhibitors);
615 
616  switch (static_cast<Action>(type))
617  {
618  case Action::LOGOUT:
619  performAsyncLomiriCall(QStringLiteral("RequestLogout"));
620  break;
621 
622  case Action::REBOOT:
623  performAsyncLomiriCall(QStringLiteral("RequestReboot"));
624  break;
625 
626  case Action::SHUTDOWN:
627  performAsyncLomiriCall(QStringLiteral("RequestShutdown"));
628  break;
629 
630  default:
631  break;
632  }
633 }
634 
635 
636 DBusGnomeScreensaverWrapper::DBusGnomeScreensaverWrapper()
637  : LomiriDBusObject(QStringLiteral("/org/gnome/ScreenSaver"), QStringLiteral("org.gnome.ScreenSaver"))
638 {
639  connect(d, &DBusLomiriSessionServicePrivate::screensaverActiveChanged, this, &DBusGnomeScreensaverWrapper::ActiveChanged);
640 }
641 
642 bool DBusGnomeScreensaverWrapper::GetActive() const
643 {
644  return !d->isSessionActive; // return whether the session is not active
645 }
646 
647 void DBusGnomeScreensaverWrapper::SetActive(bool lock)
648 {
649  if (lock) {
650  Lock();
651  }
652 }
653 
654 void DBusGnomeScreensaverWrapper::Lock()
655 {
656  performAsyncLomiriCall(QStringLiteral("PromptLock"));
657 }
658 
659 quint32 DBusGnomeScreensaverWrapper::GetActiveTime() const
660 {
661  return d->screensaverActiveTime();
662 }
663 
664 void DBusGnomeScreensaverWrapper::SimulateUserActivity()
665 {
666  d->setIdleHint(false);
667 }
668 
669 
670 DBusScreensaverWrapper::DBusScreensaverWrapper()
671  : LomiriDBusObject(QStringLiteral("/org/freedesktop/ScreenSaver"), QStringLiteral("org.freedesktop.ScreenSaver"))
672 {
673  QDBusConnection::sessionBus().registerObject(QStringLiteral("/ScreenSaver"), this, QDBusConnection::ExportScriptableContents); // compat path, also register here
674  connect(d, &DBusLomiriSessionServicePrivate::screensaverActiveChanged, this, &DBusScreensaverWrapper::ActiveChanged);
675 }
676 
677 bool DBusScreensaverWrapper::GetActive() const
678 {
679  return !d->isSessionActive; // return whether the session is not active
680 }
681 
682 bool DBusScreensaverWrapper::SetActive(bool lock)
683 {
684  if (lock) {
685  Lock();
686  return true;
687  }
688  return false;
689 }
690 
691 void DBusScreensaverWrapper::Lock()
692 {
693  performAsyncLomiriCall(QStringLiteral("PromptLock"));
694 }
695 
696 quint32 DBusScreensaverWrapper::GetActiveTime() const
697 {
698  return d->screensaverActiveTime();
699 }
700 
701 quint32 DBusScreensaverWrapper::GetSessionIdleTime() const
702 {
703  return QDateTime::fromMSecsSinceEpoch(d->idleSinceUSecTimestamp()/1000).secsTo(QDateTime::currentDateTime());
704 }
705 
706 void DBusScreensaverWrapper::SimulateUserActivity()
707 {
708  d->setIdleHint(false);
709 }
710 
711 #include "dbuslomirisessionservice.moc"
DBusLomiriSessionService::HostName
Q_SCRIPTABLE QString HostName() const
Definition: dbuslomirisessionservice.cpp:410
DBusLomiriSessionService::LogoutReady
Q_SCRIPTABLE void LogoutReady()
DBusLomiriSessionService::Hibernate
Q_SCRIPTABLE void Hibernate()
Definition: dbuslomirisessionservice.cpp:523
DBusLomiriSessionService::EndSession
Q_SCRIPTABLE void EndSession()
Definition: dbuslomirisessionservice.cpp:346
DBusLomiriSessionService::UserName
Q_SCRIPTABLE QString UserName() const
Definition: dbuslomirisessionservice.cpp:391
DBusLomiriSessionService::Lock
Q_SCRIPTABLE void Lock()
Definition: dbuslomirisessionservice.cpp:432
DBusLomiriSessionService::Unlocked
Q_SCRIPTABLE void Unlocked()
DBusLomiriSessionService::Logout
Q_SCRIPTABLE void Logout()
Definition: dbuslomirisessionservice.cpp:339
DBusLomiriSessionService::CanLock
Q_SCRIPTABLE bool CanLock() const
Definition: dbuslomirisessionservice.cpp:380
DBusLomiriSessionService::CanHibernate
Q_SCRIPTABLE bool CanHibernate() const
Definition: dbuslomirisessionservice.cpp:355
DBusLomiriSessionService::RequestLogout
Q_SCRIPTABLE void RequestLogout()
Definition: dbuslomirisessionservice.cpp:495
DBusLomiriSessionService::PromptLock
Q_SCRIPTABLE void PromptLock()
Definition: dbuslomirisessionservice.cpp:421
DBusLomiriSessionService::LockRequested
Q_SCRIPTABLE void LockRequested()
DBusLomiriSessionService::Suspend
Q_SCRIPTABLE void Suspend()
Definition: dbuslomirisessionservice.cpp:517
DBusLomiriSessionService::CanSuspend
Q_SCRIPTABLE bool CanSuspend() const
Definition: dbuslomirisessionservice.cpp:360
DBusLomiriSessionService::Reboot
Q_SCRIPTABLE void Reboot()
Definition: dbuslomirisessionservice.cpp:501
DBusLomiriSessionService::CanShutdown
Q_SCRIPTABLE bool CanShutdown() const
Definition: dbuslomirisessionservice.cpp:375
DBusLomiriSessionService::HybridSleep
Q_SCRIPTABLE void HybridSleep()
Definition: dbuslomirisessionservice.cpp:529
DBusLomiriSessionService::Shutdown
Q_SCRIPTABLE void Shutdown()
Definition: dbuslomirisessionservice.cpp:512
DBusLomiriSessionService::CanReboot
Q_SCRIPTABLE bool CanReboot() const
Definition: dbuslomirisessionservice.cpp:370
DBusLomiriSessionService::RequestReboot
Q_SCRIPTABLE void RequestReboot()
Definition: dbuslomirisessionservice.cpp:506
DBusLomiriSessionService::Locked
Q_SCRIPTABLE void Locked()
DBusLomiriSessionService::RebootRequested
Q_SCRIPTABLE void RebootRequested(bool have_inhibitors)
DBusLomiriSessionService::ShutdownRequested
Q_SCRIPTABLE void ShutdownRequested(bool have_inhibitors)
DBusLomiriSessionService::RequestShutdown
Q_SCRIPTABLE void RequestShutdown()
Definition: dbuslomirisessionservice.cpp:535
DBusLomiriSessionService::RealName
Q_SCRIPTABLE QString RealName() const
Definition: dbuslomirisessionservice.cpp:396
DBusLomiriSessionService::IsLocked
Q_SCRIPTABLE bool IsLocked() const
Definition: dbuslomirisessionservice.cpp:490
DBusLomiriSessionService::CanHybridSleep
Q_SCRIPTABLE bool CanHybridSleep() const
Definition: dbuslomirisessionservice.cpp:365
DBusLomiriSessionService::LogoutRequested
Q_SCRIPTABLE void LogoutRequested(bool have_inhibitors)