Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #include "qsensor.h"
++ #include "qsensor_p.h"
++ #include "qsensorbackend.h"
++ #include "qsensormanager.h"
++ #include <QDebug>
++ #include <QMetaProperty>
++ #include <QTimer>
++
++ QT_BEGIN_NAMESPACE
++
++ /*!
++ \typedef qrange
++ \relates QSensor
++ \since 5.1
++
++ This type is defined as a QPair.
++
++ \code
++ typedef QPair<int,int> qrange;
++ \endcode
++
++ \sa QPair, qrangelist, QSensor::availableDataRates
++ */
++
++ /*!
++ \typedef qrangelist
++ \relates QSensor
++ \since 5.1
++
++ This type is defined as a list of qrange values.
++
++ \code
++ typedef QList<qrange> qrangelist;
++ \endcode
++
++ \sa QList, qrange, QSensor::availableDataRates
++ */
++
++ /*!
++ \class qoutputrange
++ \inmodule QtSensors
++ \brief The qoutputrange class holds the specifics of an output range.
++ \since 5.1
++
++ The class is defined as a simple struct.
++
++ \code
++ struct qoutputrange
++ {
++ qreal maximum;
++ qreal minimum;
++ qreal accuracy;
++ };
++ \endcode
++
++ Each output range specifies a minimum and maximum value as well as an accuracy value.
++ The accuracy value represents the resolution of the sensor. It is the smallest change
++ the sensor can detect and is expressed using the same units as the minimum and maximum.
++
++ Sensors must often trade off range for accuracy. To allow the user to determine which of
++ these are more important the sensor may offer several output ranges. One output
++ range may have reduced minimum and maximum values and increased sensitivity. Another output
++ range may have higher minimum and maximum values with reduced sensitivity. Note that higher
++ sensitivities will be represented by smaller accuracy values.
++
++ An example of this tradeoff can be seen by examining the LIS302DL accelerometer. It has only
++ 256 possible values to report with. These values are scaled so that they can represent either
++ -2G to +2G (with an accuracy value of 0.015G) or -8G to +8G (with an accuracy value of 0.06G).
++
++ \sa qoutputrangelist, QSensor::outputRanges
++ */
++
++ /*!
++ \variable qoutputrange::maximum
++
++ This is the maximum value for this output range.
++ The units are defined by the sensor.
++ */
++
++ /*!
++ \variable qoutputrange::minimum
++
++ This is the minimum value for this output range.
++ The units are defined by the sensor.
++ */
++
++ /*!
++ \variable qoutputrange::accuracy
++
++ The accuracy value represents the resolution of the sensor. It is the smallest change
++ the sensor can detect and is expressed using the same units as the minimum and maximum.
++ */
++
++ /*!
++ \typedef qoutputrangelist
++ \relates QSensor
++ \since 5.1
++
++ This type is defined as a list of qoutputrange values.
++
++ \code
++ typedef QList<qoutputrange> qoutputrangelist;
++ \endcode
++
++ \sa QList, qoutputrange, QSensor::outputRanges
++ */
++
++ static void registerTypes()
++ {
++ qRegisterMetaType<qrange>("qrange");
++ qRegisterMetaType<qrangelist>("qrangelist");
++ qRegisterMetaType<qoutputrangelist>("qoutputrangelist");
++ }
++ Q_CONSTRUCTOR_FUNCTION(registerTypes)
++
++ // =====================================================================
++
++ void QSensorPrivate::init(const QByteArray &sensorType)
++ {
++ Q_Q(QSensor);
++ type = sensorType;
++ q->registerInstance(); // so the availableSensorsChanged() signal works
++ }
++
++ /*!
++ \class QSensor
++ \ingroup sensors_main
++ \inmodule QtSensors
++ \since 5.1
++
++ \brief The QSensor class represents a single hardware sensor.
++
++ The life cycle of a sensor is typically:
++
++ \list
++ \li Create a sub-class of QSensor on the stack or heap.
++ \li Setup as required by the application.
++ \li Start receiving values.
++ \li Sensor data is used by the application.
++ \li Stop receiving values.
++ \endlist
++
++ The sensor data is delivered via QSensorReading and its sub-classes.
++
++ \section1 Orientation
++
++ Some sensors react to screen orientation changes, such as QAccelerometer, QMagnetometer and
++ QRotationSensor. These are so called \e orientable sensors. For orientable sensors,
++ QSensor supports changing the reporting of the reading values based on the orientation of the
++ screen.
++
++ For orientable sensors, the axesOrientationMode property controls how the orientation affects
++ the reading values.
++
++ In the default mode, QSensor::FixedOrientation, the reading values remain
++ unaffected by the orientation. In the QSensor::AutomaticOrientation mode, the reading
++ values are automatically rotated by taking the current screen orientation into account. And
++ finally, in the QSensor::UserOrientation mode, the reading values are rotated
++ according to a user-specified orientation.
++
++ The functionality of this is only available if it is supported by the backend and if the sensor
++ is orientable, which can be checked by calling QSensor::isFeatureSupported()
++ with the QSensor::AxesOrientation flag.
++
++ The orientation values here are always of the screen orientation, not the device orientation.
++ The screen orientation is the orientation of the GUI. For example when rotating a device by 90
++ degrees counter-clockwise, the screen orientation compensates for that by rotating 90 degrees
++ clockwise, to the effect that the GUI is still facing upright after the device has been rotated.
++ Note that applications can lock the screen orientation, for example to force portrait or landscape
++ mode. For locked orientations, orientable sensors will not react with reading changes if the device
++ orientation is changed, as orientable sensors react to screen orientation changes only. This makes
++ sense, as the purpose of orientable sensors is to keep the sensor orientation in sync with the screen
++ orientation.
++
++ The orientation values range from 0 to 270 degrees. The orientation is applied in clockwise direction,
++ e.g. an orientation value of 90 degrees means that the screen has been rotated 90 degress to the right
++ from its origin position, to compensate a device rotation of 90 degrees to the left.
++
++ \sa QSensorReading
++ */
++
++ /*!
++ \enum QSensor::Feature
++ \brief Lists optional features a backend might support.
++
++ The features common to all sensor types are:
++
++ \value Buffering The backend supports buffering of readings, controlled by the
++ QSensor::bufferSize property.
++ \value AlwaysOn The backend supports changing the policy on whether to suspend when idle,
++ controlled by the QSensor::alwaysOn property.
++ \value SkipDuplicates The backend supports skipping of same or very similar successive
++ readings. This can be enabled by setting the QSensor::skipDuplicates
++ property to true.
++
++ The features of QMagnetometer are:
++
++ \value GeoValues The backend supports returning geo values, which can be
++ controlled with the QMagnetometer::returnGeoValues property.
++
++ The features of QLightSensor are:
++
++ \value FieldOfView The backend specifies its field of view, which can be
++ read from the QLightSensor::fieldOfView property.
++
++ The features of QAccelerometer are:
++
++ \value AccelerationMode The backend supports switching the acceleration mode
++ of the acceleromter with the QAccelerometer::accelerationMode property.
++
++ The features of QPressureSensor are:
++
++ \value PressureSensorTemperature The backend provides the pressure sensor's die temperature
++
++ The features of all orientable sensors are:
++
++ \value AxesOrientation The backend supports changing the axes orientation from the default of
++ QSensor::FixedOrientation to something else.
++
++ \omitvalue Reserved
++
++ \sa QSensor::isFeatureSupported()
++ \since 5.0
++ */
++
++ /*!
++ Construct the \a type sensor as a child of \a parent.
++
++ Do not use this constructor if a derived class exists for the specific sensor type.
++
++ The wrong way is to use the base class constructor:
++ \snippet sensors/creating.cpp 3
++ The right way is to create an instance of the derived class:
++ \snippet sensors/creating.cpp 2
++
++ The derived classes have
++ additional properties and data members which are needed for certain features such as
++ geo value support in QMagnetometer or acceleration mode support in QAccelerometer.
++ These features will only work properly when creating a sensor instance from a QSensor
++ subclass.
++
++ Only use this constructor if there is no derived sensor class available. Note that all
++ built-in sensors have a derived class, so using this constructor should only be necessary
++ when implementing custom sensors.
++ */
++ QSensor::QSensor(const QByteArray &type, QObject *parent)
++ : QObject(*new QSensorPrivate, parent)
++ {
++ Q_D(QSensor);
++ d->init(type);
++ }
++
++ /*! \internal
++ */
++ QSensor::QSensor(const QByteArray &type, QSensorPrivate &dd, QObject* parent)
++ : QObject(dd, parent)
++ {
++ Q_D(QSensor);
++ d->init(type);
++ }
++
++ /*! \internal
++ */
++ QSensorBackend *QSensor::backend() const
++ {
++ Q_D(const QSensor);
++ return d->backend;
++ }
++
++ /*!
++ Destroy the sensor. Stops the sensor if it has not already been stopped.
++ */
++ QSensor::~QSensor()
++ {
++ Q_D(QSensor);
++ stop();
++ for (QSensorFilter *filter : d->filters)
++ filter->setSensor(0);
++ delete d->backend;
++ d->backend = 0;
++ // owned by the backend
++ d->device_reading = 0;
++ d->filter_reading = 0;
++ d->cache_reading = 0;
++ }
++
++ /*!
++ \property QSensor::connectedToBackend
++ \brief a value indicating if the sensor has connected to a backend.
++
++ A sensor that has not been connected to a backend cannot do anything useful.
++
++ Call the connectToBackend() method to force the sensor to connect to a backend
++ immediately. This is automatically called if you call start() so you only need
++ to do this if you need access to sensor properties (ie. to poll the sensor's
++ meta-data before you use it).
++ */
++
++ bool QSensor::isConnectedToBackend() const
++ {
++ Q_D(const QSensor);
++ return (d->backend != 0);
++ }
++
++ /*!
++ \property QSensor::identifier
++ \brief the backend identifier for the sensor.
++
++ Note that the identifier is filled out automatically
++ when the sensor is connected to a backend. If you want
++ to connect a specific backend, you should call
++ setIdentifier() before connectToBackend().
++ */
++
++ QByteArray QSensor::identifier() const
++ {
++ Q_D(const QSensor);
++ return d->identifier;
++ }
++
++ void QSensor::setIdentifier(const QByteArray &identifier)
++ {
++ Q_D(QSensor);
++ if (isConnectedToBackend()) {
++ qWarning() << "ERROR: Cannot call QSensor::setIdentifier while connected to a backend!";
++ return;
++ }
++ if (d->identifier == identifier)
++ return;
++ d->identifier = identifier;
++ emit identifierChanged();
++ }
++
++ /*!
++ \property QSensor::type
++ \brief the type of the sensor.
++ */
++
++ QByteArray QSensor::type() const
++ {
++ Q_D(const QSensor);
++ return d->type;
++ }
++
++ /*!
++ Try to connect to a sensor backend.
++
++ Returns true if a suitable backend could be found, false otherwise.
++
++ The type must be set before calling this method if you are using QSensor directly.
++
++ \sa isConnectedToBackend()
++ */
++ bool QSensor::connectToBackend()
++ {
++ Q_D(QSensor);
++ if (isConnectedToBackend())
++ return true;
++
++ int dataRate = d->dataRate;
++ int outputRange = d->outputRange;
++
++ d->backend = QSensorManager::createBackend(this);
++
++ if (d->backend) {
++ // Reset the properties to their default values and re-set them now so
++ // that the logic we've put into the setters gets called.
++ if (dataRate != 0) {
++ d->dataRate = 0;
++ setDataRate(dataRate);
++ }
++ if (outputRange != -1) {
++ d->outputRange = -1;
++ setOutputRange(outputRange);
++ }
++ }
++
++ return isConnectedToBackend();
++ }
++
++ /*!
++ \property QSensor::busy
++ \brief a value to indicate if the sensor is busy.
++
++ Some sensors may be on the system but unavailable for use.
++ This function will return true if the sensor is busy. You
++ will not be able to start() the sensor.
++
++ Note that this function does not return true if you
++ are using the sensor, only if another process is using
++ the sensor.
++
++ \sa busyChanged()
++ */
++
++ bool QSensor::isBusy() const
++ {
++ Q_D(const QSensor);
++ return d->busy;
++ }
++
++ /*!
++ \fn QSensor::busyChanged()
++
++ This signal is emitted when the sensor is no longer busy.
++ This can be used to grab a sensor when it becomes available.
++
++ \code
++ sensor.start();
++ if (sensor.isBusy()) {
++ // need to wait for busyChanged signal and try again
++ }
++ \endcode
++ */
++
++ /*!
++ \property QSensor::active
++ \brief a value to indicate if the sensor is active.
++
++ This is true if the sensor is active (returning values). This is false otherwise.
++
++ Note that setting this value to true will not have an immediate effect. Instead,
++ the sensor will be started once the event loop has been reached.
++ */
++ void QSensor::setActive(bool active)
++ {
++ if (active == isActive())
++ return;
++
++ if (active)
++ QTimer::singleShot(0, this, SLOT(start())); // delay ensures all properties have been set if using QML
++ else
++ stop();
++ }
++
++ bool QSensor::isActive() const
++ {
++ Q_D(const QSensor);
++ return d->active;
++ }
++
++ /*!
++ \property QSensor::alwaysOn
++ \brief a value to indicate if the sensor should remain running when the screen is off.
++
++ Some platforms have a policy of suspending sensors when the screen turns off.
++ Setting this property to true will ensure the sensor continues to run.
++ */
++ /*!
++ \fn QSensor::alwaysOnChanged()
++
++ This signal is emitted when the alwaysOn property changes.
++ */
++ void QSensor::setAlwaysOn(bool alwaysOn)
++ {
++ Q_D(QSensor);
++ if (d->alwaysOn == alwaysOn) return;
++ d->alwaysOn = alwaysOn;
++ emit alwaysOnChanged();
++ }
++
++ bool QSensor::isAlwaysOn() const
++ {
++ Q_D(const QSensor);
++ return d->alwaysOn;
++ }
++
++ /*!
++ \property QSensor::skipDuplicates
++ \brief Indicates whether duplicate reading values should be omitted.
++ \since 5.1
++
++ When duplicate skipping is enabled, successive readings with the same or very
++ similar values are omitted. This helps reducing the amount of processing done, as less sensor
++ readings are made available. As a consequence, readings arrive at an irregular interval.
++
++ Duplicate skipping is not just enabled for readings that are exactly the same, but also for
++ readings that are quite similar, as each sensor has a bit of jitter even if the device is
++ not moved.
++
++ Support for this property depends on the backend. Use isFeatureSupported() to check if it is
++ supported on the current platform.
++
++ Duplicate skipping is disabled by default.
++
++ Duplicate skipping takes effect when the sensor is started, changing the property while the
++ sensor is active has no immediate effect.
++ */
++ bool QSensor::skipDuplicates() const
++ {
++ Q_D(const QSensor);
++ return d->skipDuplicates;
++ }
++
++ /*!
++ Sets the duplicate skipping to \a skipDuplicates.
++
++ \since 5.1
++ */
++ void QSensor::setSkipDuplicates(bool skipDuplicates)
++ {
++ Q_D(QSensor);
++ if (d->skipDuplicates != skipDuplicates) {
++ d->skipDuplicates = skipDuplicates;
++ emit skipDuplicatesChanged(skipDuplicates);
++ }
++ }
++
++ /*!
++ \fn QSensor::skipDuplicatesChanged(bool skipDuplicates)
++ \since 5.1
++
++ This signal is emitted when the \a skipDuplicates property changes.
++ */
++
++ /*!
++ \property QSensor::availableDataRates
++ \brief the data rates that the sensor supports.
++
++ This is a list of the data rates that the sensor supports.
++ Measured in Hertz.
++
++ Entries in the list can represent discrete rates or a
++ continuous range of rates.
++ A discrete rate is noted by having both values the same.
++
++ Note that this information is not mandatory as not all sensors have a rate at which
++ they run. In such cases, the list will be empty.
++
++ \sa QSensor::dataRate, qrangelist
++ */
++
++ qrangelist QSensor::availableDataRates() const
++ {
++ Q_D(const QSensor);
++ return d->availableDataRates;
++ }
++
++ /*!
++ \property QSensor::dataRate
++ \brief the data rate that the sensor should be run at.
++
++ Measured in Hertz.
++
++ The data rate is the maximum frequency at which the sensor can detect changes.
++
++ Setting this property is not portable and can cause conflicts with other
++ applications. Check with the sensor backend and platform documentation for
++ any policy regarding multiple applications requesting a data rate.
++
++ The default value (0) means that the app does not care what the data rate is.
++ Applications should consider using a timer-based poll of the current value or
++ ensure that the code that processes values can run very quickly as the platform
++ may provide updates hundreds of times each second.
++
++ This should be set before calling start() because the sensor may not
++ notice changes to this value while it is running.
++
++ Note that there is no mechanism to determine the current data rate in use by the
++ platform.
++
++ \sa QSensor::availableDataRates
++ */
++
++ int QSensor::dataRate() const
++ {
++ Q_D(const QSensor);
++ return d->dataRate;
++ }
++
++ void QSensor::setDataRate(int rate)
++ {
++ Q_D(QSensor);
++ if (d->dataRate != rate) {
++ d->dataRate = rate;
++ emit dataRateChanged();
++ }
++ }
++
++ /*!
++ Checks if a specific feature is supported by the backend.
++
++ \l[Cpp]{QtSensors} supports a rich API for controlling and providing information about sensors.
++ Naturally, not all of this functionality can be supported by all of the backends.
++
++ To check if the current backend supports the feature \a feature, call this function.
++
++ The backend needs to be connected, otherwise false will be returned. Calling connectToBackend()
++ or start() will create a connection to the backend.
++
++ Backends have to implement QSensorBackend::isFeatureSupported() to make this work.
++
++ Returns whether or not the feature is supported if the backend is connected, or false if the backend is not connected.
++ \since 5.0
++ */
++ bool QSensor::isFeatureSupported(Feature feature) const
++ {
++ Q_D(const QSensor);
++ return d->backend && d->backend->isFeatureSupported(feature);
++ }
++
++ /*!
++ Start retrieving values from the sensor.
++ Returns true if the sensor was started, false otherwise.
++
++ The sensor may fail to start for several reasons.
++
++ Once an application has started a sensor it must wait until the sensor receives a
++ new value before it can query the sensor's values. This is due to how the sensor
++ receives values from the system. Sensors do not (in general) poll for new values,
++ rather new values are pushed to the sensors as they happen.
++
++ For example, this code will not work as intended.
++
++ \badcode
++ sensor->start();
++ sensor->reading()->x(); // no data available
++ \endcode
++
++ To work correctly, the code that accesses the reading should ensure the
++ readingChanged() signal has been emitted.
++
++ \code
++ connect(sensor, SIGNAL(readingChanged()), this, SLOT(checkReading()));
++ sensor->start();
++ }
++ void MyClass::checkReading() {
++ sensor->reading()->x();
++ \endcode
++
++ \sa QSensor::busy
++ */
++ bool QSensor::start()
++ {
++ Q_D(QSensor);
++ if (isActive())
++ return true;
++ if (!connectToBackend())
++ return false;
++ // Set these flags to their defaults
++ d->active = true;
++ d->busy = false;
++ // Backend will update the flags appropriately
++ d->backend->start();
++ Q_EMIT activeChanged();
++ return isActive();
++ }
++
++ /*!
++ Stop retrieving values from the sensor.
++
++ This releases the sensor so that other processes can use it.
++
++ \sa QSensor::busy
++ */
++ void QSensor::stop()
++ {
++ Q_D(QSensor);
++ if (!isConnectedToBackend() || !isActive())
++ return;
++ d->active = false;
++ d->backend->stop();
++ Q_EMIT activeChanged();
++ }
++
++ /*!
++ \property QSensor::reading
++ \brief the reading class.
++
++ The reading class provides access to sensor readings. The reading object
++ is a volatile cache of the most recent sensor reading that has been received
++ so the application should process readings immediately or save the values
++ somewhere for later processing.
++
++ Note that this will return 0 until a sensor backend is connected to a backend.
++
++ Also note that readings are not immediately available after start() is called.
++ Applications must wait for the readingChanged() signal to be emitted.
++
++ \sa isConnectedToBackend(), start()
++ */
++
++ QSensorReading *QSensor::reading() const
++ {
++ Q_D(const QSensor);
++ return d->cache_reading;
++ }
++
++ /*!
++ Add a \a filter to the sensor.
++
++ The sensor does not take ownership of the filter.
++ QSensorFilter will inform the sensor if it is destroyed.
++
++ \sa QSensorFilter
++ */
++ void QSensor::addFilter(QSensorFilter *filter)
++ {
++ Q_D(QSensor);
++ if (!filter) {
++ qWarning() << "addFilter: passed a null filter!";
++ return;
++ }
++ filter->setSensor(this);
++ d->filters << filter;
++ }
++
++ /*!
++ Remove \a filter from the sensor.
++
++ \sa QSensorFilter
++ */
++ void QSensor::removeFilter(QSensorFilter *filter)
++ {
++ Q_D(QSensor);
++ if (!filter) {
++ qWarning() << "removeFilter: passed a null filter!";
++ return;
++ }
++ d->filters.removeOne(filter);
++ filter->setSensor(0);
++ }
++
++ /*!
++ Returns the filters currently attached to the sensor.
++
++ \sa QSensorFilter
++ */
++ QList<QSensorFilter*> QSensor::filters() const
++ {
++ Q_D(const QSensor);
++ return d->filters;
++ }
++
++ /*!
++ \fn QSensor::readingChanged()
++
++ This signal is emitted when a new sensor reading is received.
++
++ The sensor reading can be found in the QSensor::reading property. Note that the
++ reading object is a volatile cache of the most recent sensor reading that has
++ been received so the application should process the reading immediately or
++ save the values somewhere for later processing.
++
++ Before this signal has been emitted for the first time, the reading object will
++ have uninitialized data.
++
++ \sa start()
++ */
++
++ /*!
++ \fn QSensor::activeChanged()
++
++ This signal is emitted when the QSensor::active property has changed.
++
++ \sa QSensor::active
++ */
++
++ /*!
++ \property QSensor::outputRanges
++ \brief a list of output ranges the sensor supports.
++
++ A sensor may have more than one output range. Typically this is done
++ to give a greater measurement range at the cost of lowering accuracy.
++
++ Note that this information is not mandatory. This information is typically only
++ available for sensors that have selectable output ranges (such as typical
++ accelerometers).
++
++ \sa QSensor::outputRange, qoutputrangelist
++ */
++
++ qoutputrangelist QSensor::outputRanges() const
++ {
++ Q_D(const QSensor);
++ return d->outputRanges;
++ }
++
++ /*!
++ \property QSensor::outputRange
++ \brief the output range in use by the sensor.
++
++ This value represents the index in the QSensor::outputRanges list to use.
++
++ Setting this property is not portable and can cause conflicts with other
++ applications. Check with the sensor backend and platform documentation for
++ any policy regarding multiple applications requesting an output range.
++
++ The default value (-1) means that the app does not care what the output range is.
++
++ Note that there is no mechanism to determine the current output range in use by the
++ platform.
++
++ \sa QSensor::outputRanges
++ */
++
++ int QSensor::outputRange() const
++ {
++ Q_D(const QSensor);
++ return d->outputRange;
++ }
++
++ void QSensor::setOutputRange(int index)
++ {
++ Q_D(QSensor);
++ if (index == -1 || !isConnectedToBackend()) {
++ d->outputRange = index;
++ return;
++ }
++ bool warn = true;
++ if (index >= 0 && index < d->outputRanges.size()) {
++ warn = false;
++ d->outputRange = index;
++ }
++ if (warn) {
++ qWarning() << "setOutputRange:" << index << "is not supported by the sensor.";
++ }
++ }
++
++ /*!
++ \property QSensor::description
++ \brief a descriptive string for the sensor.
++ */
++
++ QString QSensor::description() const
++ {
++ Q_D(const QSensor);
++ return d->description;
++ }
++
++ /*!
++ \property QSensor::error
++ \brief the last error code set on the sensor.
++
++ Note that error codes are sensor-specific.
++ */
++
++ int QSensor::error() const
++ {
++ Q_D(const QSensor);
++ return d->error;
++ }
++
++ /*!
++ \enum QSensor::AxesOrientationMode
++ \since 5.1
++
++ Describes how reading values are affected by the screen orientation.
++
++ \value FixedOrientation No automatic rotation is applied to the reading values.
++
++ \value AutomaticOrientation The reading values are automatically rotated based on the screen
++ orientation.
++
++ \value UserOrientation The reading values are rotated based on the angle of the userOrientation property.
++
++ \sa QSensor::axesOrientationMode
++ */
++
++ /*!
++ \property QSensor::axesOrientationMode
++ \since 5.1
++ \brief The mode that affects how the screen orientation changes reading values.
++
++ When set to FixedOrientation, which is the default mode, no automatic rotation is applied to
++ the reading. This is the only mode available for backends that do not support the
++ QSensor::AxesOrientation feature.
++
++ When set to AutomaticOrientation, the reading values are automatically rotated when the
++ screen orientation changes. In effect, the screen orientation is canceled out.
++
++ As an example, assume the device is rotated by 180 degrees and therefore the screen orientation
++ also is rotated by 180 degrees from the native orientation. Without automatic axes orientation,
++ the reading values would now be changed: Both the X and the Y values would be negated, forcing
++ an application developer to manually cancel out the negation in application code. Automatic
++ axes orientation does this automatically, in this mode the X and Y values would be the same as
++ with the default screen orientation.
++
++ This automatic rotation of the axes is handy is some usecases, for example in a bubble level
++ application that measures how level a surface is by looking at the X axis value of an
++ accelerometer. When the device and screen orientation change by 90 degrees, an application
++ developer does not need to change anything, he can continue using the X axis value even though
++ the device is rotated. Without automatic axes orientation, the application developer would need
++ to look at the Y values instead, thereby adding code to the application that reads from a
++ different axis depending on the screen orientation.
++
++ The UserOrientation mode is quite similar to AutomaticOrientation, only that the screen orientation
++ is manually controlled instead of automatically determined. The angle of the userOrientation
++ property is then used for rotating the reading values.
++
++ Since the rotation of the reading values is based on the screen orientation, Z values will never
++ change, as the Z axis is perpendicular to the screen.
++ As screen orientation changes in 90 degree steps, rotating the reading values is also done in
++ steps of 90 degrees.
++
++ This property is only used for orientable sensors.
++ */
++
++ QSensor::AxesOrientationMode QSensor::axesOrientationMode() const
++ {
++ Q_D(const QSensor);
++ return d->axesOrientationMode;
++ }
++
++ void QSensor::setAxesOrientationMode(QSensor::AxesOrientationMode axesOrientationMode)
++ {
++ Q_D(QSensor);
++ if (d->axesOrientationMode != axesOrientationMode) {
++ d->axesOrientationMode = axesOrientationMode;
++ emit axesOrientationModeChanged(axesOrientationMode);
++ }
++ }
++
++ /*!
++ \property QSensor::currentOrientation
++ \since 5.1
++ \brief The current orientation that is used for rotating the reading values.
++
++ This might not be the same as the screen orientation. For example, in the FixedOrientation mode,
++ the reading values are not rotated, and therefore the property is 0.
++
++ In the UserOrientation mode, the readings are rotated based on the userOrientation property,
++ and therefore this property is equal to the userOrientation property.
++
++ In the AutomaticOrientation mode, the readings are rotated based on the screen orientation,
++ and therefore this property will be equal to the current screen orientation.
++
++ This property is set by the backend and only valid for orientable sensors.
++ */
++
++ int QSensor::currentOrientation() const
++ {
++ Q_D(const QSensor);
++ return d->currentOrientation;
++ }
++
++ /*!
++ \since 5.1
++ Sets the current screen orientation to \a currentOrientation. This is to be called from the
++ backend whenever the screen orientation or the userOrientation property changes.
++ */
++ void QSensor::setCurrentOrientation(int currentOrientation)
++ {
++ Q_D(QSensor);
++ if (d->currentOrientation != currentOrientation) {
++ d->currentOrientation = currentOrientation;
++ emit currentOrientationChanged(currentOrientation);
++ }
++ }
++
++ /*!
++ \property QSensor::userOrientation
++ \since 5.1
++ \brief The angle used for rotating the reading values in the UserOrientation mode.
++
++ When the axesOrientationMode property is set to UserOrientation, the angle for rotating the
++ reading values is taken from this property. In other modes, the property has no effect.
++
++ The default is 0. The only valid values are 0, 90, 180 and 270, as those are the only possible
++ screen orientations.
++
++ This property is only valid for orientable sensors.
++ */
++
++ int QSensor::userOrientation() const
++ {
++ Q_D(const QSensor);
++ return d->userOrientation;
++ }
++
++ void QSensor::setUserOrientation(int userOrientation)
++ {
++ Q_D(QSensor);
++ if (d->userOrientation != userOrientation) {
++ d->userOrientation = userOrientation;
++ emit userOrientationChanged(userOrientation);
++ }
++ }
++
++ /*!
++ \fn QSensor::sensorError(int error)
++
++ This signal is emitted when an \a error code is set on the sensor.
++ Note that some errors will cause the sensor to stop working.
++ You should call isActive() to determine if the sensor is still running.
++ */
++
++ /*!
++ \fn QSensor::availableSensorsChanged()
++
++ This signal is emitted when the list of available sensors has changed.
++ The sensors available to a program will not generally change over time
++ however some of the available sensors may represent hardware that is not
++ permanently connected. For example, a game controller that is connected
++ via bluetooth would become available when it was on and would become
++ unavailable when it was off.
++
++ \sa QSensor::sensorTypes(), QSensor::sensorsForType()
++ */
++
++ /*!
++ \property QSensor::maxBufferSize
++
++ The property holds the maximum buffer size.
++
++ Note that this may be 1, in which case the sensor does not support any form of buffering.
++ In that case, isFeatureSupported(QSensor::Buffering) will also return false.
++
++ \sa QSensor::bufferSize, QSensor::efficientBufferSize
++ */
++
++ int QSensor::maxBufferSize() const
++ {
++ Q_D(const QSensor);
++ return d->maxBufferSize;
++ }
++
++ /*!
++ \since 5.1
++ Sets the maximum buffer size to \a maxBufferSize. This is to be called from the
++ backend.
++ */
++ void QSensor::setMaxBufferSize(int maxBufferSize)
++ {
++ Q_D(QSensor);
++ if (d->maxBufferSize != maxBufferSize) {
++ d->maxBufferSize = maxBufferSize;
++ emit maxBufferSizeChanged(maxBufferSize);
++ }
++ }
++
++ /*!
++ \property QSensor::efficientBufferSize
++
++ The property holds the most efficient buffer size. Normally this is 1 (which means
++ no particular size is most efficient). Some sensor drivers have a FIFO buffer which
++ makes it more efficient to deliver the FIFO's size worth of readings at one time.
++
++ \sa QSensor::bufferSize, QSensor::maxBufferSize
++ */
++
++ int QSensor::efficientBufferSize() const
++ {
++ Q_D(const QSensor);
++ return d->efficientBufferSize;
++ }
++
++ /*!
++ \since 5.1
++ Sets the efficient buffer size to \a efficientBufferSize. This is to be called from the
++ backend.
++ */
++ void QSensor::setEfficientBufferSize(int efficientBufferSize)
++ {
++ Q_D(QSensor);
++ if (d->efficientBufferSize != efficientBufferSize) {
++ d->efficientBufferSize = efficientBufferSize;
++ emit efficientBufferSizeChanged(efficientBufferSize);
++ }
++ }
++
++ /*!
++ \property QSensor::bufferSize
++
++ This property holds the size of the buffer. By default, the buffer size is 1,
++ which means no buffering.
++ If the maximum buffer size is 1, then buffering is not supported
++ by the sensor.
++
++ Setting bufferSize greater than maxBufferSize will cause maxBufferSize to be used.
++
++ Buffering is turned on when bufferSize is greater than 1. The sensor will collect
++ the requested number of samples and deliver them all to the application at one time.
++ They will be delivered to the application as a burst of changed readings so it is
++ particularly important that the application processes each reading immediately or
++ saves the values somewhere else.
++
++ If stop() is called when buffering is on-going, the partial buffer is not delivered.
++
++ When the sensor is started with buffering option, values are collected from that
++ moment onwards. There is no pre-existing buffer that can be utilized.
++
++ Some backends only support enabling or disabling the buffer and do not give
++ control over the size. In this case, the maxBufferSize and efficientBufferSize properties
++ might not be set at all, even though buffering is supported. Setting the bufferSize property
++ to any value greater than 1 will enable buffering. After the sensor has been started,
++ the bufferSize property will be set to the actual value by the backend.
++
++ \sa QSensor::maxBufferSize, QSensor::efficientBufferSize
++ */
++
++ int QSensor::bufferSize() const
++ {
++ Q_D(const QSensor);
++ return d->bufferSize;
++ }
++
++ void QSensor::setBufferSize(int bufferSize)
++ {
++ Q_D(QSensor);
++ if (d->bufferSize != bufferSize) {
++ d->bufferSize = bufferSize;
++ emit bufferSizeChanged(bufferSize);
++ }
++ }
++
++ // =====================================================================
++
++ /*!
++ \class QSensorFilter
++ \ingroup sensors_main
++ \inmodule QtSensors
++
++ \brief The QSensorFilter class provides an efficient
++ callback facility for asynchronous notifications of
++ sensor changes.
++
++ Some sensors (eg. the accelerometer) are often accessed very frequently.
++ This may be slowed down by the use of signals and slots.
++ The QSensorFilter interface provides a more efficient way for the
++ sensor to notify your class that the sensor has changed.
++
++ Additionally, multiple filters can be added to a sensor. They are called
++ in order and each filter has the option to modify the values in the reading
++ or to suppress the reading altogether.
++
++ Note that the values in the class returned by QSensor::reading() will
++ not be updated until after the filters have been run.
++
++ \sa filter()
++ */
++
++ /*!
++ \internal
++ */
++ QSensorFilter::QSensorFilter()
++ : m_sensor(0)
++ {
++ }
++
++ /*!
++ Notifies the attached sensor (if any) that the filter is being destroyed.
++ */
++ QSensorFilter::~QSensorFilter()
++ {
++ if (m_sensor)
++ m_sensor->removeFilter(this);
++ }
++
++ /*!
++ \fn QSensorFilter::filter(QSensorReading *reading)
++
++ This function is called when the sensor \a reading changes.
++
++ The filter can modify the reading.
++
++ Returns true to allow the next filter to receive the value.
++ If this is the last filter, returning true causes the signal
++ to be emitted and the value is stored in the sensor.
++
++ Returns false to drop the reading.
++ */
++
++ /*!
++ \internal
++ */
++ void QSensorFilter::setSensor(QSensor *sensor)
++ {
++ m_sensor = sensor;
++ }
++
++ // =====================================================================
++
++ /*!
++ \class QSensorReading
++ \ingroup sensors_main
++ \inmodule QtSensors
++
++ \brief The QSensorReading class holds the readings from the sensor.
++
++ Note that QSensorReading is not particularly useful by itself. The interesting
++ data for each sensor is defined in a sub-class of QSensorReading.
++ */
++
++ /*!
++ \internal
++ */
++ QSensorReading::QSensorReading(QObject *parent, QSensorReadingPrivate *_d)
++ : QObject(parent)
++ , d(_d?_d:new QSensorReadingPrivate)
++ {
++ }
++
++ /*!
++ \internal
++ */
++ QSensorReading::~QSensorReading()
++ {
++ }
++
++ /*!
++ \property QSensorReading::timestamp
++ \brief the timestamp of the reading.
++
++ Timestamps values are microseconds since a fixed point.
++ You can use timestamps to see how far apart two sensor readings are.
++
++ Note that sensor timestamps from different sensors may not be directly
++ comparable (as they may choose different fixed points for their reference).
++
++ \b{Note that some platforms do not deliver timestamps correctly}.
++ Applications should be prepared for occasional issues that cause timestamps to jump
++ backwards.
++ */
++
++ /*!
++ Returns the timestamp of the reading.
++ */
++ quint64 QSensorReading::timestamp() const
++ {
++ return d->timestamp;
++ }
++
++ /*!
++ Sets the \a timestamp of the reading.
++ */
++ void QSensorReading::setTimestamp(quint64 timestamp)
++ {
++ d->timestamp = timestamp;
++ }
++
++ /*!
++ Returns the number of extra properties that the reading has.
++
++ Note that this does not count properties declared in QSensorReading.
++
++ As an example, this returns 3 for QAccelerometerReading because
++ there are 3 properties defined in that class.
++ */
++ int QSensorReading::valueCount() const
++ {
++ const QMetaObject *mo = metaObject();
++ return mo->propertyCount() - mo->propertyOffset();
++ }
++
++ /*!
++ Returns the value of the property at \a index.
++
++ Note that this function is slower than calling the data function directly.
++
++ Here is an example of getting a property via the different mechanisms available.
++
++ Accessing directly provides the best performance but requires compile-time knowledge
++ of the data you are accessing.
++
++ \code
++ QAccelerometerReading *reading = ...;
++ qreal x = reading->x();
++ \endcode
++
++ You can also access a property by name. To do this you must call QObject::property().
++
++ \code
++ qreal x = reading->property("x").value<qreal>();
++ \endcode
++
++ Finally, you can access values via numeric index.
++
++ \code
++ qreal x = reading->value(0).value<qreal>();
++ \endcode
++
++ Note that value() can only access properties declared with Q_PROPERTY() in sub-classes
++ of QSensorReading.
++
++ \sa valueCount(), QObject::property()
++ */
++ QVariant QSensorReading::value(int index) const
++ {
++ // get them meta-object
++ const QMetaObject *mo = metaObject();
++
++ // determine the index of the property we want
++ index += mo->propertyOffset();
++
++ // get the meta-property
++ QMetaProperty property = mo->property(index);
++
++ // read the property
++ return property.read(this);
++ }
++
++ /*!
++ \fn QSensorReading::copyValuesFrom(QSensorReading *other)
++ \internal
++
++ Copy values from other into this reading. Implemented by sub-classes
++ using the DECLARE_READING() and IMPLEMENT_READING() macros.
++
++ Note that this method should only be called by QSensorBackend.
++ */
++ void QSensorReading::copyValuesFrom(QSensorReading *other)
++ {
++ QSensorReadingPrivate *my_ptr = d.data();
++ QSensorReadingPrivate *other_ptr = other->d.data();
++ /* Do a direct copy of the private class */
++ *(my_ptr) = *(other_ptr);
++ }
++
++ /*!
++ \fn QSensorReading::d_ptr()
++ \internal
++ No longer used. Exists to keep the winscw build happy.
++ */
++
++ /*!
++ \macro DECLARE_READING(classname)
++ \relates QSensorReading
++ \brief The DECLARE_READING macro adds some required methods to a reading class.
++
++ This macro should be used for all reading classes. Pass the \a classname of your reading class.
++
++ \snippet sensors/myreading.cpp MyReading-Declaration
++
++ \sa IMPLEMENT_READING()
++ */
++
++ /*!
++ \macro IMPLEMENT_READING(classname)
++ \relates QSensorReading
++ \brief The IMPLEMENT_READING macro implements the required methods for a reading class.
++
++ This macro should be used for all reading classes. It should be placed into a single compilation
++ unit (source file), not into a header file. Pass the \a classname of your reading class.
++
++ \snippet sensors/myreading.cpp IMPLEMENT_READING_MyReading
++
++ \sa DECLARE_READING()
++ */
++
++ QT_END_NAMESPACE