qtmobility/src/sensors/qsensor.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     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