qtmobility/src/sensors/qsensor.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 8 71781823f776
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    61     comparable (as they may choose different fixed points for their reference).
    61     comparable (as they may choose different fixed points for their reference).
    62 */
    62 */
    63 
    63 
    64 // A bit of a hack to call qRegisterMetaType when the library is loaded.
    64 // A bit of a hack to call qRegisterMetaType when the library is loaded.
    65 static int qtimestamp_id = qRegisterMetaType<QtMobility::qtimestamp>("QtMobility::qtimestamp");
    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");
    66 
    69 
    67 // =====================================================================
    70 // =====================================================================
    68 
    71 
    69 /*!
    72 /*!
    70     \class QSensor
    73     \class QSensor
    85 
    88 
    86     The sensor data is delivered via QSensorData and its sub-classes.
    89     The sensor data is delivered via QSensorData and its sub-classes.
    87 */
    90 */
    88 
    91 
    89 /*!
    92 /*!
    90     Construct the sensor as a child of \a parent.
    93     Construct the \a type sensor as a child of \a parent.
    91 */
    94 */
    92 QSensor::QSensor(QObject *parent)
    95 QSensor::QSensor(const QByteArray &type, QObject *parent)
    93     : QObject(parent)
    96     : QObject(parent)
    94     , d(new QSensorPrivate)
    97     , d(new QSensorPrivate)
    95 {
    98 {
       
    99     d->type = type;
    96 }
   100 }
    97 
   101 
    98 /*!
   102 /*!
    99     Destroy the sensor. Stops the sensor if it has not already been stopped.
   103     Destroy the sensor. Stops the sensor if it has not already been stopped.
   100 */
   104 */
   110     d->filter_reading = 0;
   114     d->filter_reading = 0;
   111     d->cache_reading = 0;
   115     d->cache_reading = 0;
   112 }
   116 }
   113 
   117 
   114 /*!
   118 /*!
   115     \property QSensor::connected
   119     \property QSensor::connectedToBackend
   116     \brief a value indicating if the sensor has connected to a backend.
   120     \brief a value indicating if the sensor has connected to a backend.
   117 
   121 
   118     A sensor that has not been connected to a backend cannot do anything useful.
   122     A sensor that has not been connected to a backend cannot do anything useful.
   119 
   123 
   120     Call the connect() method to force the sensor to connect to a backend immediately.
   124     Call the connectToBackend() method to force the sensor to connect to a backend
   121 */
   125     immediately. This is automatically called if you call start() so you only need
   122 
   126     to do this if you need access to sensor properties (ie. to poll the sensor's
   123 bool QSensor::isConnected() const
   127     meta-data before you use it).
       
   128 */
       
   129 
       
   130 bool QSensor::isConnectedToBackend() const
   124 {
   131 {
   125     return (d->backend != 0);
   132     return (d->backend != 0);
   126 }
   133 }
   127 
   134 
   128 /*!
   135 /*!
   130     \brief the backend identifier for the sensor.
   137     \brief the backend identifier for the sensor.
   131 
   138 
   132     Note that the identifier is filled out automatically
   139     Note that the identifier is filled out automatically
   133     when the sensor is connected to a backend. If you want
   140     when the sensor is connected to a backend. If you want
   134     to connect a specific backend, you should call
   141     to connect a specific backend, you should call
   135     setIdentifier() before connect().
   142     setIdentifier() before connectToBackend().
   136 */
   143 */
   137 
   144 
   138 QByteArray QSensor::identifier() const
   145 QByteArray QSensor::identifier() const
   139 {
   146 {
   140     return d->identifier;
   147     return d->identifier;
   141 }
   148 }
   142 
   149 
   143 void QSensor::setIdentifier(const QByteArray &identifier)
   150 void QSensor::setIdentifier(const QByteArray &identifier)
   144 {
   151 {
   145     Q_ASSERT(!d->backend);
   152     if (d->backend) {
       
   153         qWarning() << "ERROR: Cannot call QSensor::setIdentifier while connected to a backend!";
       
   154         return;
       
   155     }
   146     d->identifier = identifier;
   156     d->identifier = identifier;
   147 }
   157 }
   148 
   158 
   149 /*!
   159 /*!
   150     \property QSensor::type
   160     \property QSensor::type
   151     \brief the type of the sensor.
   161     \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 */
   162 */
   156 
   163 
   157 QByteArray QSensor::type() const
   164 QByteArray QSensor::type() const
   158 {
   165 {
   159     return d->type;
   166     return d->type;
   160 }
   167 }
   161 
   168 
   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 /*!
   169 /*!
   170     Try to connect to a sensor backend.
   170     Try to connect to a sensor backend.
   171 
   171 
   172     Returns true if a suitable backend could be found, false otherwise.
   172     Returns true if a suitable backend could be found, false otherwise.
   173 
   173 
   174     The type must be set before calling this method if you are using QSensor directly.
   174     The type must be set before calling this method if you are using QSensor directly.
   175 
   175 
   176     \sa isConnected()
   176     \sa isConnectedToBackend()
   177 */
   177 */
   178 bool QSensor::connect()
   178 bool QSensor::connectToBackend()
   179 {
   179 {
   180     if (d->backend)
   180     if (d->backend)
   181         return true;
   181         return true;
   182 
   182 
   183     if (d->type.isEmpty()) {
   183     int rate = d->dataRate;
   184         qWarning() << "QSensor::connect - Cannot call this method unless the type is set.";
   184     d->backend = QSensorManager::createBackend(this);
       
   185     if (rate != 0)
       
   186         setDataRate(rate);
       
   187     return (d->backend != 0);
       
   188 }
       
   189 
       
   190 /*!
       
   191     \property QSensor::busy
       
   192     \brief a value to indicate if the sensor is busy.
       
   193 
       
   194     Some sensors may be on the system but unavailable for use.
       
   195     This function will return true if the sensor is busy. You
       
   196     will not be able to start() the sensor.
       
   197 
       
   198     Note that this function does not return true if you
       
   199     are using the sensor, only if another process is using
       
   200     the sensor.
       
   201 
       
   202     \sa busyChanged()
       
   203 */
       
   204 
       
   205 bool QSensor::isBusy() const
       
   206 {
       
   207     return d->busy;
       
   208 }
       
   209 
       
   210 /*!
       
   211     \fn QSensor::busyChanged()
       
   212 
       
   213     This signal is emitted when the busy state changes. This can
       
   214     be used to grab a sensor when it becomes available.
       
   215 */
       
   216 
       
   217 /*!
       
   218     \property QSensor::active
       
   219     \brief a value to indicate if the sensor is active.
       
   220 
       
   221     This is true if the sensor is active (returning values). This is false otherwise.
       
   222 */
       
   223 
       
   224 bool QSensor::isActive() const
       
   225 {
       
   226     return d->active;
       
   227 }
       
   228 
       
   229 /*!
       
   230     \property QSensor::availableDataRates
       
   231     \brief the data rates that the sensor supports.
       
   232 
       
   233     This is a list of the data rates that the sensor supports.
       
   234     Entries in the list can represent discrete rates or a
       
   235     continuous range of rates.
       
   236     A discrete rate is noted by having both values the same.
       
   237 
       
   238     See the sensor_explorer example for an example of how to interpret and use
       
   239     this information.
       
   240 
       
   241     \sa QSensor::dataRate
       
   242 */
       
   243 
       
   244 qrangelist QSensor::availableDataRates() const
       
   245 {
       
   246     return d->availableDataRates;
       
   247 }
       
   248 
       
   249 /*!
       
   250     \property QSensor::dataRate
       
   251     \brief the data rate that the sensor should be run at.
       
   252 
       
   253     The default value is determined by the backend.
       
   254 
       
   255     This should be set before calling start() because the sensor may not
       
   256     notice changes to this value while it is running.
       
   257 
       
   258     \sa QSensor::availableDataRates
       
   259 */
       
   260 
       
   261 int QSensor::dataRate() const
       
   262 {
       
   263     return d->dataRate;
       
   264 }
       
   265 
       
   266 void QSensor::setDataRate(int rate)
       
   267 {
       
   268     bool warn = true;
       
   269     Q_FOREACH (const qrange &range, d->availableDataRates) {
       
   270         if (rate >= range.first && rate <= range.second) {
       
   271             warn = false;
       
   272             d->dataRate = rate;
       
   273             break;
       
   274         }
       
   275     }
       
   276     if (warn) {
       
   277         qWarning() << "setDataRate: rate" << rate << "is not supported by the sensor.";
       
   278     }
       
   279 }
       
   280 
       
   281 /*!
       
   282     Start retrieving values from the sensor.
       
   283     Returns true if the sensor was started, false otherwise.
       
   284 
       
   285     Note that the sensor may fail to start for several reasons.
       
   286 
       
   287     \sa QSensor::busy
       
   288 */
       
   289 bool QSensor::start()
       
   290 {
       
   291     if (d->active)
       
   292         return true;
       
   293     if (!connectToBackend())
   185         return false;
   294         return false;
   186     }
   295     if (d->availableDataRates.count() == 0)
   187 
   296         return false;
   188     d->backend = QSensorManager::createBackend(this);
   297     // Set these flags to their defaults
   189     return (d->backend != 0);
   298     d->active = true;
   190 }
   299     d->busy = false;
   191 
   300     // Backend will update the flags appropriately
   192 /*!
   301     d->backend->start();
   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;
   302     return d->active;
   203 }
   303 }
   204 
   304 
   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 /*!
   305 /*!
   356     Stop retrieving values from the sensor.
   306     Stop retrieving values from the sensor.
       
   307 
       
   308     This releases the sensor so that other processes can use it.
       
   309 
       
   310     \sa QSensor::busy
   357 */
   311 */
   358 void QSensor::stop()
   312 void QSensor::stop()
   359 {
   313 {
   360     if (!d->active || !d->backend)
   314     if (!d->active || !d->backend)
   361         return;
   315         return;
   367     \property QSensor::reading
   321     \property QSensor::reading
   368     \brief the reading class.
   322     \brief the reading class.
   369 
   323 
   370     The reading class provides access to sensor readings.
   324     The reading class provides access to sensor readings.
   371 
   325 
   372     Note that this will return 0 until a sensor backend is connected.
   326     Note that this will return 0 until a sensor backend is connected to a backend.
   373 
   327 
   374     \sa isConnected()
   328     \sa isConnectedToBackend()
   375 */
   329 */
   376 
   330 
   377 QSensorReading *QSensor::reading() const
   331 QSensorReading *QSensor::reading() const
   378 {
   332 {
   379     return d->cache_reading;
   333     return d->cache_reading;
   387 
   341 
   388     \sa QSensorFilter
   342     \sa QSensorFilter
   389 */
   343 */
   390 void QSensor::addFilter(QSensorFilter *filter)
   344 void QSensor::addFilter(QSensorFilter *filter)
   391 {
   345 {
       
   346     if (!filter) {
       
   347         qWarning() << "addFilter: passed a null filter!";
       
   348         return;
       
   349     }
   392     d->filters << filter;
   350     d->filters << filter;
   393 }
   351 }
   394 
   352 
   395 /*!
   353 /*!
   396     Remove \a filter from the sensor.
   354     Remove \a filter from the sensor.
   397 
   355 
   398     \sa QSensorFilter
   356     \sa QSensorFilter
   399 */
   357 */
   400 void QSensor::removeFilter(QSensorFilter *filter)
   358 void QSensor::removeFilter(QSensorFilter *filter)
   401 {
   359 {
       
   360     if (!filter) {
       
   361         qWarning() << "removeFilter: passed a null filter!";
       
   362         return;
       
   363     }
   402     d->filters.removeOne(filter);
   364     d->filters.removeOne(filter);
   403     filter->setSensor(0);
   365     filter->setSensor(0);
   404 }
   366 }
   405 
   367 
   406 /*!
   368 /*!
   410 
   372 
   411 /*!
   373 /*!
   412     \fn QSensor::readingChanged()
   374     \fn QSensor::readingChanged()
   413 
   375 
   414     This signal is emitted when the reading has changed.
   376     This signal is emitted when the reading has changed.
       
   377 */
       
   378 
       
   379 /*!
       
   380     \property QSensor::outputRanges
       
   381     \brief a list of output ranges the sensor supports.
       
   382 
       
   383     A sensor may have more than one output range. Typically this is done
       
   384     to give a greater measurement range at the cost of lowering accuracy.
       
   385 
       
   386     \sa QSensor::outputRange
       
   387 */
       
   388 
       
   389 qoutputrangelist QSensor::outputRanges() const
       
   390 {
       
   391     return d->outputRanges;
       
   392 }
       
   393 
       
   394 /*!
       
   395     \property QSensor::outputRange
       
   396     \brief the output range in use by the sensor.
       
   397 
       
   398     A sensor may have more than one output range. Typically this is done
       
   399     to give a greater measurement range at the cost of lowering accuracy.
       
   400 
       
   401     \sa QSensor::outputRanges
       
   402 */
       
   403 
       
   404 int QSensor::outputRange() const
       
   405 {
       
   406     return d->outputRange;
       
   407 }
       
   408 
       
   409 void QSensor::setOutputRange(int index)
       
   410 {
       
   411     if (index < 0 || index >= d->outputRanges.count()) {
       
   412         qWarning() << "ERROR: Output range" << index << "is not valid";
       
   413         return;
       
   414     }
       
   415     d->outputRange = index;
       
   416 }
       
   417 
       
   418 /*!
       
   419     \property QSensor::description
       
   420     \brief a descriptive string for the sensor.
       
   421 */
       
   422 
       
   423 QString QSensor::description() const
       
   424 {
       
   425     return d->description;
       
   426 }
       
   427 
       
   428 /*!
       
   429     \property QSensor::error
       
   430     \brief the last error code set on the sensor.
       
   431 
       
   432     Note that error codes are sensor-specific.
       
   433 */
       
   434 
       
   435 int QSensor::error() const
       
   436 {
       
   437     return d->error;
       
   438 }
       
   439 
       
   440 /*!
       
   441     \fn QSensor::sensorError(int error)
       
   442 
       
   443     This signal is emitted when an \a error code is set on the sensor.
       
   444     Note that some errors will cause the sensor to stop working.
       
   445     You should call isActive() to determine if the sensor is still running.
   415 */
   446 */
   416 
   447 
   417 // =====================================================================
   448 // =====================================================================
   418 
   449 
   419 /*!
   450 /*!
   552 
   583 
   553 /*!
   584 /*!
   554     Returns the value of the property at \a index.
   585     Returns the value of the property at \a index.
   555 
   586 
   556     Note that this function is slower than calling the data function directly.
   587     Note that this function is slower than calling the data function directly.
   557     Consider the following statement that provides the best performance.
   588 
       
   589     Here is an example of getting a property via the different mechanisms available.
       
   590 
       
   591     Accessing directly provides the best performance but requires compile-time knowledge
       
   592     of the data you are accessing.
   558 
   593 
   559     \code
   594     \code
   560     QAccelerometerReading *reading = ...;
   595     QAccelerometerReading *reading = ...;
   561     qreal x = reading->x();
   596     qreal x = reading->x();
   562     \endcode
   597     \endcode
   563 
   598 
   564     The slowest way to access a property is via name. To do this you must call
   599     You can also access a property by name. To do this you must call QObject::property().
   565     QObject::property().
       
   566 
   600 
   567     \code
   601     \code
   568     qreal x = reading->property("x").value<qreal>();
   602     qreal x = reading->property("x").value<qreal>();
   569     \endcode
   603     \endcode
   570 
   604 
   571     This is about 20 times slower than simply calling x(). There are 3 costs here.
   605     Finally, you can access values via numeric index.
   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 
   606 
   582     \code
   607     \code
   583     qreal x = reading->value(0).value<qreal>();
   608     qreal x = reading->value(0).value<qreal>();
   584     \endcode
   609     \endcode
   585 
   610 
   586     While faster than name-based lookup this is still about 20 times slower than
   611     Note that value() can only access properties declared with Q_PROPERTY() in sub-classes
   587     simply calling x().
   612     of QSensorReading.
   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 
   613 
   593     \sa valueCount(), QObject::property()
   614     \sa valueCount(), QObject::property()
   594 */
   615 */
   595 QVariant QSensorReading::value(int index) const
   616 QVariant QSensorReading::value(int index) const
   596 {
   617 {
   604     QMetaProperty property = mo->property(index);
   625     QMetaProperty property = mo->property(index);
   605 
   626 
   606     // read the property
   627     // read the property
   607     return property.read(this);
   628     return property.read(this);
   608 }
   629 }
   609 
       
   610 /*
       
   611     \fn QSensorReading::value(int index) const
       
   612 
       
   613     Returns the value of the property at \a index.
       
   614 */
       
   615 
   630 
   616 /*!
   631 /*!
   617     \fn QSensorReading::copyValuesFrom(QSensorReading *other)
   632     \fn QSensorReading::copyValuesFrom(QSensorReading *other)
   618     \internal
   633     \internal
   619 
   634