Suppress compiler warnings about unused function parameters
[lxde/liblxqt.git] / lxqtpower / lxqtpowerproviders.cpp
CommitLineData
b3678cfd
AS
1/* BEGIN_COMMON_COPYRIGHT_HEADER
2 * (c)LGPL2+
3 *
b9223fe7 4 * LXQt - a lightweight, Qt based, desktop toolset
b3678cfd
AS
5 * http://razor-qt.org
6 *
7 * Copyright: 2010-2011 Razor team
8 * Authors:
626f1f31 9 * Alexander Sokoloff <sokoloff.a@gmail.com>
c7351c0e 10 * Petr Vanek <petr@scribus.info>
b3678cfd
AS
11 *
12 * This program or library is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21
22 * You should have received a copy of the GNU Lesser General
23 * Public License along with this library; if not, write to the
24 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 * Boston, MA 02110-1301 USA
26 *
27 * END_COMMON_COPYRIGHT_HEADER */
28
29
8e6db58a 30#include "lxqtpowerproviders.h"
e6389bfc
HJYP
31#include <QDBusInterface>
32#include <QProcess>
33#include <QDebug>
0e4fbf35 34#include "lxqtnotification.h"
ce86ee51 35#include <signal.h> // for kill()
b3678cfd
AS
36
37#define UPOWER_SERVICE "org.freedesktop.UPower"
38#define UPOWER_PATH "/org/freedesktop/UPower"
39#define UPOWER_INTERFACE UPOWER_SERVICE
40
41#define CONSOLEKIT_SERVICE "org.freedesktop.ConsoleKit"
42#define CONSOLEKIT_PATH "/org/freedesktop/ConsoleKit/Manager"
43#define CONSOLEKIT_INTERFACE "org.freedesktop.ConsoleKit.Manager"
44
a5b5dc7a
AM
45#define SYSTEMD_SERVICE "org.freedesktop.login1"
46#define SYSTEMD_PATH "/org/freedesktop/login1"
47#define SYSTEMD_INTERFACE "org.freedesktop.login1.Manager"
48
db4aaddf 49#define LXQT_SERVICE "org.lxqt.session"
f05ba5af 50#define LXQT_PATH "/LXQtSession"
db4aaddf 51#define LXQT_INTERFACE "org.lxqt.session"
b3678cfd 52
b3678cfd
AS
53#define PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
54
f05ba5af 55using namespace LXQt;
b3678cfd
AS
56
57/************************************************
58 Helper func
59 ************************************************/
60void printDBusMsg(const QDBusMessage &msg)
61{
62 qWarning() << "** Dbus error **************************";
63 qWarning() << "Error name " << msg.errorName();
64 qWarning() << "Error msg " << msg.errorMessage();
65 qWarning() << "****************************************";
66}
67
68
69/************************************************
70 Helper func
71 ************************************************/
dabae7a2 72static bool dbusCall(const QString &service,
b3678cfd
AS
73 const QString &path,
74 const QString &interface,
75 const QDBusConnection &connection,
a9c02a1b 76 const QString & method,
8e6db58a 77 PowerProvider::DbusErrorCheck errorCheck = PowerProvider::CheckDBUS
b3678cfd
AS
78 )
79{
80 QDBusInterface dbus(service, path, interface, connection);
81 if (!dbus.isValid())
c7351c0e 82 {
83 qWarning() << "dbusCall: QDBusInterface is invalid" << service << path << interface << method;
8e6db58a 84 if (errorCheck == PowerProvider::CheckDBUS)
a9c02a1b 85 {
0e4fbf35 86 Notification::notify(
a9c02a1b 87 QObject::tr("Power Manager Error"),
1693d610 88 QObject::tr("QDBusInterface is invalid")+ "\n\n" + service + " " + path + " " + interface + " " + method,
db4aaddf 89 "lxqt-logo.png");
a9c02a1b 90 }
b3678cfd 91 return false;
c7351c0e 92 }
b3678cfd
AS
93
94 QDBusMessage msg = dbus.call(method);
95
96 if (!msg.errorName().isEmpty())
44311613 97 {
b3678cfd 98 printDBusMsg(msg);
8e6db58a 99 if (errorCheck == PowerProvider::CheckDBUS)
a9c02a1b 100 {
0e4fbf35 101 Notification::notify(
a9c02a1b 102 QObject::tr("Power Manager Error (D-BUS call)"),
1693d610 103 msg.errorName() + "\n\n" + msg.errorMessage(),
db4aaddf 104 "lxqt-logo.png");
a9c02a1b 105 }
44311613 106 }
b3678cfd 107
5ea86b7a
AS
108 // If the method no returns value, we believe that it was successful.
109 return msg.arguments().isEmpty() ||
6fd34ba5 110 msg.arguments().first().isNull() ||
5ea86b7a 111 msg.arguments().first().toBool();
b3678cfd
AS
112}
113
a5b5dc7a
AM
114/************************************************
115 Helper func
116
117 Just like dbusCall(), except that systemd
118 returns a string instead of a bool, and it takes
119 an "interactivity boolean" as an argument.
120 ************************************************/
dabae7a2 121static bool dbusCallSystemd(const QString &service,
a5b5dc7a
AM
122 const QString &path,
123 const QString &interface,
124 const QDBusConnection &connection,
125 const QString &method,
dabae7a2 126 bool needBoolArg,
8e6db58a 127 PowerProvider::DbusErrorCheck errorCheck = PowerProvider::CheckDBUS
a5b5dc7a
AM
128 )
129{
130 QDBusInterface dbus(service, path, interface, connection);
131 if (!dbus.isValid())
132 {
133 qWarning() << "dbusCall: QDBusInterface is invalid" << service << path << interface << method;
8e6db58a 134 if (errorCheck == PowerProvider::CheckDBUS)
a5b5dc7a 135 {
0e4fbf35 136 Notification::notify(
a5b5dc7a
AM
137 QObject::tr("Power Manager Error"),
138 QObject::tr("QDBusInterface is invalid")+ "\n\n" + service + " " + path + " " + interface + " " + method,
db4aaddf 139 "lxqt-logo.png");
a5b5dc7a
AM
140 }
141 return false;
142 }
143
dabae7a2 144 QDBusMessage msg = dbus.call(method, needBoolArg ? QVariant(true) : QVariant());
a5b5dc7a
AM
145
146 if (!msg.errorName().isEmpty())
147 {
148 printDBusMsg(msg);
8e6db58a 149 if (errorCheck == PowerProvider::CheckDBUS)
a5b5dc7a 150 {
0e4fbf35 151 Notification::notify(
a5b5dc7a
AM
152 QObject::tr("Power Manager Error (D-BUS call)"),
153 msg.errorName() + "\n\n" + msg.errorMessage(),
db4aaddf 154 "lxqt-logo.png");
a5b5dc7a
AM
155 }
156 }
157
158 // If the method no returns value, we believe that it was successful.
6fd34ba5 159 if (msg.arguments().isEmpty() || msg.arguments().first().isNull())
a5b5dc7a
AM
160 return true;
161
162 QString response = msg.arguments().first().toString();
163 qDebug() << "systemd:" << method << "=" << response;
164 return response == "yes" || response == "challenge";
165}
166
b3678cfd
AS
167
168/************************************************
169 Helper func
170 ************************************************/
171bool dbusGetProperty(const QString &service,
172 const QString &path,
173 const QString &interface,
174 const QDBusConnection &connection,
175 const QString & property
176 )
177{
178 QDBusInterface dbus(service, path, interface, connection);
179 if (!dbus.isValid())
c7351c0e 180 {
181 qWarning() << "dbusGetProperty: QDBusInterface is invalid" << service << path << interface << property;
f05ba5af 182// Notification::notify(QObject::tr("LXQt Power Manager"),
db4aaddf 183// "lxqt-logo.png",
a9c02a1b 184// QObject::tr("Power Manager Error"),
1693d610 185// QObject::tr("QDBusInterface is invalid")+ "\n\n" + service +" " + path +" " + interface +" " + property);
44311613 186
b3678cfd 187 return false;
c7351c0e 188 }
b3678cfd
AS
189
190 QDBusMessage msg = dbus.call("Get", dbus.interface(), property);
191
192 if (!msg.errorName().isEmpty())
44311613 193 {
b3678cfd 194 printDBusMsg(msg);
f05ba5af 195// Notification::notify(QObject::tr("LXQt Power Manager"),
db4aaddf 196// "lxqt-logo.png",
a9c02a1b 197// QObject::tr("Power Manager Error (Get Property)"),
1693d610 198// msg.errorName() + "\n\n" + msg.errorMessage());
44311613 199 }
b3678cfd
AS
200
201 return !msg.arguments().isEmpty() &&
202 msg.arguments().first().value<QDBusVariant>().variant().toBool();
203}
204
205
206
207
208/************************************************
8e6db58a 209 PowerProvider
b3678cfd 210 ************************************************/
8e6db58a 211PowerProvider::PowerProvider(QObject *parent):
b3678cfd
AS
212 QObject(parent)
213{
214}
215
216
8e6db58a 217PowerProvider::~PowerProvider()
b3678cfd
AS
218{
219}
220
221
222
223/************************************************
224 UPowerProvider
225 ************************************************/
226UPowerProvider::UPowerProvider(QObject *parent):
8e6db58a 227 PowerProvider(parent)
b3678cfd
AS
228{
229}
230
231
232UPowerProvider::~UPowerProvider()
233{
234}
235
236
8e6db58a 237bool UPowerProvider::canAction(Power::Action action) const
b3678cfd
AS
238{
239 QString command;
240 QString property;
241 switch (action)
242 {
8e6db58a 243 case Power::PowerHibernate:
b3678cfd
AS
244 property = "CanHibernate";
245 command = "HibernateAllowed";
246 break;
247
8e6db58a 248 case Power::PowerSuspend:
b3678cfd
AS
249 property = "CanSuspend";
250 command = "SuspendAllowed";
251 break;
252
253 default:
254 return false;
255 }
256
257 return dbusGetProperty( // Whether the system is able to hibernate.
258 UPOWER_SERVICE,
259 UPOWER_PATH,
260 PROPERTIES_INTERFACE,
261 QDBusConnection::systemBus(),
262 property
263 )
264 &&
265 dbusCall( // Check if the caller has (or can get) the PolicyKit privilege to call command.
266 UPOWER_SERVICE,
267 UPOWER_PATH,
268 UPOWER_INTERFACE,
269 QDBusConnection::systemBus(),
731cfd19
PV
270 command,
271 // canAction should be always silent because it can freeze
272 // g_main_context_iteration Qt event loop in QMessageBox
273 // on panel startup if there is no DBUS running.
8e6db58a 274 PowerProvider::DontCheckDBUS
b3678cfd
AS
275 );
276}
277
278
8e6db58a 279bool UPowerProvider::doAction(Power::Action action)
b3678cfd
AS
280{
281 QString command;
282
283 switch (action)
284 {
8e6db58a 285 case Power::PowerHibernate:
b3678cfd
AS
286 command = "Hibernate";
287 break;
288
8e6db58a 289 case Power::PowerSuspend:
b3678cfd
AS
290 command = "Suspend";
291 break;
292
293 default:
5ea86b7a 294 return false;
b3678cfd
AS
295 }
296
5ea86b7a
AS
297
298 return dbusCall(UPOWER_SERVICE,
b3678cfd
AS
299 UPOWER_PATH,
300 UPOWER_INTERFACE,
301 QDBusConnection::systemBus(),
302 command );
303}
304
305
306
307/************************************************
308 ConsoleKitProvider
309 ************************************************/
310ConsoleKitProvider::ConsoleKitProvider(QObject *parent):
8e6db58a 311 PowerProvider(parent)
b3678cfd
AS
312{
313}
314
315
316ConsoleKitProvider::~ConsoleKitProvider()
317{
318}
319
320
8e6db58a 321bool ConsoleKitProvider::canAction(Power::Action action) const
b3678cfd
AS
322{
323 QString command;
b3678cfd
AS
324 switch (action)
325 {
8e6db58a 326 case Power::PowerReboot:
6246a14a 327 command = "CanReboot";
b3678cfd
AS
328 break;
329
8e6db58a 330 case Power::PowerShutdown:
6246a14a
TM
331 command = "CanPowerOff";
332 break;
333
334 case Power::PowerHibernate:
335 command = "CanHibernate";
336 break;
337
338 case Power::PowerSuspend:
339 command = "CanSuspend";
b3678cfd
AS
340 break;
341
342 default:
343 return false;
344 }
345
6246a14a 346 return dbusCallSystemd(CONSOLEKIT_SERVICE,
4c73a6f3
CS
347 CONSOLEKIT_PATH,
348 CONSOLEKIT_INTERFACE,
349 QDBusConnection::systemBus(),
350 command,
6246a14a 351 false,
4c73a6f3
CS
352 // canAction should be always silent because it can freeze
353 // g_main_context_iteration Qt event loop in QMessageBox
354 // on panel startup if there is no DBUS running.
355 PowerProvider::DontCheckDBUS
356 );
b3678cfd
AS
357}
358
359
8e6db58a 360bool ConsoleKitProvider::doAction(Power::Action action)
b3678cfd
AS
361{
362 QString command;
b3678cfd
AS
363 switch (action)
364 {
8e6db58a 365 case Power::PowerReboot:
6246a14a 366 command = "Reboot";
b3678cfd
AS
367 break;
368
8e6db58a 369 case Power::PowerShutdown:
6246a14a
TM
370 command = "PowerOff";
371 break;
372
373 case Power::PowerHibernate:
374 command = "Hibernate";
375 break;
376
377 case Power::PowerSuspend:
378 command = "Suspend";
b3678cfd
AS
379 break;
380
381 default:
5ea86b7a 382 return false;
b3678cfd
AS
383 }
384
6246a14a
TM
385 return dbusCallSystemd(CONSOLEKIT_SERVICE,
386 CONSOLEKIT_PATH,
387 CONSOLEKIT_INTERFACE,
388 QDBusConnection::systemBus(),
389 command,
390 true
391 );
b3678cfd
AS
392}
393
a5b5dc7a
AM
394/************************************************
395 SystemdProvider
396
397 http://www.freedesktop.org/wiki/Software/systemd/logind
398 ************************************************/
399
400SystemdProvider::SystemdProvider(QObject *parent):
8e6db58a 401 PowerProvider(parent)
a5b5dc7a
AM
402{
403}
404
405
406SystemdProvider::~SystemdProvider()
407{
408}
409
410
8e6db58a 411bool SystemdProvider::canAction(Power::Action action) const
a5b5dc7a
AM
412{
413 QString command;
414
415 switch (action)
416 {
8e6db58a 417 case Power::PowerReboot:
a5b5dc7a
AM
418 command = "CanReboot";
419 break;
420
8e6db58a 421 case Power::PowerShutdown:
a5b5dc7a
AM
422 command = "CanPowerOff";
423 break;
424
8e6db58a 425 case Power::PowerSuspend:
a5b5dc7a
AM
426 command = "CanSuspend";
427 break;
428
8e6db58a 429 case Power::PowerHibernate:
a5b5dc7a
AM
430 command = "CanHibernate";
431 break;
432
433 default:
434 return false;
435 }
436
437 return dbusCallSystemd(SYSTEMD_SERVICE,
438 SYSTEMD_PATH,
439 SYSTEMD_INTERFACE,
440 QDBusConnection::systemBus(),
441 command,
85965778 442 false,
a5b5dc7a
AM
443 // canAction should be always silent because it can freeze
444 // g_main_context_iteration Qt event loop in QMessageBox
445 // on panel startup if there is no DBUS running.
8e6db58a 446 PowerProvider::DontCheckDBUS
a5b5dc7a
AM
447 );
448}
449
450
8e6db58a 451bool SystemdProvider::doAction(Power::Action action)
a5b5dc7a
AM
452{
453 QString command;
454
455 switch (action)
456 {
8e6db58a 457 case Power::PowerReboot:
a5b5dc7a
AM
458 command = "Reboot";
459 break;
460
8e6db58a 461 case Power::PowerShutdown:
a5b5dc7a
AM
462 command = "PowerOff";
463 break;
464
8e6db58a 465 case Power::PowerSuspend:
a5b5dc7a
AM
466 command = "Suspend";
467 break;
468
8e6db58a 469 case Power::PowerHibernate:
a5b5dc7a
AM
470 command = "Hibernate";
471 break;
472
473 default:
474 return false;
475 }
476
477 return dbusCallSystemd(SYSTEMD_SERVICE,
478 SYSTEMD_PATH,
479 SYSTEMD_INTERFACE,
480 QDBusConnection::systemBus(),
dabae7a2 481 command,
85965778 482 true
a5b5dc7a
AM
483 );
484}
b3678cfd
AS
485
486
487/************************************************
f05ba5af 488 LXQtProvider
b3678cfd 489 ************************************************/
f05ba5af 490LXQtProvider::LXQtProvider(QObject *parent):
8e6db58a 491 PowerProvider(parent)
b3678cfd
AS
492{
493}
494
495
f05ba5af 496LXQtProvider::~LXQtProvider()
b3678cfd
AS
497{
498}
499
500
f05ba5af 501bool LXQtProvider::canAction(Power::Action action) const
b3678cfd 502{
c7351c0e 503 switch (action)
504 {
8e6db58a 505 case Power::PowerLogout:
c7351c0e 506 // there can be case when razo-session does not run
db4aaddf 507 return dbusCall(LXQT_SERVICE, LXQT_PATH, LXQT_SERVICE,
731cfd19 508 QDBusConnection::sessionBus(), "canLogout",
8e6db58a 509 PowerProvider::DontCheckDBUS);
c7351c0e 510 default:
511 return false;
512 }
b3678cfd
AS
513}
514
515
f05ba5af 516bool LXQtProvider::doAction(Power::Action action)
b3678cfd
AS
517{
518 QString command;
519
520 switch (action)
521 {
8e6db58a 522 case Power::PowerLogout:
b3678cfd
AS
523 command = "logout";
524 break;
525
526 default:
5ea86b7a 527 return false;
b3678cfd
AS
528 }
529
db4aaddf
HJYP
530 return dbusCall(LXQT_SERVICE,
531 LXQT_PATH,
532 LXQT_INTERFACE,
b3678cfd
AS
533 QDBusConnection::sessionBus(),
534 command
535 );
536}
537
ce86ee51
HJYP
538/************************************************
539 LxSessionProvider
540 ************************************************/
541LxSessionProvider::LxSessionProvider(QObject *parent):
542 PowerProvider(parent)
543{
544 pid = (Q_PID)qgetenv("_LXSESSION_PID").toLong();
545}
546
547
548LxSessionProvider::~LxSessionProvider()
549{
550}
551
552
553bool LxSessionProvider::canAction(Power::Action action) const
554{
555 switch (action)
556 {
557 case Power::PowerLogout:
558 return pid != 0;
559 default:
560 return false;
561 }
562}
563
564
565bool LxSessionProvider::doAction(Power::Action action)
566{
567 switch (action)
568 {
569 case Power::PowerLogout:
570 if(pid)
571 ::kill(pid, SIGTERM);
572 break;
573 default:
574 return false;
575 }
85965778
JL
576
577 return true;
ce86ee51 578}
b3678cfd
AS
579
580
581/************************************************
582 HalProvider
583 ************************************************/
584HalProvider::HalProvider(QObject *parent):
8e6db58a 585 PowerProvider(parent)
b3678cfd
AS
586{
587}
588
589
590HalProvider::~HalProvider()
591{
592}
593
594
8e6db58a 595bool HalProvider::canAction(Power::Action action) const
b3678cfd 596{
7cce0c05 597 Q_UNUSED(action)
b3678cfd
AS
598 return false;
599}
600
601
8e6db58a 602bool HalProvider::doAction(Power::Action action)
b3678cfd 603{
7cce0c05 604 Q_UNUSED(action)
5ea86b7a 605 return false;
b3678cfd 606}
497b5c91
AM
607
608
609/************************************************
610 CustomProvider
611 ************************************************/
612CustomProvider::CustomProvider(QObject *parent):
8e6db58a 613 PowerProvider(parent),
497b5c91
AM
614 mSettings("power")
615{
616}
617
618CustomProvider::~CustomProvider()
619{
620}
621
8e6db58a 622bool CustomProvider::canAction(Power::Action action) const
497b5c91
AM
623{
624 switch (action)
625 {
8e6db58a 626 case Power::PowerShutdown:
497b5c91
AM
627 return mSettings.contains("shutdownCommand");
628
8e6db58a 629 case Power::PowerReboot:
497b5c91
AM
630 return mSettings.contains("rebootCommand");
631
8e6db58a 632 case Power::PowerHibernate:
497b5c91
AM
633 return mSettings.contains("hibernateCommand");
634
8e6db58a 635 case Power::PowerSuspend:
497b5c91
AM
636 return mSettings.contains("suspendCommand");
637
8e6db58a 638 case Power::PowerLogout:
497b5c91
AM
639 return mSettings.contains("logoutCommand");
640
641 default:
642 return false;
643 }
644}
645
8e6db58a 646bool CustomProvider::doAction(Power::Action action)
497b5c91
AM
647{
648 QString command;
649
650 switch(action)
651 {
8e6db58a 652 case Power::PowerShutdown:
497b5c91
AM
653 command = mSettings.value("shutdownCommand").toString();
654 break;
655
8e6db58a 656 case Power::PowerReboot:
497b5c91
AM
657 command = mSettings.value("rebootCommand").toString();
658 break;
659
8e6db58a 660 case Power::PowerHibernate:
497b5c91
AM
661 command = mSettings.value("hibernateCommand").toString();
662 break;
663
8e6db58a 664 case Power::PowerSuspend:
497b5c91
AM
665 command = mSettings.value("suspendCommand").toString();
666 break;
667
8e6db58a 668 case Power::PowerLogout:
497b5c91
AM
669 command = mSettings.value("logoutCommand").toString();
670 break;
671
672 default:
673 return false;
674 }
675
676 return QProcess::startDetached(command);
677}