Revision control
Copy as Markdown
// 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 "qmlsensor_p.h"
#include <QtSensors/QSensor>
#include <QDebug>
#include <QtCore/private/qobject_p.h>
QT_BEGIN_NAMESPACE
class QmlSensorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QmlSensor)
public:
QList<QmlSensorRange *> availableRanges;
QList<QmlSensorOutputRange *> outputRanges;
};
template<typename Item>
qsizetype readonlyListCount(QQmlListProperty<Item> *p)
{
return static_cast<const QList<Item *> *>(p->data)->size();
}
template<typename Item>
Item *readonlyListAt(QQmlListProperty<Item> *p, qsizetype idx)
{
return static_cast<const QList<Item *> *>(p->data)->at(idx);
};
template<typename Item>
QQmlListProperty<Item> readonlyListProperty(const QObject *o, const QList<Item *> *list)
{
// Unfortunately QQmlListProperty won't accept a const object, even on the readonly ctor.
return QQmlListProperty<Item>(const_cast<QObject *>(o), const_cast<QList<Item *> *>(list),
readonlyListCount<Item>, readonlyListAt<Item>);
}
/*!
\qmltype Sensor
\nativetype QmlSensor
\inqmlmodule QtSensors
\since QtSensors 5.0
\brief The Sensor element serves as a base type for sensors.
The Sensor element serves as a base type for sensors.
This element wraps the QSensor class. Please see the documentation for
QSensor for details.
This element cannot be directly created. Please use one of the sub-classes instead.
*/
QmlSensor::QmlSensor(QObject *parent)
: QObject(*(new QmlSensorPrivate), parent)
{
}
QmlSensor::~QmlSensor()
{
}
/*!
\qmlproperty string Sensor::identifier
This property holds the backend identifier for the sensor.
Please see QSensor::identifier for information about this property.
*/
QByteArray QmlSensor::identifier() const
{
return sensor()->identifier();
}
void QmlSensor::setIdentifier(const QByteArray &identifier)
{
sensor()->setIdentifier(identifier);
}
/*!
\qmlproperty string Sensor::type
This property holds the type of the sensor.
*/
QByteArray QmlSensor::type() const
{
return sensor()->type();
}
/*!
\qmlproperty bool Sensor::connectedToBackend
This property holds a value indicating if the sensor has connected to a backend.
Please see QSensor::connectedToBackend for information about this property.
*/
bool QmlSensor::isConnectedToBackend() const
{
return sensor()->isConnectedToBackend();
}
/*!
\qmlproperty bool Sensor::busy
This property holds a value to indicate if the sensor is busy.
Please see QSensor::busy for information about this property.
*/
bool QmlSensor::isBusy() const
{
return sensor()->isBusy();
}
/*!
\qmlproperty bool Sensor::active
This property holds a value to indicate if the sensor is active.
Please see QSensor::active for information about this property.
*/
void QmlSensor::setActive(bool active)
{
if (!m_componentComplete) {
m_activateOnComplete = active;
return;
}
if (active)
sensor()->start();
else
sensor()->stop();
}
bool QmlSensor::isActive() const
{
return sensor()->isActive();
}
/*!
\qmlproperty bool Sensor::alwaysOn
This property holds a value to indicate if the sensor should remain running when the screen is off.
Please see QSensor::alwaysOn for information about this property.
*/
bool QmlSensor::isAlwaysOn() const
{
return sensor()->isAlwaysOn();
}
void QmlSensor::setAlwaysOn(bool alwaysOn)
{
sensor()->setAlwaysOn(alwaysOn);
}
/*!
\qmlproperty bool Sensor::skipDuplicates
\since QtSensors 5.1
This property indicates whether duplicate reading values should be omitted.
Please see QSensor::skipDuplicates for information about this property.
*/
bool QmlSensor::skipDuplicates() const
{
return sensor()->skipDuplicates();
}
void QmlSensor::setSkipDuplicates(bool skipDuplicates)
{
sensor()->setSkipDuplicates(skipDuplicates);
}
/*!
\qmlproperty list<Range> Sensor::availableDataRates
This property holds the data rates that the sensor supports.
Please see QSensor::availableDataRates for information about this property.
*/
QQmlListProperty<QmlSensorRange> QmlSensor::availableDataRates() const
{
Q_D(const QmlSensor);
return readonlyListProperty<QmlSensorRange>(this, &d->availableRanges);
}
/*!
\qmlproperty int Sensor::dataRate
This property holds the data rate that the sensor should be run at.
Please see QSensor::dataRate for information about this property.
*/
int QmlSensor::dataRate() const
{
return sensor()->dataRate();
}
void QmlSensor::setDataRate(int rate)
{
if (rate != dataRate()) {
sensor()->setDataRate(rate);
Q_EMIT dataRateChanged();
}
}
/*!
\qmlproperty list<OutputRange> Sensor::outputRanges
This property holds a list of output ranges the sensor supports.
Please see QSensor::outputRanges for information about this property.
*/
QQmlListProperty<QmlSensorOutputRange> QmlSensor::outputRanges() const
{
Q_D(const QmlSensor);
return readonlyListProperty<QmlSensorOutputRange>(this, &d->outputRanges);
}
/*!
\qmlproperty int Sensor::outputRange
This property holds the output range in use by the sensor.
Please see QSensor::outputRange for information about this property.
*/
int QmlSensor::outputRange() const
{
return sensor()->outputRange();
}
void QmlSensor::setOutputRange(int index)
{
int oldRange = outputRange();
if (oldRange == index) return;
sensor()->setOutputRange(index);
if (sensor()->outputRange() == index)
Q_EMIT outputRangeChanged();
}
/*!
\qmlproperty string Sensor::description
This property holds a descriptive string for the sensor.
*/
QString QmlSensor::description() const
{
return sensor()->description();
}
/*!
\qmlproperty int Sensor::error
This property holds the last error code set on the sensor.
*/
int QmlSensor::error() const
{
return sensor()->error();
}
/*!
\qmlproperty SensorReading Sensor::reading
This property holds the reading class.
Please see QSensor::reading for information about this property.
\sa {QML Reading types}
*/
QmlSensorReading *QmlSensor::reading() const
{
return m_reading;
}
QBindable<QmlSensorReading*> QmlSensor::bindableReading() const
{
return &m_reading;
}
/*!
\qmlmethod bool Sensor::isFeatureSupported(feature)
\since QtSensors 6.7
Checks if a specific feature is supported by the backend.
Returns \c true if the \a feature is supported, and \c false otherwise.
For feature descriptions see \l {QSensor::Feature}.
Please see QSensor::isFeatureSupported for information.
*/
bool QmlSensor::isFeatureSupported(Feature feature) const
{
return sensor()->isFeatureSupported(static_cast<QSensor::Feature>(feature));
}
/*!
\qmlproperty Sensor::AxesOrientationMode Sensor::axesOrientationMode
\since QtSensors 5.1
This property holds the mode that affects how the screen orientation changes reading values.
Please see QSensor::axesOrientationMode for information about this property.
*/
QmlSensor::AxesOrientationMode QmlSensor::axesOrientationMode() const
{
return static_cast<QmlSensor::AxesOrientationMode>(sensor()->axesOrientationMode());
}
void QmlSensor::setAxesOrientationMode(QmlSensor::AxesOrientationMode axesOrientationMode)
{
sensor()->setAxesOrientationMode(static_cast<QSensor::AxesOrientationMode>(axesOrientationMode));
}
/*!
\qmlproperty int Sensor::currentOrientation
\since QtSensors 5.1
This property holds the current orientation that is used for rotating the reading values.
Please see QSensor::currentOrientation for information about this property.
*/
int QmlSensor::currentOrientation() const
{
return sensor()->currentOrientation();
}
/*!
\qmlproperty int Sensor::userOrientation
\since QtSensors 5.1
This property holds the angle used for rotating the reading values in the UserOrientation mode.
Please see QSensor::userOrientation for information about this property.
*/
int QmlSensor::userOrientation() const
{
return sensor()->userOrientation();
}
void QmlSensor::setUserOrientation(int userOrientation)
{
sensor()->setUserOrientation(userOrientation);
}
/*!
\qmlproperty int Sensor::maxBufferSize
\since QtSensors 5.1
This property holds the maximum buffer size.
Please see QSensor::maxBufferSize for information about this property.
*/
int QmlSensor::maxBufferSize() const
{
return sensor()->maxBufferSize();
}
/*!
\qmlproperty int Sensor::efficientBufferSize
\since QtSensors 5.1
The property holds the most efficient buffer size.
Please see QSensor::efficientBufferSize for information about this property.
*/
int QmlSensor::efficientBufferSize() const
{
return sensor()->efficientBufferSize();
}
/*!
\qmlproperty int Sensor::bufferSize
\since QtSensors 5.1
This property holds the size of the buffer.
Please see QSensor::bufferSize for information about this property.
*/
int QmlSensor::bufferSize() const
{
return sensor()->bufferSize();
}
void QmlSensor::setBufferSize(int bufferSize)
{
sensor()->setBufferSize(bufferSize);
}
/*!
\qmlmethod bool Sensor::start()
Start retrieving values from the sensor. Returns true if the sensor
was started, false otherwise.
Please see QSensor::start() for information.
*/
bool QmlSensor::start()
{
return sensor()->start();
}
/*!
\qmlmethod bool Sensor::stop()
Stop retrieving values from the sensor.
Returns true if the sensor was stopped, false otherwise.
Please see QSensor::stop() for information.
*/
void QmlSensor::stop()
{
setActive(false);
}
void QmlSensor::classBegin()
{
}
void QmlSensor::componentComplete()
{
m_componentComplete = true;
connect(sensor(), SIGNAL(sensorError(int)), this, SIGNAL(errorChanged()));
connect(sensor(), SIGNAL(activeChanged()), this, SIGNAL(activeChanged()));
connect(sensor(), SIGNAL(alwaysOnChanged()), this, SIGNAL(alwaysOnChanged()));
connect(sensor(), SIGNAL(skipDuplicatesChanged(bool)), this, SIGNAL(skipDuplicatesChanged(bool)));
connect(sensor(), SIGNAL(axesOrientationModeChanged(AxesOrientationMode)),
this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode)));
connect(sensor(), SIGNAL(userOrientationChanged(int)), this, SIGNAL(userOrientationChanged(int)));
connect(sensor(), SIGNAL(currentOrientationChanged(int)), this, SIGNAL(currentOrientationChanged(int)));
connect(sensor(), SIGNAL(bufferSizeChanged(int)), this, SIGNAL(bufferSizeChanged(int)));
connect(sensor(), SIGNAL(maxBufferSizeChanged(int)), this, SIGNAL(maxBufferSizeChanged(int)));
connect(sensor(), SIGNAL(efficientBufferSizeChanged(int)), this, SIGNAL(efficientBufferSizeChanged(int)));
connect(sensor(), &QSensor::busyChanged, this, &QmlSensor::busyChanged);
connect(sensor(), &QSensor::identifierChanged, this, &QmlSensor::identifierChanged);
// These can change!
int oldDataRate = dataRate();
int oldOutputRange = outputRange();
if (sensor()->connectToBackend())
Q_EMIT connectedToBackendChanged();
m_reading.setValueBypassingBindings(createReading());
m_reading->setParent(this);
if (oldDataRate != dataRate())
Q_EMIT dataRateChanged();
if (oldOutputRange != outputRange())
Q_EMIT outputRangeChanged();
Q_D(QmlSensor);
const auto available = sensor()->availableDataRates();
d->availableRanges.reserve(available.size());
for (const qrange &r : available) {
auto *range = new QmlSensorRange(this);
range->setMinumum(r.first);
range->setMaximum(r.second);
d->availableRanges.append(range);
}
const auto output = sensor()->outputRanges();
d->outputRanges.reserve(output.size());
for (const qoutputrange &r : output) {
auto *range = new QmlSensorOutputRange(this);
range->setMinimum(r.minimum);
range->setMaximum(r.maximum);
range->setAccuracy(r.accuracy);
d->outputRanges.append(range);
}
// meta-data should become non-empty
if (!description().isEmpty())
Q_EMIT descriptionChanged();
if (available.size())
Q_EMIT availableDataRatesChanged();
if (output.size())
Q_EMIT outputRangesChanged();
connect(sensor(), SIGNAL(readingChanged()), this, SLOT(updateReading()));
if (m_activateOnComplete)
start();
}
void QmlSensor::updateReading()
{
if (m_reading) {
m_reading->update();
m_reading.notify();
Q_EMIT readingChanged();
}
}
/*!
\qmltype SensorReading
\nativetype QmlSensorReading
\inqmlmodule QtSensors
\since QtSensors 5.0
\brief The SensorReading element serves as a base type for sensor readings.
The SensorReading element serves as a base type for sensor readings.
This element wraps the QSensorReading class. Please see the documentation for
QSensorReading for details.
This element cannot be directly created.
*/
/*!
\qmlproperty quint64 SensorReading::timestamp
A timestamp for the reading.
Please see QSensorReading::timestamp for information about this property.
*/
quint64 QmlSensorReading::timestamp() const
{
return m_timestamp;
}
QBindable<quint64> QmlSensorReading::bindableTimestamp() const
{
return &m_timestamp;
}
void QmlSensorReading::update()
{
m_timestamp = reading()->timestamp();
readingUpdate();
}
QT_END_NAMESPACE