|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 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 |
|
67 // ===================================================================== |
|
68 |
|
69 /*! |
|
70 \class QSensor |
|
71 \ingroup sensors_main |
|
72 |
|
73 \preliminary |
|
74 \brief The QSensor class represents a single hardware sensor. |
|
75 |
|
76 The life cycle of a sensor is typically: |
|
77 |
|
78 \list |
|
79 \o Create a sub-class of QSensor on the stack or heap. |
|
80 \o Setup as required by the application. |
|
81 \o Start receiving values. |
|
82 \o Sensor data is used by the application. |
|
83 \o Stop receiving values. |
|
84 \endlist |
|
85 |
|
86 The sensor data is delivered via QSensorData and its sub-classes. |
|
87 */ |
|
88 |
|
89 /*! |
|
90 Construct the sensor as a child of \a parent. |
|
91 */ |
|
92 QSensor::QSensor(QObject *parent) |
|
93 : QObject(parent) |
|
94 , d(new QSensorPrivate) |
|
95 { |
|
96 } |
|
97 |
|
98 /*! |
|
99 Destroy the sensor. Stops the sensor if it has not already been stopped. |
|
100 */ |
|
101 QSensor::~QSensor() |
|
102 { |
|
103 stop(); |
|
104 Q_FOREACH (QSensorFilter *filter, d->filters) |
|
105 filter->setSensor(0); |
|
106 delete d->backend; |
|
107 d->backend = 0; |
|
108 // owned by the backend |
|
109 d->device_reading = 0; |
|
110 d->filter_reading = 0; |
|
111 d->cache_reading = 0; |
|
112 } |
|
113 |
|
114 /*! |
|
115 \property QSensor::connected |
|
116 \brief a value indicating if the sensor has connected to a backend. |
|
117 |
|
118 A sensor that has not been connected to a backend cannot do anything useful. |
|
119 |
|
120 Call the connect() method to force the sensor to connect to a backend immediately. |
|
121 */ |
|
122 |
|
123 bool QSensor::isConnected() const |
|
124 { |
|
125 return (d->backend != 0); |
|
126 } |
|
127 |
|
128 /*! |
|
129 \property QSensor::sensorid |
|
130 \brief the backend identifier for the sensor. |
|
131 |
|
132 Note that the identifier is filled out automatically |
|
133 when the sensor is connected to a backend. If you want |
|
134 to connect a specific backend, you should call |
|
135 setIdentifier() before connect(). |
|
136 */ |
|
137 |
|
138 QByteArray QSensor::identifier() const |
|
139 { |
|
140 return d->identifier; |
|
141 } |
|
142 |
|
143 void QSensor::setIdentifier(const QByteArray &identifier) |
|
144 { |
|
145 Q_ASSERT(!d->backend); |
|
146 d->identifier = identifier; |
|
147 } |
|
148 |
|
149 /*! |
|
150 \property QSensor::type |
|
151 \brief the type of the sensor. |
|
152 |
|
153 Note that setType() can only be used if you are using QSensor directly. |
|
154 Sub-classes of QSensor call this automatically for you. |
|
155 */ |
|
156 |
|
157 QByteArray QSensor::type() const |
|
158 { |
|
159 return d->type; |
|
160 } |
|
161 |
|
162 void QSensor::setType(const QByteArray &type) |
|
163 { |
|
164 Q_ASSERT(!d->backend); |
|
165 Q_ASSERT(QLatin1String(metaObject()->className()) == QLatin1String("QSensor") || QLatin1String(metaObject()->className()) == QLatin1String(type)); |
|
166 d->type = type; |
|
167 } |
|
168 |
|
169 /*! |
|
170 Try to connect to a sensor backend. |
|
171 |
|
172 Returns true if a suitable backend could be found, false otherwise. |
|
173 |
|
174 The type must be set before calling this method if you are using QSensor directly. |
|
175 |
|
176 \sa isConnected() |
|
177 */ |
|
178 bool QSensor::connect() |
|
179 { |
|
180 if (d->backend) |
|
181 return true; |
|
182 |
|
183 if (d->type.isEmpty()) { |
|
184 qWarning() << "QSensor::connect - Cannot call this method unless the type is set."; |
|
185 return false; |
|
186 } |
|
187 |
|
188 d->backend = QSensorManager::createBackend(this); |
|
189 return (d->backend != 0); |
|
190 } |
|
191 |
|
192 /*! |
|
193 \property QSensor::running |
|
194 \brief controls the running state of the sensor. |
|
195 |
|
196 This is provided for QML, set running: true to cause the sensor |
|
197 to start on. |
|
198 */ |
|
199 |
|
200 bool QSensor::isActive() const |
|
201 { |
|
202 return d->active; |
|
203 } |
|
204 |
|
205 void QSensor::setActive(bool running) |
|
206 { |
|
207 if (d->complete) { |
|
208 if (running) |
|
209 start(); |
|
210 else |
|
211 stop(); |
|
212 } |
|
213 } |
|
214 |
|
215 /*! |
|
216 Returns true if the readingChanged() signal will be emitted. |
|
217 */ |
|
218 bool QSensor::isSignalEnabled() const |
|
219 { |
|
220 return d->signalEnabled; |
|
221 } |
|
222 |
|
223 /*! |
|
224 Call with \a enabled as false to turn off the readingChanged() signal. |
|
225 |
|
226 You might want to do this for performance reasons. If you are polling |
|
227 the sensor or using a filter in a performance-critical application |
|
228 then the overhead of emitting the signal may be too high even if nothing |
|
229 is connected to it. |
|
230 */ |
|
231 void QSensor::setSignalEnabled(bool enabled) |
|
232 { |
|
233 d->signalEnabled = enabled; |
|
234 } |
|
235 |
|
236 /*! |
|
237 \enum QSensor::UpdatePolicy |
|
238 |
|
239 This enum is used to indicate to the sensor how often data will be collected. |
|
240 Note that most sensors will only support one sensitivity. Setting an update |
|
241 policy that the sensor does not support will result in undefined behaviour. |
|
242 You can determine the policies the sensor supports with the |
|
243 QSensor::supportedUpdatePolicies() method. |
|
244 |
|
245 \value Undefined The sensor has no specific update policy. Updates may |
|
246 arrive frequently or infrequently. Updates based on |
|
247 user interaction are likely to fit into this category. |
|
248 \value OnChangeUpdates Updates are delivered as they happen, usually based on |
|
249 user activity. |
|
250 \value OccasionalUpdates Updates are delivered occasionally, about one every |
|
251 5 seconds. |
|
252 \value InfrequentUpdates Updates are delivered infrequently, no more than once |
|
253 per second. |
|
254 \value FrequentUpdates Updates are delivered frequently, several per second. |
|
255 \value TimedUpdates Updates are delivered at a specific time interval. |
|
256 Note that not all sensors may be able to run with the |
|
257 exact timings requested and may operate slightly faster |
|
258 or slower. |
|
259 \value PolledUpdates Updates are retrieved when the currentReading() |
|
260 method is called. |
|
261 */ |
|
262 |
|
263 /*! |
|
264 Change the update \a policy of the sensor. Note that not all |
|
265 sensors support changing the update policy. If you set a |
|
266 policy that the sensor does not support the behaviour is |
|
267 undefined. |
|
268 |
|
269 If you wish to use the TimedUpdates policy, please call |
|
270 setUpdateInterval() with the desired interval. |
|
271 |
|
272 \sa supportedUpdatePolicies() |
|
273 */ |
|
274 void QSensor::setUpdatePolicy(UpdatePolicy policy) |
|
275 { |
|
276 if (policy == TimedUpdates) |
|
277 return; |
|
278 |
|
279 d->updatePolicy = policy; |
|
280 d->updateInterval = 0; |
|
281 } |
|
282 |
|
283 void QSensor::setUpdateInterval(int interval) |
|
284 { |
|
285 d->updatePolicy = TimedUpdates; |
|
286 d->updateInterval = interval; |
|
287 } |
|
288 |
|
289 /*! |
|
290 \property QSensor::updatePolicy |
|
291 \brief the update policy of the sensor. |
|
292 */ |
|
293 |
|
294 /*! |
|
295 Returns the update policy the sensor is using. |
|
296 */ |
|
297 QSensor::UpdatePolicy QSensor::updatePolicy() const |
|
298 { |
|
299 return d->updatePolicy; |
|
300 } |
|
301 |
|
302 /*! |
|
303 \property QSensor::updateInterval |
|
304 \brief the update interval of the sensor. |
|
305 |
|
306 This value is only useful if the QSensor::updatePolicy property is set to TimedUpdates. |
|
307 */ |
|
308 |
|
309 int QSensor::updateInterval() const |
|
310 { |
|
311 return d->updateInterval; |
|
312 } |
|
313 |
|
314 /*! |
|
315 \property QSensor::supportedUpdatePolicies |
|
316 \brief the supported policies of the sensor. |
|
317 */ |
|
318 |
|
319 /*! |
|
320 Returns the update policies that the sensor supports. |
|
321 |
|
322 Note that this will return QSensor::Undefined until a sensor backend is connected. |
|
323 |
|
324 \sa isConnected() |
|
325 */ |
|
326 QSensor::UpdatePolicies QSensor::supportedUpdatePolicies() const |
|
327 { |
|
328 return d->supportedUpdatePolicies; |
|
329 } |
|
330 |
|
331 /*! |
|
332 Poll the sensor. |
|
333 */ |
|
334 void QSensor::poll() |
|
335 { |
|
336 if (!connect()) |
|
337 return; |
|
338 if (d->updatePolicy == PolledUpdates) |
|
339 d->backend->poll(); |
|
340 } |
|
341 |
|
342 /*! |
|
343 Start retrieving values from the sensor. |
|
344 */ |
|
345 void QSensor::start() |
|
346 { |
|
347 if (d->active) |
|
348 return; |
|
349 if (!connect()) |
|
350 return; |
|
351 d->active = true; |
|
352 d->backend->start(); |
|
353 } |
|
354 |
|
355 /*! |
|
356 Stop retrieving values from the sensor. |
|
357 */ |
|
358 void QSensor::stop() |
|
359 { |
|
360 if (!d->active || !d->backend) |
|
361 return; |
|
362 d->active = false; |
|
363 d->backend->stop(); |
|
364 } |
|
365 |
|
366 /*! |
|
367 \property QSensor::reading |
|
368 \brief the reading class. |
|
369 |
|
370 The reading class provides access to sensor readings. |
|
371 |
|
372 Note that this will return 0 until a sensor backend is connected. |
|
373 |
|
374 \sa isConnected() |
|
375 */ |
|
376 |
|
377 QSensorReading *QSensor::reading() const |
|
378 { |
|
379 return d->cache_reading; |
|
380 } |
|
381 |
|
382 /*! |
|
383 Add a \a filter to the sensor. |
|
384 |
|
385 The sensor does not take ownership of the filter. |
|
386 QSensorFilter will inform the sensor if it is destroyed. |
|
387 |
|
388 \sa QSensorFilter |
|
389 */ |
|
390 void QSensor::addFilter(QSensorFilter *filter) |
|
391 { |
|
392 d->filters << filter; |
|
393 } |
|
394 |
|
395 /*! |
|
396 Remove \a filter from the sensor. |
|
397 |
|
398 \sa QSensorFilter |
|
399 */ |
|
400 void QSensor::removeFilter(QSensorFilter *filter) |
|
401 { |
|
402 d->filters.removeOne(filter); |
|
403 filter->setSensor(0); |
|
404 } |
|
405 |
|
406 /*! |
|
407 \fn QSensor::d_func() const |
|
408 \internal |
|
409 */ |
|
410 |
|
411 /*! |
|
412 \fn QSensor::readingChanged() |
|
413 |
|
414 This signal is emitted when the reading has changed. |
|
415 */ |
|
416 |
|
417 // ===================================================================== |
|
418 |
|
419 /*! |
|
420 \class QSensorFilter |
|
421 \ingroup sensors_main |
|
422 |
|
423 \preliminary |
|
424 \brief The QSensorFilter class provides an efficient |
|
425 callback facility for asynchronous notifications of |
|
426 sensor changes. |
|
427 |
|
428 Some sensors (eg. the accelerometer) are often accessed very frequently. |
|
429 This may be slowed down by the use of signals and slots. |
|
430 The QSensorFilter interface provides a more efficient way for the |
|
431 sensor to notify your class that the sensor has changed. |
|
432 |
|
433 Additionally, multiple filters can be added to a sensor. They are called |
|
434 in order and each filter has the option to modify the values in the reading |
|
435 or to suppress the reading altogether. |
|
436 |
|
437 Note that the values in the class returned by QSensor::reading() will |
|
438 not be updated until after the filters have been run. |
|
439 |
|
440 \sa filter() |
|
441 */ |
|
442 |
|
443 /*! |
|
444 \internal |
|
445 */ |
|
446 QSensorFilter::QSensorFilter() |
|
447 : m_sensor(0) |
|
448 { |
|
449 } |
|
450 |
|
451 /*! |
|
452 Notifies the attached sensor (if any) that the filter is being destroyed. |
|
453 */ |
|
454 QSensorFilter::~QSensorFilter() |
|
455 { |
|
456 if (m_sensor) |
|
457 m_sensor->removeFilter(this); |
|
458 } |
|
459 |
|
460 /*! |
|
461 \fn QSensorFilter::filter(QSensorReading *reading) |
|
462 |
|
463 This function is called when the sensor \a reading changes. |
|
464 |
|
465 The filter can modify the reading. |
|
466 |
|
467 Returns true to allow the next filter to receive the value. |
|
468 If this is the last filter, returning true causes the signal |
|
469 to be emitted and the value is stored in the sensor. |
|
470 |
|
471 Returns false to drop the reading. |
|
472 */ |
|
473 |
|
474 /*! |
|
475 \internal |
|
476 */ |
|
477 void QSensorFilter::setSensor(QSensor *sensor) |
|
478 { |
|
479 m_sensor = sensor; |
|
480 } |
|
481 |
|
482 // ===================================================================== |
|
483 |
|
484 /*! |
|
485 \class QSensorReading |
|
486 \ingroup sensors_main |
|
487 |
|
488 \preliminary |
|
489 \brief The QSensorReading class holds the readings from the sensor. |
|
490 |
|
491 Note that QSensorReading is not particularly useful by itself. The interesting |
|
492 data for each sensor is defined in a sub-class of QSensorReading. |
|
493 */ |
|
494 |
|
495 /*! |
|
496 \internal |
|
497 */ |
|
498 QSensorReading::QSensorReading(QObject *parent, QSensorReadingPrivate *_d) |
|
499 : QObject(parent) |
|
500 , d(_d) |
|
501 { |
|
502 } |
|
503 |
|
504 /*! |
|
505 \fn QSensorReading::d_ptr() |
|
506 \internal |
|
507 */ |
|
508 |
|
509 /*! |
|
510 \internal |
|
511 */ |
|
512 QSensorReading::~QSensorReading() |
|
513 { |
|
514 } |
|
515 |
|
516 /*! |
|
517 \property QSensorReading::timestamp |
|
518 \brief the timestamp of the reading. |
|
519 |
|
520 \sa qtimestamp |
|
521 */ |
|
522 |
|
523 /*! |
|
524 Returns the timestamp of the reading. |
|
525 */ |
|
526 qtimestamp QSensorReading::timestamp() const |
|
527 { |
|
528 return d->timestamp; |
|
529 } |
|
530 |
|
531 /*! |
|
532 Sets the \a timestamp of the reading. |
|
533 */ |
|
534 void QSensorReading::setTimestamp(qtimestamp timestamp) |
|
535 { |
|
536 d->timestamp = timestamp; |
|
537 } |
|
538 |
|
539 /*! |
|
540 Returns the number of extra properties that the reading has. |
|
541 |
|
542 Note that this does not count properties declared in QSensorReading. |
|
543 |
|
544 As an example, this returns 3 for QAccelerometerReading because |
|
545 there are 3 properties defined in that class. |
|
546 */ |
|
547 int QSensorReading::valueCount() const |
|
548 { |
|
549 const QMetaObject *mo = metaObject(); |
|
550 return mo->propertyCount() - mo->propertyOffset(); |
|
551 } |
|
552 |
|
553 /*! |
|
554 Returns the value of the property at \a index. |
|
555 |
|
556 Note that this function is slower than calling the data function directly. |
|
557 Consider the following statement that provides the best performance. |
|
558 |
|
559 \code |
|
560 QAccelerometerReading *reading = ...; |
|
561 qreal x = reading->x(); |
|
562 \endcode |
|
563 |
|
564 The slowest way to access a property is via name. To do this you must call |
|
565 QObject::property(). |
|
566 |
|
567 \code |
|
568 qreal x = reading->property("x").value<qreal>(); |
|
569 \endcode |
|
570 |
|
571 This is about 20 times slower than simply calling x(). There are 3 costs here. |
|
572 |
|
573 \list |
|
574 \o The cost of the string comparison. |
|
575 \o The cost of using the meta-object system. |
|
576 \o The cost of converting to/from QVariant. |
|
577 \endlist |
|
578 |
|
579 By looking up the property via numeric index, the string comparison cost is |
|
580 removed. |
|
581 |
|
582 \code |
|
583 qreal x = reading->value(0).value<qreal>(); |
|
584 \endcode |
|
585 |
|
586 While faster than name-based lookup this is still about 20 times slower than |
|
587 simply calling x(). |
|
588 |
|
589 Reading classes can opt to re-implement this function and bypass the |
|
590 meta-object system. If this is done this function will be about 3 times slower |
|
591 than simply calling x(). |
|
592 |
|
593 \sa valueCount(), QObject::property() |
|
594 */ |
|
595 QVariant QSensorReading::value(int index) const |
|
596 { |
|
597 // get them meta-object |
|
598 const QMetaObject *mo = metaObject(); |
|
599 |
|
600 // determine the index of the property we want |
|
601 index += mo->propertyOffset(); |
|
602 |
|
603 // get the meta-property |
|
604 QMetaProperty property = mo->property(index); |
|
605 |
|
606 // read the property |
|
607 return property.read(this); |
|
608 } |
|
609 |
|
610 /* |
|
611 \fn QSensorReading::value(int index) const |
|
612 |
|
613 Returns the value of the property at \a index. |
|
614 */ |
|
615 |
|
616 /*! |
|
617 \fn QSensorReading::copyValuesFrom(QSensorReading *other) |
|
618 \internal |
|
619 |
|
620 Copy values from other into this reading. Implemented by sub-classes |
|
621 using the DECLARE_READING() and IMPLEMENT_READING() macros. |
|
622 |
|
623 Note that this method should only be called by QSensorBackend. |
|
624 */ |
|
625 |
|
626 /*! |
|
627 \macro DECLARE_READING(classname) |
|
628 \relates QSensorReading |
|
629 \brief The DECLARE_READING macro adds some required methods to a reading class. |
|
630 |
|
631 This macro should be used for all reading classes. Pass the \a classname of your reading class. |
|
632 |
|
633 \code |
|
634 class MyReading : public QSensorReading |
|
635 { |
|
636 Q_OBJECT |
|
637 Q_PROPERTY(qreal myprop READ myprop) |
|
638 DECLARE_READING(MyReading) |
|
639 public: |
|
640 qreal myprop() const; |
|
641 vod setMyprop(qreal myprop); |
|
642 }; |
|
643 \endcode |
|
644 |
|
645 \sa IMPLEMENT_READING() |
|
646 */ |
|
647 |
|
648 /*! |
|
649 \macro IMPLEMENT_READING(classname) |
|
650 \relates QSensorReading |
|
651 \brief The IMPLEMENT_READING macro implements the required methods for a reading class. |
|
652 |
|
653 This macro should be used for all reading classes. It should be placed into a single compilation |
|
654 unit (source file), not into a header file. Pass the \a classname of your reading class. |
|
655 |
|
656 \code |
|
657 IMPLEMENT_READING(MyReading) |
|
658 \endcode |
|
659 |
|
660 \sa DECLARE_READING() |
|
661 */ |
|
662 |
|
663 #include "moc_qsensor.cpp" |
|
664 QTM_END_NAMESPACE |
|
665 |