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 | |
45 | QT_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 | */ |
62 | QSensorBackend::QSensorBackend(QSensor *sensor, QObject *parent) |
63 | : QObject(*new QSensorBackendPrivate(sensor), parent) |
64 | { |
65 | } |
66 | |
67 | /*! |
68 | \internal |
69 | */ |
70 | QSensorBackend::~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 | */ |
83 | bool 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 | */ |
92 | void 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 | */ |
133 | QSensorReading *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 | */ |
143 | QSensor *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 | */ |
216 | void 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 | */ |
233 | void 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 | */ |
253 | void 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 | */ |
280 | void 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 | */ |
296 | void 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 | */ |
313 | void 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 | */ |
330 | void 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 | */ |
345 | void 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 | |
353 | QT_END_NAMESPACE |
354 | |
355 | #include "moc_qsensorbackend.cpp" |
356 | |