src/sensors/qsensor.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     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