|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qsensor.h" |
|
43 #include "qsensor_p.h" |
|
44 #include "qsensorbackend.h" |
|
45 #include "qsensormanager.h" |
|
46 #include <QDebug> |
|
47 #include <QMetaProperty> |
|
48 |
|
49 QTM_BEGIN_NAMESPACE |
|
50 |
|
51 /*! |
|
52 \typedef qtimestamp |
|
53 \relates QSensor |
|
54 |
|
55 Sensor timestamps are represented by this typedef which is a 64 bit unsigned integer. |
|
56 |
|
57 Timestamps values are microseconds since a fixed point. |
|
58 You can use timestamps to see how far apart two sensor readings are. |
|
59 |
|
60 Note that sensor timestamps from different sensors may not be directly |
|
61 comparable (as they may choose different fixed points for their reference). |
|
62 */ |
|
63 |
|
64 // A bit of a hack to call qRegisterMetaType when the library is loaded. |
|
65 static int qtimestamp_id = qRegisterMetaType<QtMobility::qtimestamp>("QtMobility::qtimestamp"); |
|
66 static int qrange_id = qRegisterMetaType<QtMobility::qrange>("QtMobility::qrange"); |
|
67 static int qrangelist_id = qRegisterMetaType<QtMobility::qrangelist>("QtMobility::qrangelist"); |
|
68 static int qoutputrangelist_id = qRegisterMetaType<QtMobility::qoutputrangelist>("QtMobility::qoutputrangelist"); |
|
69 |
|
70 // ===================================================================== |
|
71 |
|
72 /*! |
|
73 \class QSensor |
|
74 \ingroup sensors_main |
|
75 |
|
76 \brief The QSensor class represents a single hardware sensor. |
|
77 |
|
78 The life cycle of a sensor is typically: |
|
79 |
|
80 \list |
|
81 \o Create a sub-class of QSensor on the stack or heap. |
|
82 \o Setup as required by the application. |
|
83 \o Start receiving values. |
|
84 \o Sensor data is used by the application. |
|
85 \o Stop receiving values. |
|
86 \endlist |
|
87 |
|
88 The sensor data is delivered via QSensorData and its sub-classes. |
|
89 */ |
|
90 |
|
91 /*! |
|
92 Construct the \a type sensor as a child of \a parent. |
|
93 */ |
|
94 QSensor::QSensor(const QByteArray &type, QObject *parent) |
|
95 : QObject(parent) |
|
96 , d(new QSensorPrivate) |
|
97 { |
|
98 d->type = type; |
|
99 } |
|
100 |
|
101 /*! |
|
102 Destroy the sensor. Stops the sensor if it has not already been stopped. |
|
103 */ |
|
104 QSensor::~QSensor() |
|
105 { |
|
106 stop(); |
|
107 Q_FOREACH (QSensorFilter *filter, d->filters) |
|
108 filter->setSensor(0); |
|
109 delete d->backend; |
|
110 d->backend = 0; |
|
111 // owned by the backend |
|
112 d->device_reading = 0; |
|
113 d->filter_reading = 0; |
|
114 d->cache_reading = 0; |
|
115 } |
|
116 |
|
117 /*! |
|
118 \property QSensor::connectedToBackend |
|
119 \brief a value indicating if the sensor has connected to a backend. |
|
120 |
|
121 A sensor that has not been connected to a backend cannot do anything useful. |
|
122 |
|
123 Call the connectToBackend() method to force the sensor to connect to a backend |
|
124 immediately. This is automatically called if you call start() so you only need |
|
125 to do this if you need access to sensor properties (ie. to poll the sensor's |
|
126 meta-data before you use it). |
|
127 */ |
|
128 |
|
129 bool QSensor::isConnectedToBackend() const |
|
130 { |
|
131 return (d->backend != 0); |
|
132 } |
|
133 |
|
134 /*! |
|
135 \property QSensor::sensorid |
|
136 \brief the backend identifier for the sensor. |
|
137 |
|
138 Note that the identifier is filled out automatically |
|
139 when the sensor is connected to a backend. If you want |
|
140 to connect a specific backend, you should call |
|
141 setIdentifier() before connectToBackend(). |
|
142 */ |
|
143 |
|
144 QByteArray QSensor::identifier() const |
|
145 { |
|
146 return d->identifier; |
|
147 } |
|
148 |
|
149 void QSensor::setIdentifier(const QByteArray &identifier) |
|
150 { |
|
151 if (d->backend) { |
|
152 qWarning() << "ERROR: Cannot call QSensor::setIdentifier while connected to a backend!"; |
|
153 return; |
|
154 } |
|
155 d->identifier = identifier; |
|
156 } |
|
157 |
|
158 /*! |
|
159 \property QSensor::type |
|
160 \brief the type of the sensor. |
|
161 */ |
|
162 |
|
163 QByteArray QSensor::type() const |
|
164 { |
|
165 return d->type; |
|
166 } |
|
167 |
|
168 /*! |
|
169 Try to connect to a sensor backend. |
|
170 |
|
171 Returns true if a suitable backend could be found, false otherwise. |
|
172 |
|
173 The type must be set before calling this method if you are using QSensor directly. |
|
174 |
|
175 \sa isConnectedToBackend() |
|
176 */ |
|
177 bool QSensor::connectToBackend() |
|
178 { |
|
179 if (d->backend) |
|
180 return true; |
|
181 |
|
182 d->backend = QSensorManager::createBackend(this); |
|
183 return (d->backend != 0); |
|
184 } |
|
185 |
|
186 /*! |
|
187 \property QSensor::busy |
|
188 \brief a value to indicate if the sensor is busy. |
|
189 |
|
190 Some sensors may be on the system but unavailable for use. |
|
191 This function will return true if the sensor is busy. You |
|
192 will not be able to start() the sensor. |
|
193 |
|
194 Note that this function does not return true if you |
|
195 are using the sensor, only if another process is using |
|
196 the sensor. |
|
197 |
|
198 \sa busyChanged() |
|
199 */ |
|
200 |
|
201 bool QSensor::isBusy() const |
|
202 { |
|
203 return d->busy; |
|
204 } |
|
205 |
|
206 /*! |
|
207 \fn QSensor::busyChanged() |
|
208 |
|
209 This signal is emitted when the busy state changes. This can |
|
210 be used to grab a sensor when it becomes available. |
|
211 */ |
|
212 |
|
213 /*! |
|
214 \property QSensor::active |
|
215 \brief a value to indicate if the sensor is active. |
|
216 |
|
217 This is true if the sensor is active (returning values). This is false otherwise. |
|
218 */ |
|
219 |
|
220 bool QSensor::isActive() const |
|
221 { |
|
222 return d->active; |
|
223 } |
|
224 |
|
225 /*! |
|
226 \property QSensor::availableDataRates |
|
227 \brief the data rates that the sensor supports. |
|
228 |
|
229 This is a list of the data rates that the sensor supports. |
|
230 Measured in Hertz. |
|
231 |
|
232 Entries in the list can represent discrete rates or a |
|
233 continuous range of rates. |
|
234 A discrete rate is noted by having both values the same. |
|
235 |
|
236 See the sensor_explorer example for an example of how to interpret and use |
|
237 this information. |
|
238 |
|
239 \sa QSensor::dataRate |
|
240 */ |
|
241 |
|
242 qrangelist QSensor::availableDataRates() const |
|
243 { |
|
244 return d->availableDataRates; |
|
245 } |
|
246 |
|
247 /*! |
|
248 \property QSensor::dataRate |
|
249 \brief the data rate that the sensor should be run at. |
|
250 |
|
251 Measured in Hertz. |
|
252 |
|
253 The data rate is the maximum frequency at which the sensor can detect changes. |
|
254 |
|
255 Setting this property is not portable and can cause conflicts with other |
|
256 applications. Check with the sensor backend and platform documentation for |
|
257 any policy regarding multiple applications requesting a data rate. |
|
258 |
|
259 The default value (0) means that the app does not care what the data rate is. |
|
260 Applications should consider using a timer-based poll of the current value or |
|
261 ensure that the code that processes values can run very quickly as the platform |
|
262 may provide updates hundreds of times each second. |
|
263 |
|
264 This should be set before calling start() because the sensor may not |
|
265 notice changes to this value while it is running. |
|
266 |
|
267 Note that there is no mechanism to determine the current data rate in use by the |
|
268 platform. |
|
269 |
|
270 \sa QSensor::availableDataRates |
|
271 */ |
|
272 |
|
273 int QSensor::dataRate() const |
|
274 { |
|
275 return d->dataRate; |
|
276 } |
|
277 |
|
278 void QSensor::setDataRate(int rate) |
|
279 { |
|
280 if (rate == 0) { |
|
281 d->dataRate = rate; |
|
282 return; |
|
283 } |
|
284 bool warn = true; |
|
285 Q_FOREACH (const qrange &range, d->availableDataRates) { |
|
286 if (rate >= range.first && rate <= range.second) { |
|
287 warn = false; |
|
288 d->dataRate = rate; |
|
289 break; |
|
290 } |
|
291 } |
|
292 if (warn) { |
|
293 qWarning() << "setDataRate: rate" << rate << "is not supported by the sensor."; |
|
294 } |
|
295 } |
|
296 |
|
297 /*! |
|
298 Start retrieving values from the sensor. |
|
299 Returns true if the sensor was started, false otherwise. |
|
300 |
|
301 Note that the sensor may fail to start for several reasons. |
|
302 |
|
303 \sa QSensor::busy |
|
304 */ |
|
305 bool QSensor::start() |
|
306 { |
|
307 if (d->active) |
|
308 return true; |
|
309 if (!connectToBackend()) |
|
310 return false; |
|
311 // Set these flags to their defaults |
|
312 d->active = true; |
|
313 d->busy = false; |
|
314 // Backend will update the flags appropriately |
|
315 d->backend->start(); |
|
316 return d->active; |
|
317 } |
|
318 |
|
319 /*! |
|
320 Stop retrieving values from the sensor. |
|
321 |
|
322 This releases the sensor so that other processes can use it. |
|
323 |
|
324 \sa QSensor::busy |
|
325 */ |
|
326 void QSensor::stop() |
|
327 { |
|
328 if (!d->active || !d->backend) |
|
329 return; |
|
330 d->active = false; |
|
331 d->backend->stop(); |
|
332 } |
|
333 |
|
334 /*! |
|
335 \property QSensor::reading |
|
336 \brief the reading class. |
|
337 |
|
338 The reading class provides access to sensor readings. |
|
339 |
|
340 Note that this will return 0 until a sensor backend is connected to a backend. |
|
341 |
|
342 \sa isConnectedToBackend() |
|
343 */ |
|
344 |
|
345 QSensorReading *QSensor::reading() const |
|
346 { |
|
347 return d->cache_reading; |
|
348 } |
|
349 |
|
350 /*! |
|
351 Add a \a filter to the sensor. |
|
352 |
|
353 The sensor does not take ownership of the filter. |
|
354 QSensorFilter will inform the sensor if it is destroyed. |
|
355 |
|
356 \sa QSensorFilter |
|
357 */ |
|
358 void QSensor::addFilter(QSensorFilter *filter) |
|
359 { |
|
360 if (!filter) { |
|
361 qWarning() << "addFilter: passed a null filter!"; |
|
362 return; |
|
363 } |
|
364 d->filters << filter; |
|
365 } |
|
366 |
|
367 /*! |
|
368 Remove \a filter from the sensor. |
|
369 |
|
370 \sa QSensorFilter |
|
371 */ |
|
372 void QSensor::removeFilter(QSensorFilter *filter) |
|
373 { |
|
374 if (!filter) { |
|
375 qWarning() << "removeFilter: passed a null filter!"; |
|
376 return; |
|
377 } |
|
378 d->filters.removeOne(filter); |
|
379 filter->setSensor(0); |
|
380 } |
|
381 |
|
382 /*! |
|
383 \fn QSensor::d_func() const |
|
384 \internal |
|
385 */ |
|
386 |
|
387 /*! |
|
388 \fn QSensor::readingChanged() |
|
389 |
|
390 This signal is emitted when the reading has changed. |
|
391 */ |
|
392 |
|
393 /*! |
|
394 \property QSensor::outputRanges |
|
395 \brief a list of output ranges the sensor supports. |
|
396 |
|
397 A sensor may have more than one output range. Typically this is done |
|
398 to give a greater measurement range at the cost of lowering accuracy. |
|
399 |
|
400 \sa QSensor::outputRange |
|
401 */ |
|
402 |
|
403 qoutputrangelist QSensor::outputRanges() const |
|
404 { |
|
405 return d->outputRanges; |
|
406 } |
|
407 |
|
408 /*! |
|
409 \property QSensor::outputRange |
|
410 \brief the output range in use by the sensor. |
|
411 |
|
412 This value represents the index in the QSensor::outputRanges list to use. |
|
413 |
|
414 Setting this property is not portable and can cause conflicts with other |
|
415 applications. Check with the sensor backend and platform documentation for |
|
416 any policy regarding multiple applications requesting an output range. |
|
417 |
|
418 The default value (-1) means that the app does not care what the output range is. |
|
419 |
|
420 Note that there is no mechanism to determine the current output range in use by the |
|
421 platform. |
|
422 |
|
423 \sa QSensor::outputRanges |
|
424 */ |
|
425 |
|
426 int QSensor::outputRange() const |
|
427 { |
|
428 return d->outputRange; |
|
429 } |
|
430 |
|
431 void QSensor::setOutputRange(int index) |
|
432 { |
|
433 if (index < -1 || index >= d->outputRanges.count()) { |
|
434 qWarning() << "ERROR: Output range" << index << "is not valid"; |
|
435 return; |
|
436 } |
|
437 d->outputRange = index; |
|
438 } |
|
439 |
|
440 /*! |
|
441 \property QSensor::description |
|
442 \brief a descriptive string for the sensor. |
|
443 */ |
|
444 |
|
445 QString QSensor::description() const |
|
446 { |
|
447 return d->description; |
|
448 } |
|
449 |
|
450 /*! |
|
451 \property QSensor::error |
|
452 \brief the last error code set on the sensor. |
|
453 |
|
454 Note that error codes are sensor-specific. |
|
455 */ |
|
456 |
|
457 int QSensor::error() const |
|
458 { |
|
459 return d->error; |
|
460 } |
|
461 |
|
462 /*! |
|
463 \fn QSensor::sensorError(int error) |
|
464 |
|
465 This signal is emitted when an \a error code is set on the sensor. |
|
466 Note that some errors will cause the sensor to stop working. |
|
467 You should call isActive() to determine if the sensor is still running. |
|
468 */ |
|
469 |
|
470 // ===================================================================== |
|
471 |
|
472 /*! |
|
473 \class QSensorFilter |
|
474 \ingroup sensors_main |
|
475 |
|
476 \brief The QSensorFilter class provides an efficient |
|
477 callback facility for asynchronous notifications of |
|
478 sensor changes. |
|
479 |
|
480 Some sensors (eg. the accelerometer) are often accessed very frequently. |
|
481 This may be slowed down by the use of signals and slots. |
|
482 The QSensorFilter interface provides a more efficient way for the |
|
483 sensor to notify your class that the sensor has changed. |
|
484 |
|
485 Additionally, multiple filters can be added to a sensor. They are called |
|
486 in order and each filter has the option to modify the values in the reading |
|
487 or to suppress the reading altogether. |
|
488 |
|
489 Note that the values in the class returned by QSensor::reading() will |
|
490 not be updated until after the filters have been run. |
|
491 |
|
492 \sa filter() |
|
493 */ |
|
494 |
|
495 /*! |
|
496 \internal |
|
497 */ |
|
498 QSensorFilter::QSensorFilter() |
|
499 : m_sensor(0) |
|
500 { |
|
501 } |
|
502 |
|
503 /*! |
|
504 Notifies the attached sensor (if any) that the filter is being destroyed. |
|
505 */ |
|
506 QSensorFilter::~QSensorFilter() |
|
507 { |
|
508 if (m_sensor) |
|
509 m_sensor->removeFilter(this); |
|
510 } |
|
511 |
|
512 /*! |
|
513 \fn QSensorFilter::filter(QSensorReading *reading) |
|
514 |
|
515 This function is called when the sensor \a reading changes. |
|
516 |
|
517 The filter can modify the reading. |
|
518 |
|
519 Returns true to allow the next filter to receive the value. |
|
520 If this is the last filter, returning true causes the signal |
|
521 to be emitted and the value is stored in the sensor. |
|
522 |
|
523 Returns false to drop the reading. |
|
524 */ |
|
525 |
|
526 /*! |
|
527 \internal |
|
528 */ |
|
529 void QSensorFilter::setSensor(QSensor *sensor) |
|
530 { |
|
531 m_sensor = sensor; |
|
532 } |
|
533 |
|
534 // ===================================================================== |
|
535 |
|
536 /*! |
|
537 \class QSensorReading |
|
538 \ingroup sensors_main |
|
539 |
|
540 \brief The QSensorReading class holds the readings from the sensor. |
|
541 |
|
542 Note that QSensorReading is not particularly useful by itself. The interesting |
|
543 data for each sensor is defined in a sub-class of QSensorReading. |
|
544 */ |
|
545 |
|
546 /*! |
|
547 \internal |
|
548 */ |
|
549 QSensorReading::QSensorReading(QObject *parent, QSensorReadingPrivate *_d) |
|
550 : QObject(parent) |
|
551 , d(_d?_d:new QSensorReadingPrivate) |
|
552 { |
|
553 } |
|
554 |
|
555 /*! |
|
556 \internal |
|
557 */ |
|
558 QSensorReading::~QSensorReading() |
|
559 { |
|
560 } |
|
561 |
|
562 /*! |
|
563 \property QSensorReading::timestamp |
|
564 \brief the timestamp of the reading. |
|
565 |
|
566 \sa qtimestamp |
|
567 */ |
|
568 |
|
569 /*! |
|
570 Returns the timestamp of the reading. |
|
571 */ |
|
572 qtimestamp QSensorReading::timestamp() const |
|
573 { |
|
574 return d->timestamp; |
|
575 } |
|
576 |
|
577 /*! |
|
578 Sets the \a timestamp of the reading. |
|
579 */ |
|
580 void QSensorReading::setTimestamp(qtimestamp timestamp) |
|
581 { |
|
582 d->timestamp = timestamp; |
|
583 } |
|
584 |
|
585 /*! |
|
586 Returns the number of extra properties that the reading has. |
|
587 |
|
588 Note that this does not count properties declared in QSensorReading. |
|
589 |
|
590 As an example, this returns 3 for QAccelerometerReading because |
|
591 there are 3 properties defined in that class. |
|
592 */ |
|
593 int QSensorReading::valueCount() const |
|
594 { |
|
595 const QMetaObject *mo = metaObject(); |
|
596 return mo->propertyCount() - mo->propertyOffset(); |
|
597 } |
|
598 |
|
599 /*! |
|
600 Returns the value of the property at \a index. |
|
601 |
|
602 Note that this function is slower than calling the data function directly. |
|
603 |
|
604 Here is an example of getting a property via the different mechanisms available. |
|
605 |
|
606 Accessing directly provides the best performance but requires compile-time knowledge |
|
607 of the data you are accessing. |
|
608 |
|
609 \code |
|
610 QAccelerometerReading *reading = ...; |
|
611 qreal x = reading->x(); |
|
612 \endcode |
|
613 |
|
614 You can also access a property by name. To do this you must call QObject::property(). |
|
615 |
|
616 \code |
|
617 qreal x = reading->property("x").value<qreal>(); |
|
618 \endcode |
|
619 |
|
620 Finally, you can access values via numeric index. |
|
621 |
|
622 \code |
|
623 qreal x = reading->value(0).value<qreal>(); |
|
624 \endcode |
|
625 |
|
626 Note that value() can only access properties declared with Q_PROPERTY() in sub-classes |
|
627 of QSensorReading. |
|
628 |
|
629 \sa valueCount(), QObject::property() |
|
630 */ |
|
631 QVariant QSensorReading::value(int index) const |
|
632 { |
|
633 // get them meta-object |
|
634 const QMetaObject *mo = metaObject(); |
|
635 |
|
636 // determine the index of the property we want |
|
637 index += mo->propertyOffset(); |
|
638 |
|
639 // get the meta-property |
|
640 QMetaProperty property = mo->property(index); |
|
641 |
|
642 // read the property |
|
643 return property.read(this); |
|
644 } |
|
645 |
|
646 /*! |
|
647 \fn QSensorReading::copyValuesFrom(QSensorReading *other) |
|
648 \internal |
|
649 |
|
650 Copy values from other into this reading. Implemented by sub-classes |
|
651 using the DECLARE_READING() and IMPLEMENT_READING() macros. |
|
652 |
|
653 Note that this method should only be called by QSensorBackend. |
|
654 */ |
|
655 void QSensorReading::copyValuesFrom(QSensorReading *other) |
|
656 { |
|
657 QSensorReadingPrivate *my_ptr = d.data(); |
|
658 QSensorReadingPrivate *other_ptr = other->d.data(); |
|
659 /* Do a direct copy of the private class */ |
|
660 *(my_ptr) = *(other_ptr); |
|
661 } |
|
662 |
|
663 /*! |
|
664 \macro DECLARE_READING(classname) |
|
665 \relates QSensorReading |
|
666 \brief The DECLARE_READING macro adds some required methods to a reading class. |
|
667 |
|
668 This macro should be used for all reading classes. Pass the \a classname of your reading class. |
|
669 |
|
670 \code |
|
671 class MyReading : public QSensorReading |
|
672 { |
|
673 Q_OBJECT |
|
674 Q_PROPERTY(qreal myprop READ myprop) |
|
675 DECLARE_READING(MyReading) |
|
676 public: |
|
677 qreal myprop() const; |
|
678 vod setMyprop(qreal myprop); |
|
679 }; |
|
680 \endcode |
|
681 |
|
682 \sa IMPLEMENT_READING() |
|
683 */ |
|
684 |
|
685 /*! |
|
686 \macro IMPLEMENT_READING(classname) |
|
687 \relates QSensorReading |
|
688 \brief The IMPLEMENT_READING macro implements the required methods for a reading class. |
|
689 |
|
690 This macro should be used for all reading classes. It should be placed into a single compilation |
|
691 unit (source file), not into a header file. Pass the \a classname of your reading class. |
|
692 |
|
693 \code |
|
694 IMPLEMENT_READING(MyReading) |
|
695 \endcode |
|
696 |
|
697 \sa DECLARE_READING() |
|
698 */ |
|
699 |
|
700 #include "moc_qsensor.cpp" |
|
701 QTM_END_NAMESPACE |
|
702 |