Libksysguard

SensorDaemonInterface.cpp
1 /*
2  Copyright (C) 2020 Arjen Hiemstra <[email protected]>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "SensorDaemonInterface_p.h"
21 
22 #include <QDBusPendingCallWatcher>
23 
24 #include "ksysguarddaemon.h"
25 
26 using namespace KSysGuard;
27 
28 class SensorDaemonInterface::Private
29 {
30 public:
31  std::unique_ptr<org::kde::KSysGuardDaemon> dbusInterface;
32  std::unique_ptr<QDBusServiceWatcher> serviceWatcher;
33  QStringList subscribedSensors;
34  static const QString SensorServiceName;
35  static const QString SensorPath;
36 };
37 
38 const QString SensorDaemonInterface::Private::SensorServiceName = QStringLiteral("org.kde.ksystemstats");
39 const QString SensorDaemonInterface::Private::SensorPath = QStringLiteral("/");
40 
41 SensorDaemonInterface::SensorDaemonInterface(QObject *parent)
42  : QObject(parent)
43  , d(new Private)
44 {
45  qDBusRegisterMetaType<SensorData>();
46  qDBusRegisterMetaType<SensorInfo>();
47  qDBusRegisterMetaType<SensorDataList>();
48  qDBusRegisterMetaType<SensorInfoMap>();
49 
50  d->serviceWatcher = std::make_unique<QDBusServiceWatcher>(d->SensorServiceName, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration);
51  connect(d->serviceWatcher.get(), &QDBusServiceWatcher::serviceUnregistered, this, &SensorDaemonInterface::reconnect);
52  reconnect();
53 }
54 
55 void KSysGuard::SensorDaemonInterface::reconnect()
56 {
57  d->dbusInterface = std::make_unique<org::kde::KSysGuardDaemon>(Private::SensorServiceName, Private::SensorPath, QDBusConnection::sessionBus());
58  connect(d->dbusInterface.get(), &org::kde::KSysGuardDaemon::sensorMetaDataChanged, this, &SensorDaemonInterface::onMetaDataChanged);
59  connect(d->dbusInterface.get(), &org::kde::KSysGuardDaemon::newSensorData, this, &SensorDaemonInterface::onValueChanged);
60  connect(d->dbusInterface.get(), &org::kde::KSysGuardDaemon::sensorAdded, this, &SensorDaemonInterface::sensorAdded);
61  connect(d->dbusInterface.get(), &org::kde::KSysGuardDaemon::sensorRemoved, this, &SensorDaemonInterface::sensorRemoved);
62  subscribe(d->subscribedSensors);
63 }
64 
65 SensorDaemonInterface::~SensorDaemonInterface()
66 {
67 }
68 
69 void SensorDaemonInterface::requestMetaData(const QString &sensorId)
70 {
71  requestMetaData(QStringList{sensorId});
72 }
73 
74 void SensorDaemonInterface::requestMetaData(const QStringList &sensorIds)
75 {
76  auto watcher = new QDBusPendingCallWatcher{d->dbusInterface->sensors(sensorIds), this};
77  connect(watcher, &QDBusPendingCallWatcher::finished, watcher, [this](QDBusPendingCallWatcher *self) {
78  self->deleteLater();
79 
80  const QDBusPendingReply<SensorInfoMap> reply = *self;
81  if (reply.isError()) {
82  return;
83  }
84 
85  const auto infos = reply.value();
86  for (auto itr = infos.begin(); itr != infos.end(); ++itr) {
87  Q_EMIT metaDataChanged(itr.key(), itr.value());
88  }
89  });
90 }
91 
92 void SensorDaemonInterface::requestValue(const QString &sensorId)
93 {
94  auto watcher = new QDBusPendingCallWatcher{d->dbusInterface->sensorData({sensorId}), this};
95  connect(watcher, &QDBusPendingCallWatcher::finished, watcher, [this](QDBusPendingCallWatcher *self) {
96  self->deleteLater();
97 
98  const QDBusPendingReply<SensorDataList> reply = *self;
99  if (reply.isError()) {
100  return;
101  }
102 
103  const auto allData = reply.value();
104  for (auto data : allData) {
105  Q_EMIT valueChanged(data.attribute, data.payload);
106  }
107  });
108 }
109 
110 QDBusPendingCallWatcher *SensorDaemonInterface::allSensors() const
111 {
112  return new QDBusPendingCallWatcher{d->dbusInterface->allSensors()};
113 }
114 
115 void SensorDaemonInterface::subscribe(const QString &sensorId)
116 {
117  subscribe(QStringList{sensorId});
118 }
119 
120 void KSysGuard::SensorDaemonInterface::subscribe(const QStringList &sensorIds)
121 {
122  d->dbusInterface->subscribe(sensorIds);
123  d->subscribedSensors.append(sensorIds);
124 }
125 
126 void SensorDaemonInterface::unsubscribe(const QString &sensorId)
127 {
128  unsubscribe(QStringList{sensorId});
129 }
130 
131 void KSysGuard::SensorDaemonInterface::unsubscribe(const QStringList &sensorIds)
132 {
133  d->dbusInterface->unsubscribe(sensorIds);
134 }
135 
136 SensorDaemonInterface *SensorDaemonInterface::instance()
137 {
138  static SensorDaemonInterface instance;
139  return &instance;
140 }
141 
142 void SensorDaemonInterface::onMetaDataChanged(const QHash<QString, SensorInfo> &metaData)
143 {
144  for (auto itr = metaData.begin(); itr != metaData.end(); ++itr) {
145  Q_EMIT metaDataChanged(itr.key(), itr.value());
146  }
147 }
148 
149 void SensorDaemonInterface::onValueChanged(const SensorDataList &values)
150 {
151  for (auto entry : values) {
152  Q_EMIT valueChanged(entry.attribute, entry.payload);
153  }
154 }
Q_SIGNAL void metaDataChanged() const
This signal is emitted when any of the metadata properties change.
void finished(QDBusPendingCallWatcher *self)
QDBusConnection sessionBus()
void serviceUnregistered(const QString &serviceName)
QHash::iterator begin()
Internal helper class to communicate with the daemon.
T1 value() const const
QHash::iterator end()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
Q_EMITQ_EMIT
bool isError() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Mar 2 2021 02:46:14 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.