diff --git a/patch/qtsensor.patch b/patch/qtsensor.patch new file mode 100644 index 0000000000000000000000000000000000000000..27f14995436d7083af25f7b78cdb0e4ad4152788 --- /dev/null +++ b/patch/qtsensor.patch @@ -0,0 +1,1339 @@ +diff --git a/src/openharmony/native/QtSensors.ts b/src/openharmony/native/QtSensors.ts +new file mode 100644 +index 00000000..8c7ad9a0 +--- /dev/null ++++ b/src/openharmony/native/QtSensors.ts +@@ -0,0 +1,132 @@ ++import sensor from '@ohos.sensor'; ++import qtsensorsplugin from 'libplugins_sensors_qtsensors_openharmony.so'; ++ ++export class QtSensors { ++ private pointerId = 0; ++ ++ public constructor(id) { ++ this.pointerId = id; ++ } ++ ++ /* Hz转ns,周期为1 */ ++ private hertz2ns(rate: Number) { ++ /* f=1/T (其中f是指赫兹,T是指以秒为单位的时间)*/ ++ let ns = (1 / Number(rate)) * 1000000000; ++ return ns; ++ } ++ ++ /* ns转Hz,周期为1 */ ++ private ns2hertz(ns: Number) { ++ /* f=1/T (其中f是指赫兹,T是指以秒为单位的时间)*/ ++ let hz = 1 / (Number(ns) / 1000000000); ++ return hz; ++ } ++ ++ createSensor(name, p) { ++ let server = new QtSensors(p); ++ Reflect.defineProperty(globalThis, name, { value: server }); ++ return true; ++ } ++ ++ destroySensor(name: string) { ++ Reflect.deleteProperty(globalThis, name); ++ this.pointerId = 0; ++ return true; ++ } ++ ++ /* 获取所有传感器类型Id */ ++ async sensorIds() { ++ let s: Array = new Array(); ++ try { ++ let sr = await sensor.getSensorList(); ++ for (let data of sr) { ++ s.push(String(data.sensorId)); ++ } ++ } catch (e) { ++ console.error(`Failed to get sensorList. Code: ${e.code}, message: ${e.message}`); ++ } ++ return s; ++ } ++ ++ stop(type: sensor.SensorId) { ++ try { ++ sensor.off(Number(type)); ++ } catch (error) { ++ console.error(`Failed to invoke off. Code: ${error.code}, message: ${error.message}`); ++ } ++ } ++ ++ /* 开始订阅传感器数据 */ ++ async start(type: sensor.SensorId, rate: Number) { ++ try { ++ this.stop(type); ++ let ns = this.hertz2ns(rate); ++ let max = await this.maxSamplePeriod(type); ++ let min = await this.minSamplePeriod(type); ++ let iv = Math.max(Math.min(max, ns), min); ++ ++ sensor.on(Number(type), (data) => { ++ qtsensorsplugin.DataAcception(this.pointerId, JSON.stringify(data)); ++ }, { interval: iv }); ++ } catch (error) { ++ console.error(`Failed to invoke on. Code: ${error.code}, message: ${error.message}`); ++ } ++ } ++ ++ /* 获取指定传感器信息 */ ++ async description(type: sensor.SensorId) { ++ try { ++ let info = await sensor.getSingleSensor(type); ++ let des = JSON.stringify(info); ++ console.info('Succeeded in getting sensor: ' + des); ++ return des; ++ } catch (e) { ++ console.error(`Failed to get singleSensor . Code: ${e.code}, message: ${e.message}`); ++ } ++ } ++ ++ async sensorName(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return s.sensorName; ++ } ++ ++ async vendorName(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return s.vendorName; ++ } ++ ++ async firmwareVersion(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return s.firmwareVersion; ++ } ++ ++ async hardwareVersion(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return s.hardwareVersion; ++ } ++ ++ async maxRange(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return s.maxRange; ++ } ++ ++ async minSamplePeriod(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return this.ns2hertz(s.minSamplePeriod); ++ } ++ ++ async maxSamplePeriod(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return this.ns2hertz(s.minSamplePeriod); ++ } ++ ++ async precision(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return s.precision; ++ } ++ ++ async power(type: sensor.SensorId) { ++ let s = await sensor.getSingleSensor(type); ++ return s.minSamplePeriod; ++ } ++} +\ No newline at end of file +diff --git a/src/openharmony/openharmony.pro b/src/openharmony/openharmony.pro +new file mode 100644 +index 00000000..6f56bfea +--- /dev/null ++++ b/src/openharmony/openharmony.pro +@@ -0,0 +1,11 @@ ++TEMPLATE = aux ++ ++CONFIG -= qt ++ ++templates.files += $$files($$PWD/native/*.ts, true) ++templates.path = $$[QT_INSTALL_PREFIX]/openharmony/qtsensors ++templates.base = $$PWD ++ ++INSTALLS += templates ++ ++OTHER_FILES += $$templates.files +diff --git a/src/plugins/sensors/openharmony/main.cpp b/src/plugins/sensors/openharmony/main.cpp +new file mode 100644 +index 00000000..c14f6520 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/main.cpp +@@ -0,0 +1,222 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sensormanager.h" ++#include "sensorbackend.h" ++#include ++#include "openharmonylight.h" ++#include "openharmonyrotation.h" ++#include "openharmonyhumidity.h" ++#include "openharmonypressure.h" ++#include "openharmonyproximity.h" ++#include "openharmonygyroscope.h" ++#include "openharmonytemperature.h" ++#include "openharmonymagnetometer.h" ++#include "openharmonyaccelerometer.h" ++#include "QtCore/qopenharmonydefines.h" ++#include "QtCore/qopenharmonyjsenvironment.h" ++ ++ ++static napi_value DataAcception(napi_env env, napi_callback_info info) ++{ ++ size_t argc = 2; ++ napi_value args[2] = { Q_NULLPTR }; ++ napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); ++ ++ if (argc != 2) { ++ napi_throw_type_error(env, NULL, "Wrong number of arguments in DataAcception"); ++ return nullptr; ++ } ++ int64_t value0 = qJs::getInt64(args[0]); ++ SensorBackendBase *backend = reinterpret_cast(value0); ++ if (backend == nullptr) ++ return Q_NULLPTR; ++ ++ ++ SensorBackendBase *sensor = reinterpret_cast(value0); ++ if (Q_NULLPTR == sensor) ++ return Q_NULLPTR; ++ ++ QByteArray data = qJs::getString(args[1]).toLocal8Bit(); ++ if (data.isEmpty()) ++ return Q_NULLPTR; ++ ++ QJsonParseError err; ++ const QJsonDocument &doc = QJsonDocument::fromJson(data, &err); ++ if (QJsonParseError::NoError != err.error) ++ return Q_NULLPTR; ++ ++ ++ //sensor->dataReceived(doc.object()); ++ QMetaObject::invokeMethod(sensor, "dataReceived", ++ Qt::QueuedConnection, ++ Q_ARG(QJsonObject, doc.object())); ++ return Q_NULLPTR; ++} ++ ++namespace { ++const char OPenHarmonyCompassId[] = "openharmony.synthetic.compass"; ++} ++ ++class OPenHarmonySensorPlugin : public QObject, public QSensorPluginInterface, ++ public QSensorBackendFactory ++{ ++ Q_OBJECT ++ Q_PLUGIN_METADATA(IID "com.qt-project.Qt.QSensorPluginInterface/1.0" FILE "plugin.json") ++ Q_INTERFACES(QSensorPluginInterface) ++ ++public: ++ void registerSensors() override ++ { ++ bool accelerometer = false; ++ bool magnetometer = false; ++ const QList &ids = SensorManager::instance()->sensorIds(); ++ for (int sensor : qAsConst(ids)) { ++ switch (sensor) { ++ case E_BAROMETER: ++ QSensorManager::registerBackend(QPressureSensor::type, QByteArray::number(sensor), this); ++ break; ++ case E_ACCELEROMETER: ++ m_accelerationModes |= OPenHarmonyAccelerometer::Accelerometer; ++ QSensorManager::registerBackend(QAccelerometer::type, QByteArray::number(sensor), this); ++ accelerometer = true; ++ break; ++ case E_LINEAR_ACCELEROMETER: ++ m_accelerationModes |= OPenHarmonyAccelerometer::LinearAcceleration; ++ //QSensorManager::registerBackend(QAccelerometer::type, QByteArray::number(sensor), this); ++ break; ++ case E_GRAVITY: ++ m_accelerationModes |= OPenHarmonyAccelerometer::Gravity; ++ //QSensorManager::registerBackend(QAccelerometer::type, QByteArray::number(sensor), this); ++ break; ++ case E_HUMIDITY: ++ QSensorManager::registerBackend(QHumiditySensor::type, QByteArray::number(sensor), this); ++ break; ++ case E_PROXIMITY: ++ QSensorManager::registerBackend(QProximitySensor::type, QByteArray::number(sensor), this); ++ break; ++ case E_GYROSCOPE: ++ QSensorManager::registerBackend(QGyroscope::type, QByteArray::number(sensor), this); ++ break; ++ case E_ORIENTATION: ++ /*FIXME 通过加速度传感器实现? */ ++ //QSensorManager::registerBackend(QOrientationSensor::type, QByteArray::number(sensor), this); ++ break; ++ case E_ROTATION_VECTOR: ++ QSensorManager::registerBackend(QRotationSensor::type, QByteArray::number(sensor), this); ++ break; ++ case E_AMBIENT_LIGHT: ++ QSensorManager::registerBackend(QAmbientLightSensor::type, QByteArray::number(sensor), this); ++ break; ++ case E_MAGNETIC_FIELD: ++ QSensorManager::registerBackend(QMagnetometer::type, QByteArray::number(sensor), this); ++ magnetometer = true; ++ break; ++ case E_AMBIENT_TEMPERATURE: ++ QSensorManager::registerBackend(QAmbientTemperatureSensor::type, QByteArray::number(sensor), this); ++ break; ++ default: ++ break; ++ } ++ } ++#if 0 ++ /* NOTE 现在的js回调机制不支持 ++ * 罗盘通过加速度和磁场传感器组合实现 ++ */ ++ if (accelerometer && magnetometer) ++ QSensorManager::registerBackend(QCompass::type, OPenHarmonyCompassId, this); ++#endif ++ } ++ ++ QSensorBackend *createBackend(QSensor *sensor) override ++ { ++ /* TODO QCompass */ ++ int id = sensor->identifier().toInt(); ++ switch (id) { ++ case E_BAROMETER: ++ return new OPenHarmonyPressure(id, sensor); ++ case E_ACCELEROMETER: ++ return new OPenHarmonyAccelerometer(m_accelerationModes, sensor); ++ case E_GYROSCOPE: ++ return new OPenHarmonyGyroscope(id, sensor); ++ case E_PROXIMITY: ++ return new OPenHarmonyProximity(id, sensor); ++ case E_AMBIENT_LIGHT: ++ return new OPenHarmonyLight(id, sensor); ++ case E_MAGNETIC_FIELD: ++ return new OPenHarmonyMagnetometer(id, sensor); ++ case E_HUMIDITY: ++ return new OPenHarmonyHumidity(id, sensor); ++ case E_ROTATION_VECTOR: ++ return new OPenHarmonyRotation(id, sensor); ++ case E_AMBIENT_TEMPERATURE: ++ return new OPenHarmonyTemperature(id, sensor); ++ default: ++ break; ++ } ++ return Q_NULLPTR; ++ } ++ ++private: ++ int m_accelerationModes = 0; ++}; ++ ++/* ++ * function for module exports ++ */ ++EXTERN_C_START ++static napi_value Init(napi_env env, napi_value exports) ++{ ++ static bool inited = false; ++ if (!inited) { ++ ++ LOGI("init sensors module"); ++ napi_property_descriptor desc[] ={ ++ DECLARE_NAPI_FUNCTION("DataAcception", DataAcception), ++ }; ++ NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); ++ inited = true; ++ } ++ return exports; ++} ++EXTERN_C_END ++ ++/* ++ * Napi Module define ++ */ ++static napi_module openharmonyQtSensorsModule = { ++ .nm_version = 1, ++ .nm_flags = 0, ++ .nm_filename = nullptr, ++ .nm_register_func = Init, ++ .nm_modname = "openharmony_qt_sensors", ++ .nm_priv = ((void*)0), ++ .reserved = { 0 }, ++}; ++/* ++ * Module register function ++ */ ++extern "C" __attribute__((constructor)) void RegisterModule(void) ++{ ++ napi_module_register(&openharmonyQtSensorsModule); ++} ++ ++#include "main.moc" +diff --git a/src/plugins/sensors/openharmony/openharmony.pro b/src/plugins/sensors/openharmony/openharmony.pro +new file mode 100644 +index 00000000..390e904c +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmony.pro +@@ -0,0 +1,36 @@ ++TARGET = qtsensors_openharmony ++QT = core sensors ++ ++OTHER_FILES = plugin.json ++ ++SOURCES += \ ++ main.cpp \ ++ openharmonyaccelerometer.cpp \ ++ openharmonygyroscope.cpp \ ++ openharmonyhumidity.cpp \ ++ openharmonylight.cpp \ ++ openharmonymagnetometer.cpp \ ++ openharmonypressure.cpp \ ++ openharmonyproximity.cpp \ ++ openharmonyrotation.cpp \ ++ openharmonytemperature.cpp \ ++ sensormanager.cpp ++ ++ ++PLUGIN_TYPE = sensors ++PLUGIN_CLASS_NAME = OPenHarmonySensorPlugin ++load(qt_plugin) ++ ++HEADERS += \ ++ openharmonyaccelerometer.h \ ++ openharmonygyroscope.h \ ++ openharmonyhumidity.h \ ++ openharmonylight.h \ ++ openharmonymagnetometer.h \ ++ openharmonypressure.h \ ++ openharmonyproximity.h \ ++ openharmonyrotation.h \ ++ openharmonytemperature.h \ ++ sensorbackend.h \ ++ sensormanager.h ++ +diff --git a/src/plugins/sensors/openharmony/openharmonyaccelerometer.cpp b/src/plugins/sensors/openharmony/openharmonyaccelerometer.cpp +new file mode 100644 +index 00000000..84ad1e53 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyaccelerometer.cpp +@@ -0,0 +1,71 @@ ++#include ++#include ++#include ++ ++#include "openharmonyaccelerometer.h" ++ ++OPenHarmonyAccelerometer::OPenHarmonyAccelerometer(int accelerationModes, QSensor *sensor, QObject *parent) ++ : SensorBackend(E_ACCELEROMETER, sensor, parent) ++ , m_accelerationModes(accelerationModes) ++{ ++ auto accelerometer = qobject_cast(sensor); ++ if (accelerometer) { ++ connect(accelerometer, &QAccelerometer::accelerationModeChanged, ++ this, &OPenHarmonyAccelerometer::applyAccelerationMode); ++ applyAccelerationMode(accelerometer->accelerationMode()); ++ } ++} ++ ++bool OPenHarmonyAccelerometer::isFeatureSupported(QSensor::Feature feature) const ++{ ++ return (feature == QSensor::AccelerationMode) ? m_accelerationModes == AllModes : SensorBackend::isFeatureSupported(feature); ++} ++ ++void OPenHarmonyAccelerometer::dataReceived(const QJsonObject &json) ++{ ++ double x = json.value("x").toDouble(); ++ double y = json.value("y").toDouble(); ++ double z = json.value("z").toDouble(); ++ ++ if (sensor()->skipDuplicates() && qFuzzyCompare(m_reader.x(), x) && ++ qFuzzyCompare(m_reader.y(), y) && ++ qFuzzyCompare(m_reader.z(), z)) { ++ return; ++ } ++ ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setX(x); ++ m_reader.setY(y); ++ m_reader.setZ(z); ++ ++ newReadingAvailable(); ++} ++ ++void OPenHarmonyAccelerometer::applyAccelerationMode(QAccelerometer::AccelerationMode accelerationMode) ++{ ++ switch (accelerationMode) { ++ case QAccelerometer::Gravity: ++ if (!(m_accelerationModes & Gravity)) { ++ qWarning() << "Gravity sensor missing"; ++ return; ++ } ++ setSensorType(E_GRAVITY); ++ break; ++ case QAccelerometer::User: ++ if (!(m_accelerationModes & LinearAcceleration)) { ++ qWarning() << "Linear acceleration sensor missing"; ++ return; ++ } ++ setSensorType(E_LINEAR_ACCELEROMETER); ++ break; ++ case QAccelerometer::Combined: ++ if (!(m_accelerationModes & Accelerometer)) { ++ qWarning() << "Accelerometer sensor missing"; ++ return; ++ } ++ setSensorType(E_ACCELEROMETER); ++ break; ++ } ++} ++ +diff --git a/src/plugins/sensors/openharmony/openharmonyaccelerometer.h b/src/plugins/sensors/openharmony/openharmonyaccelerometer.h +new file mode 100644 +index 00000000..a610d25b +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyaccelerometer.h +@@ -0,0 +1,32 @@ ++#ifndef OPENHARMONYACCELEROMETER_H ++#define OPENHARMONYACCELEROMETER_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyAccelerometer : public SensorBackend ++{ ++ Q_OBJECT ++ ++public: ++ enum AccelerationModes { ++ Accelerometer = 1, ++ Gravity = 2, ++ LinearAcceleration = 4, ++ AllModes = (Accelerometer | Gravity | LinearAcceleration) ++ }; ++ OPenHarmonyAccelerometer(int accelerationModes, QSensor *sensor, QObject *parent = nullptr); ++ bool isFeatureSupported(QSensor::Feature feature) const override; ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++ ++private: ++ void applyAccelerationMode(QAccelerometer::AccelerationMode accelerationMode); ++ ++private: ++ int m_accelerationModes; ++}; ++ ++#endif // OPENHARMONYACCELEROMETER_H +diff --git a/src/plugins/sensors/openharmony/openharmonygyroscope.cpp b/src/plugins/sensors/openharmony/openharmonygyroscope.cpp +new file mode 100644 +index 00000000..349b7e2f +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonygyroscope.cpp +@@ -0,0 +1,33 @@ ++#include ++#include ++#include ++ ++#include "openharmonygyroscope.h" ++ ++OPenHarmonyGyroscope::OPenHarmonyGyroscope(int type, QSensor *sensor, QObject *parent) ++: SensorBackend(type, sensor, parent) ++{ ++ ++} ++ ++void OPenHarmonyGyroscope::dataReceived(const QJsonObject &json) ++{ ++ double x = qRadiansToDegrees(json.value("x").toDouble()); ++ double y = qRadiansToDegrees(json.value("y").toDouble()); ++ double z = qRadiansToDegrees(json.value("z").toDouble()); ++ double timestamp = json.value("timestamp").toDouble(); ++ ++ if (sensor()->skipDuplicates() && qFuzzyCompare(m_reader.x(), x) && ++ qFuzzyCompare(m_reader.y(), y) && ++ qFuzzyCompare(m_reader.z(), z)) { ++ return; ++ } ++ ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setX(x); ++ m_reader.setY(y); ++ m_reader.setZ(z); ++ ++ newReadingAvailable(); ++} ++ +diff --git a/src/plugins/sensors/openharmony/openharmonygyroscope.h b/src/plugins/sensors/openharmony/openharmonygyroscope.h +new file mode 100644 +index 00000000..ff3e6d2a +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonygyroscope.h +@@ -0,0 +1,18 @@ ++#ifndef OPENHARMONYGYROSCOPE_H ++#define OPENHARMONYGYROSCOPE_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyGyroscope : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyGyroscope(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++}; ++ ++#endif // OPENHARMONYGYROSCOPE_H +diff --git a/src/plugins/sensors/openharmony/openharmonyhumidity.cpp b/src/plugins/sensors/openharmony/openharmonyhumidity.cpp +new file mode 100644 +index 00000000..e17df8cf +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyhumidity.cpp +@@ -0,0 +1,25 @@ ++#include ++#include ++ ++#include "openharmonyhumidity.h" ++ ++OPenHarmonyHumidity::OPenHarmonyHumidity(int type, QSensor *sensor, QObject *parent) ++ : SensorBackend(type, sensor, parent) ++{ ++ ++} ++ ++void OPenHarmonyHumidity::dataReceived(const QJsonObject &json) ++{ ++ qreal humidity = json.value("humidity").toDouble(); ++ ++ if (sensor()->skipDuplicates() && qFuzzyCompare(humidity, m_reader.relativeHumidity())) ++ return; ++ ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setAbsoluteHumidity(0.f); ++ m_reader.setRelativeHumidity(humidity); ++ newReadingAvailable(); ++} ++ +diff --git a/src/plugins/sensors/openharmony/openharmonyhumidity.h b/src/plugins/sensors/openharmony/openharmonyhumidity.h +new file mode 100644 +index 00000000..adbf4c9b +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyhumidity.h +@@ -0,0 +1,18 @@ ++#ifndef OPENHARMONYHUMIDITY_H ++#define OPENHARMONYHUMIDITY_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyHumidity : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyHumidity(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++}; ++ ++#endif // OPENHARMONYHUMIDITY_H +diff --git a/src/plugins/sensors/openharmony/openharmonylight.cpp b/src/plugins/sensors/openharmony/openharmonylight.cpp +new file mode 100644 +index 00000000..7274df7c +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonylight.cpp +@@ -0,0 +1,23 @@ ++#include ++#include ++ ++#include "openharmonylight.h" ++ ++OPenHarmonyLight::OPenHarmonyLight(int type, QSensor *sensor, QObject *parent) ++ : SensorBackend(type, sensor, parent) ++{ ++ ++} ++ ++void OPenHarmonyLight::dataReceived(const QJsonObject &json) ++{ ++ double intensity = json.value("intensity").toDouble(); ++ ++ if (sensor()->skipDuplicates() && qFuzzyCompare(m_reader.lux(), intensity)) ++ return; ++ ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setLux(qreal(intensity)); ++ newReadingAvailable(); ++} +diff --git a/src/plugins/sensors/openharmony/openharmonylight.h b/src/plugins/sensors/openharmony/openharmonylight.h +new file mode 100644 +index 00000000..f8039a92 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonylight.h +@@ -0,0 +1,18 @@ ++#ifndef OPENHARMONYLIGHT_H ++#define OPENHARMONYLIGHT_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyLight : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyLight(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++}; ++ ++#endif // OPENHARMONYLIGHT_H +diff --git a/src/plugins/sensors/openharmony/openharmonymagnetometer.cpp b/src/plugins/sensors/openharmony/openharmonymagnetometer.cpp +new file mode 100644 +index 00000000..34e34b21 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonymagnetometer.cpp +@@ -0,0 +1,32 @@ ++#include ++#include ++#include "openharmonymagnetometer.h" ++ ++OPenHarmonyMagnetometer::OPenHarmonyMagnetometer(int type, QSensor *sensor, QObject *parent) ++ : SensorBackend(type, sensor, parent) ++{ ++ ++} ++ ++void OPenHarmonyMagnetometer::dataReceived(const QJsonObject &json) ++{ ++ double x = json.value("x").toDouble(); ++ double y = json.value("y").toDouble(); ++ double z = json.value("z").toDouble(); ++ ++ if (sensor()->skipDuplicates() && qFuzzyCompare(m_accuracy, m_reader.calibrationLevel()) && ++ qFuzzyCompare(x, m_reader.x()) && ++ qFuzzyCompare(y, m_reader.y()) && ++ qFuzzyCompare(z, m_reader.z())) { ++ return; ++ } ++ ++ m_reader.setCalibrationLevel(m_accuracy); ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setX(x); ++ m_reader.setY(y); ++ m_reader.setZ(z); ++ newReadingAvailable(); ++} ++ +diff --git a/src/plugins/sensors/openharmony/openharmonymagnetometer.h b/src/plugins/sensors/openharmony/openharmonymagnetometer.h +new file mode 100644 +index 00000000..c3662243 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonymagnetometer.h +@@ -0,0 +1,18 @@ ++#ifndef OPENHARMONYMAGNETOMETER_H ++#define OPENHARMONYMAGNETOMETER_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyMagnetometer : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyMagnetometer(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++}; ++ ++#endif // OPENHARMONYMAGNETOMETER_H +diff --git a/src/plugins/sensors/openharmony/openharmonypressure.cpp b/src/plugins/sensors/openharmony/openharmonypressure.cpp +new file mode 100644 +index 00000000..c7d5d3d3 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonypressure.cpp +@@ -0,0 +1,22 @@ ++#include ++#include ++ ++#include "openharmonypressure.h" ++ ++OPenHarmonyPressure::OPenHarmonyPressure(int type, QSensor *sensor, QObject *parent) ++ : SensorBackend(type, sensor, parent) ++{ ++ ++} ++ ++void OPenHarmonyPressure::dataReceived(const QJsonObject &json) ++{ ++ auto pressurePa = json.value("pressure").toDouble(); ++ if (sensor()->skipDuplicates() && qFuzzyCompare(pressurePa, m_reader.pressure())) ++ return; ++ ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setPressure(pressurePa); ++ newReadingAvailable(); ++} +diff --git a/src/plugins/sensors/openharmony/openharmonypressure.h b/src/plugins/sensors/openharmony/openharmonypressure.h +new file mode 100644 +index 00000000..8c2db8aa +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonypressure.h +@@ -0,0 +1,18 @@ ++#ifndef OPENHARMONYPRESSURE_H ++#define OPENHARMONYPRESSURE_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyPressure : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyPressure(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++}; ++ ++#endif // OPENHARMONYPRESSURE_H +diff --git a/src/plugins/sensors/openharmony/openharmonyproximity.cpp b/src/plugins/sensors/openharmony/openharmonyproximity.cpp +new file mode 100644 +index 00000000..e96a0b24 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyproximity.cpp +@@ -0,0 +1,28 @@ ++#include ++#include ++ ++#include "openharmonyproximity.h" ++ ++OPenHarmonyProximity::OPenHarmonyProximity(int type, QSensor *sensor, QObject *parent) ++ : SensorBackend(type, sensor, parent) ++{ ++ m_maximumRange = m_jsSensor->maxRange(m_type); ++ ++ // if we can't get the range, we arbitrarily define anything closer than 10 cm as "close" ++ if (m_maximumRange <= 0) ++ m_maximumRange = 10.0; ++} ++ ++void OPenHarmonyProximity::dataReceived(const QJsonObject &json) ++{ ++ qreal distance = json.value("distance").toDouble(); ++ bool close = distance < m_maximumRange; ++ if (sensor()->skipDuplicates() && close == m_reader.close()) ++ return; ++ ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setClose(close); ++ newReadingAvailable(); ++} ++ +diff --git a/src/plugins/sensors/openharmony/openharmonyproximity.h b/src/plugins/sensors/openharmony/openharmonyproximity.h +new file mode 100644 +index 00000000..f1ef02f2 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyproximity.h +@@ -0,0 +1,21 @@ ++#ifndef OPENHARMONYPROXIMITY_H ++#define OPENHARMONYPROXIMITY_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyProximity : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyProximity(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++ ++private: ++ qreal m_maximumRange; ++}; ++ ++#endif // OPENHARMONYPROXIMITY_H +diff --git a/src/plugins/sensors/openharmony/openharmonyrotation.cpp b/src/plugins/sensors/openharmony/openharmonyrotation.cpp +new file mode 100644 +index 00000000..a4d70e6f +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyrotation.cpp +@@ -0,0 +1,29 @@ ++#include ++#include ++#include ++ ++#include "openharmonyrotation.h" ++ ++OPenHarmonyRotation::OPenHarmonyRotation(int type, QSensor *sensor, QObject *parent) ++ : SensorBackend(type, sensor, parent) ++{ ++ ++} ++ ++void OPenHarmonyRotation::dataReceived(const QJsonObject &json) ++{ ++ qreal rz = -qRadiansToDegrees(json.value("x").toDouble()); //corresponds to x ++ qreal rx = -qRadiansToDegrees(json.value("y").toDouble()); //corresponds to y ++ qreal ry = qRadiansToDegrees(json.value("z").toDouble()); //corresponds to z ++ if (sensor()->skipDuplicates() && qFuzzyCompare(m_reader.x(), rx) && ++ qFuzzyCompare(m_reader.y(), ry) && ++ qFuzzyCompare(m_reader.z(), rz)) { ++ return; ++ } ++ ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setFromEuler(rx, ry, rz); ++ newReadingAvailable(); ++} ++ +diff --git a/src/plugins/sensors/openharmony/openharmonyrotation.h b/src/plugins/sensors/openharmony/openharmonyrotation.h +new file mode 100644 +index 00000000..03243797 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonyrotation.h +@@ -0,0 +1,18 @@ ++#ifndef OPENHARMONYROTATION_H ++#define OPENHARMONYROTATION_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyRotation : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyRotation(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++}; ++ ++#endif // OPENHARMONYROTATION_H +diff --git a/src/plugins/sensors/openharmony/openharmonytemperature.cpp b/src/plugins/sensors/openharmony/openharmonytemperature.cpp +new file mode 100644 +index 00000000..a3865b03 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonytemperature.cpp +@@ -0,0 +1,23 @@ ++#include ++#include ++ ++#include "openharmonytemperature.h" ++ ++OPenHarmonyTemperature::OPenHarmonyTemperature(int type, QSensor *sensor, QObject *parent) ++ : SensorBackend(type, sensor, parent) ++{ ++ ++} ++ ++void OPenHarmonyTemperature::dataReceived(const QJsonObject &json) ++{ ++ qreal temperature = json.value("temperature").toDouble(); ++ if (sensor()->skipDuplicates() && qFuzzyCompare(m_reader.temperature(), temperature)) ++ return; ++ ++ double timestamp = json.value("timestamp").toDouble(); ++ m_reader.setTimestamp(quint64(timestamp)); ++ m_reader.setTemperature(temperature); // in degree Celsius ++ newReadingAvailable(); ++} ++ +diff --git a/src/plugins/sensors/openharmony/openharmonytemperature.h b/src/plugins/sensors/openharmony/openharmonytemperature.h +new file mode 100644 +index 00000000..cc881f20 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/openharmonytemperature.h +@@ -0,0 +1,18 @@ ++#ifndef OPENHARMONYTEMPERATURE_H ++#define OPENHARMONYTEMPERATURE_H ++ ++#include ++ ++#include "sensorbackend.h" ++ ++class OPenHarmonyTemperature : public SensorBackend ++{ ++ Q_OBJECT ++public: ++ OPenHarmonyTemperature(int type, QSensor *sensor, QObject *parent = nullptr); ++ ++protected Q_SLOTS: ++ void dataReceived(const QJsonObject &json) override; ++}; ++ ++#endif // OPENHARMONYTEMPERATURE_H +diff --git a/src/plugins/sensors/openharmony/plugin.json b/src/plugins/sensors/openharmony/plugin.json +new file mode 100644 +index 00000000..ff40b670 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/plugin.json +@@ -0,0 +1 @@ ++{ "Keys": [ "openharmony" ] } +diff --git a/src/plugins/sensors/openharmony/sensorbackend.h b/src/plugins/sensors/openharmony/sensorbackend.h +new file mode 100644 +index 00000000..aa0907df +--- /dev/null ++++ b/src/plugins/sensors/openharmony/sensorbackend.h +@@ -0,0 +1,91 @@ ++#ifndef SENSORBACKEND_H ++#define SENSORBACKEND_H ++ ++#include ++#include ++ ++#include "sensormanager.h" ++ ++class SensorBackendBase : public QSensorBackend ++{ ++public: ++ SensorBackendBase(QSensor *sensor, QObject *parent = nullptr) ++ : QSensorBackend(sensor, parent) ++ , m_jsSensor(Q_NULLPTR) ++ { ++ QString tempUuid = QUuid::createUuid().toString(); ++ tempUuid.chop(1); //remove trailing '}' ++ tempUuid.remove(0,1); //remove first '{' ++ ++ m_jsSensor = SensorManager::instance()->createJsSensor(tempUuid, this); ++ } ++ ++public Q_SLOTS: ++ virtual void dataReceived(const QJsonObject &json) = 0; ++ ++protected: ++ QSharedPointer m_jsSensor; ++}; ++ ++template ++class SensorBackend : public SensorBackendBase ++{ ++public: ++ explicit SensorBackend(int type, QSensor *sensor, QObject *parent = nullptr) : m_type(0) ++ , SensorBackendBase{ sensor, parent } ++ { ++ setReading(&m_reader); ++ setSensorType(type); ++ m_accuracy = m_jsSensor->precision(type); ++ addDataRate(m_jsSensor->minSamplePeriod(type), ++ m_jsSensor->maxSamplePeriod(type)); ++ addOutputRange(0, m_jsSensor->maxRange(type), m_accuracy); ++ } ++ ++ ~SensorBackend() override ++ { ++ stop(); ++ } ++ ++ void setSensorType(int type) ++ { ++ m_type = type; ++ bool started = m_started; ++ if (started) ++ stop(); ++ ++ setDescription(m_jsSensor->description(type)); ++ if (started) ++ start(); ++ } ++ ++ virtual void start() override ++ { ++ m_jsSensor->start(m_type, sensor()->dataRate()); ++ m_started = true; ++ } ++ ++ virtual void stop() override ++ { ++ m_jsSensor->stop(m_type); ++ m_started = false; ++ } ++ ++ bool isFeatureSupported(QSensor::Feature feature) const override ++ { ++ switch (feature) { ++ case QSensor::SkipDuplicates: ++ return true; ++ default: ++ return false; ++ } ++ } ++ ++protected: ++ T m_reader; ++ int m_type; ++ qreal m_accuracy = 0.0f; ++ bool m_started = false; ++}; ++ ++#endif // SENSORBACKEND_H +diff --git a/src/plugins/sensors/openharmony/sensormanager.cpp b/src/plugins/sensors/openharmony/sensormanager.cpp +new file mode 100644 +index 00000000..d34294f4 +--- /dev/null ++++ b/src/plugins/sensors/openharmony/sensormanager.cpp +@@ -0,0 +1,121 @@ ++#include "sensormanager.h" ++#include "QtCore/qopenharmonyjsobject.h" ++#include "QtCore/qopenharmonyjsenvironment.h" ++#include "QtCore/qopenharmonyjsobjectloader.h" ++ ++JsSensor::JsSensor(const QString &uuid) : m_uuid(uuid) ++ , m_jsSensor(Q_NULLPTR) ++{ ++ ++} ++ ++JsSensor::~JsSensor() ++{ ++ if (m_jsSensor) ++ m_jsSensor->call("destroySensor", m_uuid); ++} ++ ++qreal JsSensor::power(int id) const ++{ ++ qreal p = m_jsSensor->call("power", id); ++ return p; ++} ++ ++QString JsSensor::name(int id) const ++{ ++ QString n = m_jsSensor->call("sensorName", id); ++ return n; ++} ++ ++qreal JsSensor::maxRange(int id) const ++{ ++ qreal r = m_jsSensor->call("maxRange", id); ++ return r; ++} ++ ++qreal JsSensor::precision(int id) const ++{ ++ qreal accuracy = m_jsSensor->call("precision", id); ++ return accuracy; ++} ++ ++QString JsSensor::vendorName(int id) const ++{ ++ QString n = m_jsSensor->call("vendorName", id); ++ return n; ++} ++ ++QString JsSensor::description(int id) const ++{ ++ QString des = m_jsSensor->call("description", id); ++ return des; ++} ++ ++qreal JsSensor::minSamplePeriod(int id) const ++{ ++ qreal p = m_jsSensor->call("minSamplePeriod", id); ++ return p; ++} ++ ++qreal JsSensor::maxSamplePeriod(int id) const ++{ ++ qreal p = m_jsSensor->call("maxSamplePeriod", id); ++ return p; ++} ++ ++QString JsSensor::firmwareVersion(int id) const ++{ ++ QString v = m_jsSensor->call("firmwareVersion", id); ++ return v; ++} ++ ++void JsSensor::stop(int id) ++{ ++ m_jsSensor->call("stop", id); ++} ++ ++void JsSensor::start(int id, int rate) ++{ ++ m_jsSensor->call("start", id, rate); ++} ++ ++QString JsSensor::hardwareVersion(int id) const ++{ ++ QString hv = m_jsSensor->call("hardwareVersion", id); ++ return hv; ++} ++ ++SensorManager::SensorManager() { ++ m_sensors = qJsObjectLoader->create("qtsensors"); ++} ++ ++QList SensorManager::sensorIds() const ++{ ++ QStringList ids = m_sensors->call("sensorIds"); ++ QList ns; ++ ns.reserve(ids.size()); ++ for (const auto &id : qAsConst(ids)) { ++ ns.append(id.toInt()); ++ } ++ return ns; ++} ++ ++QSharedPointer &SensorManager::instance() ++{ ++ static QSharedPointer s{ new SensorManager() }; ++ return s; ++} ++ ++QSharedPointer SensorManager::createJsSensor(const QString &uuid, SensorBackendBase *backend) ++{ ++ JsSensor *s = new JsSensor(uuid); ++ m_sensors->call("createSensor", uuid, QVariant(qlonglong(backend))); ++ s->m_jsSensor.reset(new QOpenHarmonyJsObject(uuid)); ++ return QSharedPointer(s); ++} ++ ++void SensorManager::defineProperties(size_t property_count, const napi_property_descriptor *properties) ++{ ++ m_sensors->defineProperties(property_count, properties); ++} ++ +diff --git a/src/plugins/sensors/openharmony/sensormanager.h b/src/plugins/sensors/openharmony/sensormanager.h +new file mode 100644 +index 00000000..157baa3c +--- /dev/null ++++ b/src/plugins/sensors/openharmony/sensormanager.h +@@ -0,0 +1,69 @@ ++#ifndef SENSORMANAGER_H ++#define SENSORMANAGER_H ++ ++#include ++#include ++ ++/* NOTE 鸿蒙和Qt传感器匹配的项 ++ * Qt对前端传感器模块进行了封装 ++ * 鸿蒙提供的传感器模块接口不是 ++ * 完全匹配,需要转换 ++ */ ++enum { ++ E_GRAVITY = 257, /* 重力传感器<--->QAccelerometer */ ++ E_HUMIDITY = 13, /* 湿度传感器<--->QHumiditySensor */ ++ E_BAROMETER = 8, /* 气压传感器<--->QPressureSensor */ ++ E_GYROSCOPE = 2, /* 陀螺仪传感器<--->QGyroscope */ ++ E_PROXIMITY = 12, /* 接近光传感器<--->QDistanceSensor */ ++ E_ORIENTATION = 256, /* 方向传感器<--->QOrientationSensor */ ++ E_ACCELEROMETER = 1, /* 加速度传感器<--->QAccelerometer */ ++ E_AMBIENT_LIGHT = 5, /* 环境光传感器<--->QAmbientLightSensor */ ++ E_MAGNETIC_FIELD = 6, /* 磁场传感器<--->QMagnetometer */ ++ E_ROTATION_VECTOR = 259, /* 旋转矢量传感器<--->QRotationSensor */ ++ E_AMBIENT_TEMPERATURE = 260, /* 环境温度传感器<--->QAmbientTemperatureSensor */ ++ E_LINEAR_ACCELEROMETER = 258, /* 线性加速度传感器<--->QAccelerometer */ ++}; ++ ++class SensorBackendBase; ++class QOpenHarmonyJsObject; ++ ++class JsSensor ++{ ++ QString m_uuid; ++ QSharedPointer m_jsSensor; ++ ++ friend class SensorManager; ++public: ++ JsSensor(const QString &uuid); ++ ~JsSensor(); ++ ++ qreal power(int id) const; ++ QString name(int id) const; ++ qreal maxRange(int id) const; ++ qreal precision(int id) const; ++ QString vendorName(int id) const; ++ QString description(int id) const; ++ qreal minSamplePeriod(int id) const; ++ qreal maxSamplePeriod(int id) const; ++ QString firmwareVersion(int id) const; ++ QString hardwareVersion(int id) const; ++ ++ void stop(int id); ++ void start(int id, int rate); ++}; ++ ++class SensorManager ++{ ++ SensorManager(); ++ ++public: ++ QList sensorIds() const; ++ static QSharedPointer &instance(); ++ QSharedPointer createJsSensor(const QString &uuid, SensorBackendBase *backend); ++ void defineProperties(size_t property_count, const napi_property_descriptor* properties); ++ ++private: ++ QSharedPointer m_sensors; ++}; ++ ++#endif // SENSORMANAGER_H +diff --git a/src/plugins/sensors/sensors.pro b/src/plugins/sensors/sensors.pro +index 7fce2071..8037ffc4 100644 +--- a/src/plugins/sensors/sensors.pro ++++ b/src/plugins/sensors/sensors.pro +@@ -5,6 +5,10 @@ android { + isEmpty(SENSORS_PLUGINS): SENSORS_PLUGINS = android generic + } + ++openharmony { ++ isEmpty(SENSORS_PLUGINS): SENSORS_PLUGINS = openharmony generic ++} ++ + qtConfig(sensorfw) { + isEmpty(SENSORS_PLUGINS): SENSORS_PLUGINS = sensorfw generic + } +@@ -39,6 +43,7 @@ isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, simulator):qtHaveModule(simul + isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, linux):linux:SUBDIRS += linux + isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, iio-sensor-proxy):linux:qtHaveModule(dbus):SUBDIRS += iio-sensor-proxy + isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, android):android:SUBDIRS += android ++isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, openharmony):openharmony:SUBDIRS += openharmony + isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, sensorfw):sensorfw:SUBDIRS += sensorfw + isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, sensortag):linux:SUBDIRS += sensortag + isEmpty(SENSORS_PLUGINS)|contains(SENSORS_PLUGINS, ios):darwin:SUBDIRS += ios +diff --git a/src/src.pro b/src/src.pro +index b3aa7ba0..df12cad0 100644 +--- a/src/src.pro ++++ b/src/src.pro +@@ -16,3 +16,6 @@ plugins.subdir = plugins + plugins.target = sub-plugins + plugins.depends = sensors + ++SUBDIRS += openharmony ++openharmony.subdir = openharmony ++openharmony.target = sub-openharmony