Changeset View
Changeset View
Standalone View
Standalone View
daemon/powerdevilpowermanagement.cpp
- This file was added.
1 | /******************************************************************** | ||||
---|---|---|---|---|---|
2 | Copyright 2016 Martin Gräßlin <mgraesslin@kde.org> | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Lesser General Public | ||||
6 | License as published by the Free Software Foundation; either | ||||
7 | version 2.1 of the License, or (at your option) version 3, or any | ||||
8 | later version accepted by the membership of KDE e.V. (or its | ||||
9 | successor approved by the membership of KDE e.V.), which shall | ||||
10 | act as a proxy defined in Section 6 of version 3 of the license. | ||||
11 | | ||||
12 | This library is distributed in the hope that it will be useful, | ||||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
15 | Lesser General Public License for more details. | ||||
16 | | ||||
17 | You should have received a copy of the GNU Lesser General Public | ||||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | *********************************************************************/ | ||||
20 | | ||||
21 | #include "powerdevilpowermanagement.h" | ||||
22 | | ||||
23 | #include <QDBusConnection> | ||||
24 | #include <QDBusConnectionInterface> | ||||
25 | #include <QDBusServiceWatcher> | ||||
26 | | ||||
27 | namespace PowerDevil { | ||||
28 | | ||||
29 | static const QString s_fdoPowerService = QStringLiteral("org.freedesktop.PowerManagement"); | ||||
30 | static const QString s_fdoPowerPath = QStringLiteral("/org/freedesktop/PowerManagement"); | ||||
31 | | ||||
32 | class PowerManagementInstance : public PowerManagement | ||||
33 | { | ||||
34 | Q_OBJECT | ||||
35 | public: | ||||
36 | explicit PowerManagementInstance() : PowerManagement() {} | ||||
37 | }; | ||||
38 | Q_GLOBAL_STATIC(PowerManagementInstance, s_instance) | ||||
39 | | ||||
40 | class PowerManagement::Private | ||||
41 | { | ||||
42 | public: | ||||
43 | Private(PowerManagement *q); | ||||
44 | void update(); | ||||
45 | void setCanSuspend(bool set); | ||||
46 | void setCanHibernate(bool set); | ||||
47 | | ||||
48 | bool serviceRegistered; | ||||
49 | bool canSuspend; | ||||
50 | bool canHibernate; | ||||
51 | QScopedPointer<QDBusServiceWatcher> fdoPowerServiceWatcher; | ||||
52 | | ||||
53 | private: | ||||
54 | void updateProperty(const QString &dbusName, void (Private::*setter)(bool)); | ||||
55 | PowerManagement *q; | ||||
56 | }; | ||||
57 | | ||||
58 | PowerManagement::Private::Private(PowerManagement *q) | ||||
59 | : serviceRegistered(false) | ||||
60 | , canSuspend(false) | ||||
61 | , canHibernate(false) | ||||
62 | , fdoPowerServiceWatcher(new QDBusServiceWatcher(s_fdoPowerService, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration | QDBusServiceWatcher::WatchForRegistration)) | ||||
63 | , q(q) | ||||
64 | { | ||||
65 | } | ||||
66 | | ||||
67 | void PowerManagement::Private::update() | ||||
68 | { | ||||
69 | serviceRegistered = true; | ||||
70 | updateProperty(QStringLiteral("CanSuspend"), &Private::setCanSuspend); | ||||
71 | updateProperty(QStringLiteral("CanHibernate"), &Private::setCanHibernate); | ||||
72 | } | ||||
73 | | ||||
74 | void PowerManagement::Private::updateProperty(const QString &dbusName, void (Private::*setter)(bool)) | ||||
75 | { | ||||
76 | QDBusMessage message = QDBusMessage::createMethodCall(s_fdoPowerService, | ||||
77 | s_fdoPowerPath, | ||||
78 | s_fdoPowerService, | ||||
79 | dbusName); | ||||
80 | QDBusPendingReply<bool> reply = QDBusConnection::sessionBus().asyncCall(message); | ||||
81 | QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(reply, q); | ||||
82 | QObject::connect(callWatcher, &QDBusPendingCallWatcher::finished, q, | ||||
83 | [this, setter](QDBusPendingCallWatcher *self) { | ||||
84 | QDBusPendingReply<bool> reply = *self; | ||||
85 | self->deleteLater(); | ||||
86 | if (!reply.isValid()) { | ||||
87 | return; | ||||
88 | } | ||||
89 | ((this)->*setter)(reply.value()); | ||||
90 | } | ||||
91 | ); | ||||
92 | | ||||
93 | } | ||||
94 | | ||||
95 | void PowerManagement::Private::setCanHibernate(bool set) | ||||
96 | { | ||||
97 | if (canHibernate == set) { | ||||
98 | return; | ||||
99 | } | ||||
100 | canHibernate = set; | ||||
101 | q->canHibernateChanged(); | ||||
102 | } | ||||
103 | | ||||
104 | void PowerManagement::Private::setCanSuspend(bool set) | ||||
105 | { | ||||
106 | if (canSuspend == set) { | ||||
107 | return; | ||||
108 | } | ||||
109 | canSuspend = set; | ||||
110 | q->canSuspendChanged(); | ||||
111 | } | ||||
112 | | ||||
113 | PowerManagement *PowerManagement::instance() | ||||
114 | { | ||||
115 | return s_instance; | ||||
116 | } | ||||
117 | | ||||
118 | PowerManagement::PowerManagement() | ||||
119 | : QObject() | ||||
120 | , d(new Private(this)) | ||||
121 | { | ||||
122 | connect(d->fdoPowerServiceWatcher.data(), &QDBusServiceWatcher::serviceRegistered, this, [this] { d->update(); }); | ||||
123 | connect(d->fdoPowerServiceWatcher.data(), &QDBusServiceWatcher::serviceUnregistered, this, | ||||
124 | [this] { | ||||
125 | d->serviceRegistered = false; | ||||
126 | d->setCanSuspend(false); | ||||
127 | d->setCanHibernate(false); | ||||
128 | } | ||||
129 | ); | ||||
130 | | ||||
131 | // check whether the service is registered | ||||
132 | QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"), | ||||
133 | QStringLiteral("/"), | ||||
134 | QStringLiteral("org.freedesktop.DBus"), | ||||
135 | QStringLiteral("ListNames")); | ||||
136 | QDBusPendingReply<QStringList> async = QDBusConnection::sessionBus().asyncCall(message); | ||||
137 | QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(async, this); | ||||
138 | connect(callWatcher, &QDBusPendingCallWatcher::finished, this, | ||||
139 | [this](QDBusPendingCallWatcher *self) { | ||||
140 | QDBusPendingReply<QStringList> reply = *self; | ||||
141 | self->deleteLater(); | ||||
142 | if (!reply.isValid()) { | ||||
143 | return; | ||||
144 | } | ||||
145 | if (reply.value().contains(s_fdoPowerService)) { | ||||
146 | d->update(); | ||||
147 | } | ||||
148 | } | ||||
149 | ); | ||||
150 | } | ||||
151 | | ||||
152 | PowerManagement::~PowerManagement() | ||||
153 | { | ||||
154 | } | ||||
155 | | ||||
156 | void PowerManagement::suspend() | ||||
157 | { | ||||
158 | if (!d->serviceRegistered) { | ||||
159 | return; | ||||
160 | } | ||||
161 | if (!d->canSuspend) { | ||||
162 | return; | ||||
163 | } | ||||
164 | QDBusMessage message = QDBusMessage::createMethodCall(s_fdoPowerService, | ||||
165 | s_fdoPowerPath, | ||||
166 | s_fdoPowerService, | ||||
167 | QStringLiteral("Suspend")); | ||||
168 | QDBusConnection::sessionBus().asyncCall(message); | ||||
169 | } | ||||
170 | | ||||
171 | void PowerManagement::hibernate() | ||||
172 | { | ||||
173 | if (!d->serviceRegistered) { | ||||
174 | return; | ||||
175 | } | ||||
176 | if (!d->canHibernate) { | ||||
177 | return; | ||||
178 | } | ||||
179 | QDBusMessage message = QDBusMessage::createMethodCall(s_fdoPowerService, | ||||
180 | s_fdoPowerPath, | ||||
181 | s_fdoPowerService, | ||||
182 | QStringLiteral("Hibernate")); | ||||
183 | QDBusConnection::sessionBus().asyncCall(message); | ||||
184 | } | ||||
185 | | ||||
186 | bool PowerManagement::canSuspend() const | ||||
187 | { | ||||
188 | return d->canSuspend; | ||||
189 | } | ||||
190 | | ||||
191 | bool PowerManagement::canHibernate() const | ||||
192 | { | ||||
193 | return d->canHibernate; | ||||
194 | } | ||||
195 | | ||||
196 | } // namespace PowerDevil | ||||
197 | | ||||
198 | #include "powerdevilpowermanagement.moc" |