1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtSensors module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qsensorbackend.h"
41#include "qsensorbackend_p.h"
42#include "qsensor_p.h"
43#include <QDebug>
44
45QT_BEGIN_NAMESPACE
46
47/*!
48 \class QSensorBackend
49 \ingroup sensors_backend
50 \inmodule QtSensors
51 \since 5.1
52
53 \brief The QSensorBackend class is a sensor implementation.
54
55 Sensors on a device will be represented by sub-classes of
56 QSensorBackend.
57*/
58
59/*!
60 \internal
61*/
62QSensorBackend::QSensorBackend(QSensor *sensor, QObject *parent)
63 : QObject(*new QSensorBackendPrivate(sensor), parent)
64{
65}
66
67/*!
68 \internal
69*/
70QSensorBackend::~QSensorBackend()
71{
72}
73
74/*!
75 Checks whether a feature is supported by this sensor backend.
76
77 This is the backend side of QSensor::isFeatureSupported(). Reimplement this function if the
78 backend supports one of the additional sensor features of QSensor::Feature.
79
80 Returns whether the feature \a feature is supported by this backend. The default implementation returns false.
81 \since 5.0
82 */
83bool QSensorBackend::isFeatureSupported(QSensor::Feature feature) const
84{
85 Q_UNUSED(feature);
86 return false;
87}
88
89/*!
90 Notify the QSensor class that a new reading is available.
91*/
92void QSensorBackend::newReadingAvailable()
93{
94 Q_D(QSensorBackend);
95 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
96
97 // Copy the values from the device reading to the filter reading
98 sensorPrivate->filter_reading->copyValuesFrom(other: sensorPrivate->device_reading);
99
100 for (QFilterList::const_iterator it = sensorPrivate->filters.constBegin(); it != sensorPrivate->filters.constEnd(); ++it) {
101 QSensorFilter *filter = (*it);
102 if (!filter->filter(reading: sensorPrivate->filter_reading))
103 return;
104 }
105
106 // Copy the values from the filter reading to the cached reading
107 sensorPrivate->cache_reading->copyValuesFrom(other: sensorPrivate->filter_reading);
108
109 Q_EMIT d->m_sensor->readingChanged();
110}
111
112/*!
113 \fn QSensorBackend::start()
114
115 Start reporting values.
116*/
117
118/*!
119 \fn QSensorBackend::stop()
120
121 Stop reporting values.
122*/
123
124/*!
125 If the backend has lost its reference to the reading
126 it can call this method to get the address.
127
128 Note that you will need to down-cast to the appropriate
129 type.
130
131 \sa setReading()
132*/
133QSensorReading *QSensorBackend::reading() const
134{
135 Q_D(const QSensorBackend);
136 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
137 return sensorPrivate->device_reading;
138}
139
140/*!
141 Returns the sensor front end associated with this backend.
142*/
143QSensor *QSensorBackend::sensor() const
144{
145 Q_D(const QSensorBackend);
146 return d->m_sensor;
147}
148
149/*!
150 \fn template <typename T> T *QSensorBackend::setReading(T *reading)
151
152 This function is called to initialize the \a reading
153 classes used for a sensor.
154
155 If your backend has already allocated a reading you
156 should pass the address of this to the function.
157 Otherwise you should pass 0 and the function will
158 return the address of the reading your backend
159 should use when it wants to notify the sensor API
160 of new readings.
161
162 Note that this is a template function so it should
163 be called with the appropriate type.
164
165 \code
166 class MyBackend : public QSensorBackend
167 {
168 QAccelerometerReading m_reading;
169 public:
170 MyBackend(QSensor *sensor)
171 : QSensorBackend(sensor)
172 {
173 setReading<QAccelerometerReading>(&m_reading);
174 }
175
176 ...
177 \endcode
178
179 Note that this function must be called or you will
180 not be able to send readings to the front end.
181
182 If you do not wish to store the address of the reading
183 you may use the reading() method to get it again later.
184
185 \code
186 class MyBackend : public QSensorBackend
187 {
188 public:
189 MyBackend(QSensor *sensor)
190 : QSensorBackend(sensor)
191 {
192 setReading<QAccelerometerReading>(0);
193 }
194
195 void poll()
196 {
197 quint64 timestamp;
198 qreal x, y, z;
199 ...
200 QAccelerometerReading *reading = static_cast<QAccelerometerReading*>(reading());
201 reading->setTimestamp(timestamp);
202 reading->setX(x);
203 reading->setY(y);
204 reading->setZ(z);
205 }
206
207 ...
208 \endcode
209
210 \sa reading()
211*/
212
213/*!
214 \internal
215*/
216void QSensorBackend::setReadings(QSensorReading *device, QSensorReading *filter, QSensorReading *cache)
217{
218 Q_D(QSensorBackend);
219 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
220 sensorPrivate->device_reading = device;
221 sensorPrivate->filter_reading = filter;
222 sensorPrivate->cache_reading = cache;
223}
224
225/*!
226 Add a data rate (consisting of \a min and \a max values) for the sensor.
227
228 Note that this function should be called from the constructor so that the information
229 is available immediately.
230
231 \sa QSensor::availableDataRates
232*/
233void QSensorBackend::addDataRate(qreal min, qreal max)
234{
235 Q_D(QSensorBackend);
236 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
237 sensorPrivate->availableDataRates << qrange(min, max);
238}
239
240/*!
241 Set the data rates for the sensor based on \a otherSensor.
242
243 This is designed for sensors that are based on other sensors.
244
245 \code
246 setDataRates(otherSensor);
247 \endcode
248
249 Note that this function must be called from the constructor.
250
251 \sa QSensor::availableDataRates, addDataRate()
252*/
253void QSensorBackend::setDataRates(const QSensor *otherSensor)
254{
255 Q_D(QSensorBackend);
256 if (!otherSensor) {
257 qWarning() << "ERROR: Cannot call QSensorBackend::setDataRates with 0";
258 return;
259 }
260 if (otherSensor->identifier().isEmpty()) {
261 qWarning() << "ERROR: Cannot call QSensorBackend::setDataRates with an invalid sensor";
262 return;
263 }
264 if (d->m_sensor->isConnectedToBackend()) {
265 qWarning() << "ERROR: Cannot call QSensorBackend::setDataRates outside of the constructor";
266 return;
267 }
268 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
269 sensorPrivate->availableDataRates = otherSensor->availableDataRates();
270}
271
272/*!
273 Add an output range (consisting of \a min, \a max values and \a accuracy) for the sensor.
274
275 Note that this function should be called from the constructor so that the information
276 is available immediately.
277
278 \sa QSensor::outputRange, QSensor::outputRanges
279*/
280void QSensorBackend::addOutputRange(qreal min, qreal max, qreal accuracy)
281{
282 Q_D(QSensorBackend);
283 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
284
285 qoutputrange details = {.minimum: min, .maximum: max, .accuracy: accuracy};
286
287 sensorPrivate->outputRanges << details;
288}
289
290/*!
291 Set the \a description for the sensor.
292
293 Note that this function should be called from the constructor so that the information
294 is available immediately.
295*/
296void QSensorBackend::setDescription(const QString &description)
297{
298 Q_D(QSensorBackend);
299 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
300 sensorPrivate->description = description;
301}
302
303/*!
304 Inform the front end that the sensor has stopped.
305 This can be due to start() failing or for some
306 unexpected reason (eg. hardware failure).
307
308 Note that the front end must call QSensor::isActive() to see if
309 the sensor has stopped. If the sensor has stopped due to an error
310 the sensorError() function should be called to notify the class
311 of the error condition.
312*/
313void QSensorBackend::sensorStopped()
314{
315 Q_D(QSensorBackend);
316 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
317 sensorPrivate->active = false;
318}
319
320/*!
321 Inform the front end that the sensor is busy.
322 This implicitly calls sensorStopped() and
323 is typically called from start().
324
325 Note that the front end must call QSensor::isBusy() to see if
326 the sensor is busy. If the sensor has stopped due to an error
327 the sensorError() function should be called to notify the class
328 of the error condition.
329*/
330void QSensorBackend::sensorBusy()
331{
332 Q_D(QSensorBackend);
333 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
334 sensorPrivate->active = false;
335 sensorPrivate->busy = true;
336}
337
338/*!
339 Inform the front end that a sensor error occurred.
340 Note that this only reports an \a error code. It does
341 not stop the sensor.
342
343 \sa sensorStopped()
344*/
345void QSensorBackend::sensorError(int error)
346{
347 Q_D(QSensorBackend);
348 QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
349 sensorPrivate->error = error;
350 Q_EMIT d->m_sensor->sensorError(error);
351}
352
353QT_END_NAMESPACE
354
355#include "moc_qsensorbackend.cpp"
356

source code of qtsensors/src/sensors/qsensorbackend.cpp