/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "sensor_js.h" #include <cinttypes> #include <cstdlib> #include <map> #include <cmath> #include <string> #include <unistd.h> #include "refbase.h" #include "securec.h" #include "geomagnetic_field.h" #include "sensor_algorithm.h" #include "sensor_napi_error.h" #include "sensor_napi_utils.h" #include "sensor_system_js.h" namespace OHOS { namespace Sensors { namespace { constexpr int32_t QUATERNION_LENGTH = 4; constexpr int32_t ROTATION_VECTOR_LENGTH = 3; constexpr int32_t REPORTING_INTERVAL = 200000000; constexpr int32_t INVALID_SENSOR_ID = -1; constexpr int32_t SENSOR_SUBSCRIBE_FAILURE = 1001; constexpr int32_t INPUT_ERROR = 202; constexpr float BODY_STATE_EXCEPT = 1.0f; constexpr float THRESHOLD = 0.000001f; } static std::map<std::string, int64_t> g_samplingPeriod = { {"normal", 200000000}, {"ui", 60000000}, {"game", 20000000}, }; static std::mutex mutex_; static std::mutex bodyMutex_; static float g_bodyState = -1.0f; static std::map<int32_t, std::vector<sptr<AsyncCallbackInfo>>> g_subscribeCallbacks; static std::mutex onMutex_; static std::mutex onceMutex_; static std::map<int32_t, std::vector<sptr<AsyncCallbackInfo>>> g_onceCallbackInfos; static std::map<int32_t, std::vector<sptr<AsyncCallbackInfo>>> g_onCallbackInfos; static bool CheckSubscribe(int32_t sensorTypeId) { std::lock_guard<std::mutex> onCallbackLock(onMutex_); auto iter = g_onCallbackInfos.find(sensorTypeId); return iter != g_onCallbackInfos.end(); } static bool copySensorData(sptr<AsyncCallbackInfo> callbackInfo, SensorEvent *event) { CHKPF(callbackInfo); CHKPF(event); int32_t sensorTypeId = event->sensorTypeId; callbackInfo->data.sensorData.sensorTypeId = sensorTypeId; callbackInfo->data.sensorData.dataLength = event->dataLen; callbackInfo->data.sensorData.timestamp = event->timestamp; CHKPF(event->data); auto data = reinterpret_cast<float *>(event->data); if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && callbackInfo->type == SUBSCRIBE_CALLBACK) { std::lock_guard<std::mutex> onBodyLock(bodyMutex_); g_bodyState = *data; callbackInfo->data.sensorData.data[0] = (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false; return true; } if (memcpy_s(callbackInfo->data.sensorData.data, sizeof(callbackInfo->data.sensorData.data), data, event->dataLen) != EOK) { SEN_HILOGE("Copy data failed"); return false; } return true; } static bool CheckSystemSubscribe(int32_t sensorTypeId) { std::lock_guard<std::mutex> subscribeLock(mutex_); auto iter = g_subscribeCallbacks.find(sensorTypeId); if (iter == g_subscribeCallbacks.end()) { return false; } return true; } static void EmitSubscribeCallback(SensorEvent *event) { CHKPV(event); int32_t sensorTypeId = event->sensorTypeId; if (!CheckSystemSubscribe(sensorTypeId)) { return; } std::lock_guard<std::mutex> subscribeLock(mutex_); auto callbacks = g_subscribeCallbacks[sensorTypeId]; for (auto &callback : callbacks) { if (!copySensorData(callback, event)) { SEN_HILOGE("Copy sensor data failed"); continue; } EmitUvEventLoop(callback); } } static void EmitOnCallback(SensorEvent *event) { CHKPV(event); int32_t sensorTypeId = event->sensorTypeId; if (!CheckSubscribe(sensorTypeId)) { return; } std::lock_guard<std::mutex> onCallbackLock(onMutex_); auto onCallbackInfos = g_onCallbackInfos[sensorTypeId]; for (auto &onCallbackInfo : onCallbackInfos) { if (!copySensorData(onCallbackInfo, event)) { SEN_HILOGE("Copy sensor data failed"); continue; } EmitUvEventLoop(onCallbackInfo); } } static void EmitOnceCallback(SensorEvent *event) { CHKPV(event); int32_t sensorTypeId = event->sensorTypeId; std::lock_guard<std::mutex> onceCallbackLock(onceMutex_); auto iter = g_onceCallbackInfos.find(sensorTypeId); if (iter == g_onceCallbackInfos.end()) { return; } auto& onceCallbackInfos = iter->second; while (!onceCallbackInfos.empty()) { auto onceCallbackInfo = onceCallbackInfos.front(); auto beginIter = onceCallbackInfos.begin(); onceCallbackInfos.erase(beginIter); if (!copySensorData(onceCallbackInfo, event)) { SEN_HILOGE("Copy sensor data failed"); continue; } EmitUvEventLoop(std::move(onceCallbackInfo)); } g_onceCallbackInfos.erase(sensorTypeId); CHKCV((!CheckSubscribe(sensorTypeId)), "Has client subscribe, not need cancel subscribe"); CHKCV((!CheckSystemSubscribe(sensorTypeId)), "Has client subscribe system api, not need cancel subscribe"); UnsubscribeSensor(sensorTypeId); } void DataCallbackImpl(SensorEvent *event) { CHKPV(event); EmitOnCallback(event); EmitSubscribeCallback(event); EmitOnceCallback(event); } const SensorUser user = { .callback = DataCallbackImpl }; int32_t UnsubscribeSensor(int32_t sensorTypeId) { CALL_LOG_ENTER; int32_t ret = DeactivateSensor(sensorTypeId, &user); if (ret != ERR_OK) { SEN_HILOGE("DeactivateSensor failed"); return ret; } return UnsubscribeSensor(sensorTypeId, &user); } int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback) { CALL_LOG_ENTER; int32_t ret = SubscribeSensor(sensorTypeId, &user); if (ret != ERR_OK) { SEN_HILOGE("SubscribeSensor failed"); return ret; } ret = SetBatch(sensorTypeId, &user, interval, 0); if (ret != ERR_OK) { SEN_HILOGE("SetBatch failed"); return ret; } return ActivateSensor(sensorTypeId, &user); } static bool IsOnceSubscribed(napi_env env, int32_t sensorTypeId, napi_value callback) { CALL_LOG_ENTER; if (auto iter = g_onceCallbackInfos.find(sensorTypeId); iter == g_onceCallbackInfos.end()) { SEN_HILOGW("Already subscribed, sensorTypeId:%{public}d", sensorTypeId); return false; } std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onceCallbackInfos[sensorTypeId]; for (auto callbackInfo : callbackInfos) { CHKPC(callbackInfo); if (callbackInfo->env != env) { continue; } napi_value sensorCallback = nullptr; CHKNRF(env, napi_get_reference_value(env, callbackInfo->callback[0], &sensorCallback), "napi_get_reference_value"); if (IsSameValue(env, callback, sensorCallback)) { return true; } } return false; } static void UpdateOnceCallback(napi_env env, int32_t sensorTypeId, napi_value callback) { CALL_LOG_ENTER; std::lock_guard<std::mutex> onceCallbackLock(onceMutex_); CHKCV((!IsOnceSubscribed(env, sensorTypeId, callback)), "The callback has been subscribed"); sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ONCE_CALLBACK); CHKPV(asyncCallbackInfo); napi_status status = napi_create_reference(env, callback, 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return; } std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onceCallbackInfos[sensorTypeId]; callbackInfos.push_back(asyncCallbackInfo); g_onceCallbackInfos[sensorTypeId] = callbackInfos; } static napi_value Once(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 2; napi_value args[2] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 2) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if ((!IsMatchType(env, args[0], napi_number)) || (!IsMatchType(env, args[1], napi_function))) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type"); return nullptr; } int32_t sensorTypeId = INVALID_SENSOR_ID; if (!GetNativeInt32(env, args[0], sensorTypeId)) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get number fail"); return nullptr; } if (!CheckSubscribe(sensorTypeId)) { SEN_HILOGD("No subscription to change sensor data, registration is required"); int32_t ret = SubscribeSensor(sensorTypeId, REPORTING_INTERVAL, DataCallbackImpl); if (ret != ERR_OK) { ThrowErr(env, ret, "SubscribeSensor fail"); return nullptr; } } UpdateOnceCallback(env, sensorTypeId, args[1]); return nullptr; } static bool IsSubscribed(napi_env env, int32_t sensorTypeId, napi_value callback) { CALL_LOG_ENTER; if (auto iter = g_onCallbackInfos.find(sensorTypeId); iter == g_onCallbackInfos.end()) { SEN_HILOGW("No client subscribe, sensorTypeId:%{public}d", sensorTypeId); return false; } std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId]; for (auto callbackInfo : callbackInfos) { CHKPC(callbackInfo); if (callbackInfo->env != env) { continue; } napi_value sensorCallback = nullptr; CHKNRF(env, napi_get_reference_value(env, callbackInfo->callback[0], &sensorCallback), "napi_get_reference_value"); if (IsSameValue(env, callback, sensorCallback)) { return true; } } return false; } static void UpdateCallbackInfos(napi_env env, int32_t sensorTypeId, napi_value callback) { CALL_LOG_ENTER; std::lock_guard<std::mutex> onCallbackLock(onMutex_); CHKCV((!IsSubscribed(env, sensorTypeId, callback)), "The callback has been subscribed"); sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ON_CALLBACK); CHKPV(asyncCallbackInfo); napi_status status = napi_create_reference(env, callback, 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return; } std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId]; callbackInfos.push_back(asyncCallbackInfo); g_onCallbackInfos[sensorTypeId] = callbackInfos; } static napi_value On(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 3; napi_value args[3] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 2) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if ((!IsMatchType(env, args[0], napi_number)) || (!IsMatchType(env, args[1], napi_function))) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type"); return nullptr; } int32_t sensorTypeId = INVALID_SENSOR_ID; if (!GetNativeInt32(env, args[0], sensorTypeId)) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get number fail"); return nullptr; } int64_t interval = REPORTING_INTERVAL; if (argc >= 3 && IsMatchType(env, args[2], napi_object)) { napi_value value = GetNamedProperty(env, args[2], "interval"); if (IsMatchType(env, value, napi_number)) { GetNativeInt64(env, value, interval); } } SEN_HILOGD("Interval is %{public}" PRId64, interval); int32_t ret = SubscribeSensor(sensorTypeId, interval, DataCallbackImpl); if (ret != ERR_OK) { ThrowErr(env, ret, "SubscribeSensor fail"); return nullptr; } UpdateCallbackInfos(env, sensorTypeId, args[1]); return nullptr; } static int32_t RemoveAllCallback(napi_env env, int32_t sensorTypeId) { CALL_LOG_ENTER; std::lock_guard<std::mutex> onCallbackLock(onMutex_); std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId]; for (auto iter = callbackInfos.begin(); iter != callbackInfos.end();) { CHKPC(*iter); if ((*iter)->env != env) { ++iter; continue; } iter = callbackInfos.erase(iter); } if (callbackInfos.empty()) { SEN_HILOGD("No subscription to change sensor data"); g_onCallbackInfos.erase(sensorTypeId); return 0; } g_onCallbackInfos[sensorTypeId] = callbackInfos; return callbackInfos.size(); } static int32_t RemoveCallback(napi_env env, int32_t sensorTypeId, napi_value callback) { CALL_LOG_ENTER; std::lock_guard<std::mutex> onCallbackLock(onMutex_); std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId]; for (auto iter = callbackInfos.begin(); iter != callbackInfos.end(); ++iter) { CHKPC(*iter); if ((*iter)->env != env) { continue; } napi_value sensorCallback = nullptr; if (napi_get_reference_value(env, (*iter)->callback[0], &sensorCallback) != napi_ok) { SEN_HILOGE("napi_get_reference_value fail"); continue; } if (IsSameValue(env, callback, sensorCallback)) { callbackInfos.erase(iter++); SEN_HILOGD("Remove callback success"); break; } } if (callbackInfos.empty()) { SEN_HILOGD("No subscription to change sensor data"); g_onCallbackInfos.erase(sensorTypeId); return 0; } g_onCallbackInfos[sensorTypeId] = callbackInfos; return callbackInfos.size(); } static napi_value Off(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 2; napi_value args[2] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } int32_t sensorTypeId = INVALID_SENSOR_ID; if ((!IsMatchType(env, args[0], napi_number)) || (!GetNativeInt32(env, args[0], sensorTypeId))) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type or get number fail"); return nullptr; } int32_t subscribeSize = -1; if (argc == 1) { subscribeSize = RemoveAllCallback(env, sensorTypeId); } else if (IsMatchType(env, args[1], napi_undefined) || IsMatchType(env, args[1], napi_null)) { subscribeSize = RemoveAllCallback(env, sensorTypeId); } else if (IsMatchType(env, args[1], napi_function)) { subscribeSize = RemoveCallback(env, sensorTypeId, args[1]); } else { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, args[1] should is napi_function"); return nullptr; } if (CheckSystemSubscribe(sensorTypeId) || (subscribeSize > 0)) { SEN_HILOGW("There are other client subscribe system js api as well, not need unsubscribe"); return nullptr; } int32_t ret = UnsubscribeSensor(sensorTypeId); if (ret == PARAMETER_ERROR || ret == PERMISSION_DENIED) { ThrowErr(env, ret, "UnsubscribeSensor fail"); } return nullptr; } static napi_value GetGeomagneticField(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 3; napi_value args[3] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 2) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if ((!IsMatchType(env, args[0], napi_object)) || (!IsMatchType(env, args[1], napi_number))) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type"); return nullptr; } napi_value napiLatitude = GetNamedProperty(env, args[0], "latitude"); if (napiLatitude == nullptr) { ThrowErr(env, PARAMETER_ERROR, "napiLatitude is null"); return nullptr; } double latitude = 0; if (!GetNativeDouble(env, napiLatitude, latitude)) { ThrowErr(env, PARAMETER_ERROR, "Get latitude fail"); return nullptr; } napi_value napiLongitude = GetNamedProperty(env, args[0], "longitude"); if (napiLongitude == nullptr) { ThrowErr(env, PARAMETER_ERROR, "napiLongitude is null"); return nullptr; } double longitude = 0; if (!GetNativeDouble(env, napiLongitude, longitude)) { ThrowErr(env, PARAMETER_ERROR, "Get longitude fail"); return nullptr; } napi_value napiAltitude = GetNamedProperty(env, args[0], "altitude"); if (napiAltitude == nullptr) { ThrowErr(env, PARAMETER_ERROR, "napiAltitude is null"); return nullptr; } double altitude = 0; if (!GetNativeDouble(env, napiAltitude, altitude)) { ThrowErr(env, PARAMETER_ERROR, "Get altitude fail"); return nullptr; } int64_t timeMillis = 0; if (!GetNativeInt64(env, args[1], timeMillis)) { ThrowErr(env, PARAMETER_ERROR, "Get timeMillis fail"); return nullptr; } GeomagneticField geomagneticField(latitude, longitude, altitude, timeMillis); sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_GEOMAGNETIC_FIELD); CHKPP(asyncCallbackInfo); asyncCallbackInfo->data.geomagneticData = { .x = geomagneticField.ObtainX(), .y = geomagneticField.ObtainY(), .z = geomagneticField.ObtainZ(), .geomagneticDip = geomagneticField.ObtainGeomagneticDip(), .deflectionAngle = geomagneticField.ObtainDeflectionAngle(), .levelIntensity = geomagneticField.ObtainLevelIntensity(), .totalIntensity = geomagneticField.ObtainTotalIntensity(), }; if (argc >=3 && IsMatchType(env, args[2], napi_function)) { status = napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value GetAxisX(napi_env env, napi_value value) { return GetNamedProperty(env, value, "x"); } static napi_value GetAxisY(napi_env env, napi_value value) { return GetNamedProperty(env, value, "y"); } static napi_value TransformCoordinateSystem(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 3; napi_value args[3] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 2) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if ((!IsMatchArrayType(env, args[0])) || (!IsMatchType(env, args[1], napi_object))) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type"); return nullptr; } std::vector<float> inRotationVector; if (!GetFloatArray(env, args[0], inRotationVector)) { ThrowErr(env, PARAMETER_ERROR, "Get inRotationVector fail"); return nullptr; } size_t length = inRotationVector.size(); if ((length != DATA_LENGTH) && (length != THREE_DIMENSIONAL_MATRIX_LENGTH)) { ThrowErr(env, PARAMETER_ERROR, "Wrong inRotationVector length"); return nullptr; } napi_value napiAxisX = GetAxisX(env, args[1]); if (napiAxisX == nullptr) { ThrowErr(env, PARAMETER_ERROR, "napiAxisX is null"); return nullptr; } int32_t axisX = 0; if (!GetNativeInt32(env, napiAxisX, axisX)) { ThrowErr(env, PARAMETER_ERROR, "Get axisY fail"); return nullptr; } napi_value napiAxisY = GetAxisY(env, args[1]); if (napiAxisY == nullptr) { ThrowErr(env, PARAMETER_ERROR, "napiAxisY is null"); return nullptr; } int32_t axisY = 0; if (!GetNativeInt32(env, napiAxisY, axisY)) { ThrowErr(env, PARAMETER_ERROR, "Get axisY fail"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, TRANSFORM_COORDINATE_SYSTEM); CHKPP(asyncCallbackInfo); std::vector<float> outRotationVector(length); SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.TransformCoordinateSystem(inRotationVector, axisX, axisY, outRotationVector); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "Transform coordinate system fail"); return nullptr; } else { for (size_t i = 0; i < length; ++i) { asyncCallbackInfo->data.reserveData.reserve[i] = outRotationVector[i]; } asyncCallbackInfo->data.reserveData.length = static_cast<int32_t>(length); } if (argc >= 3 && IsMatchType(env, args[2], napi_function)) { status = napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value GetAngleModify(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 3; napi_value args[3] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 2) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if (!IsMatchArrayType(env, args[0])) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array"); return nullptr; } if (!IsMatchArrayType(env, args[1])) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_ANGLE_MODIFY); CHKPP(asyncCallbackInfo); std::vector<float> curRotationVector; if (!GetFloatArray(env, args[0], curRotationVector)) { ThrowErr(env, PARAMETER_ERROR, "Get curRotationVector fail"); return nullptr; } std::vector<float> preRotationVector; if (!GetFloatArray(env, args[1], preRotationVector)) { ThrowErr(env, PARAMETER_ERROR, "Get preRotationVector fail"); return nullptr; } std::vector<float> angleChange(ROTATION_VECTOR_LENGTH); SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.GetAngleModify(curRotationVector, preRotationVector, angleChange); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "Get angle modify fail"); return nullptr; } else { asyncCallbackInfo->data.reserveData.length = ROTATION_VECTOR_LENGTH; for (int32_t i = 0; i < ROTATION_VECTOR_LENGTH; ++i) { asyncCallbackInfo->data.reserveData.reserve[i] = angleChange[i]; } } if (argc >= 3 && IsMatchType(env, args[2], napi_function)) { status = napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value GetDirection(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 3; napi_value args[3] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if (!IsMatchArrayType(env, args[0])) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_DIRECTION); CHKPP(asyncCallbackInfo); std::vector<float> rotationMatrix; if (!GetFloatArray(env, args[0], rotationMatrix)) { ThrowErr(env, PARAMETER_ERROR, "Get rotationMatrix fail"); return nullptr; } std::vector<float> rotationAngle(ROTATION_VECTOR_LENGTH); SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.GetDirection(rotationMatrix, rotationAngle); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "Get direction fail"); return nullptr; } else { asyncCallbackInfo->data.reserveData.length = ROTATION_VECTOR_LENGTH; for (int32_t i = 0; i < ROTATION_VECTOR_LENGTH; ++i) { asyncCallbackInfo->data.reserveData.reserve[i] = rotationAngle[i]; } } if (argc >= 2 && IsMatchType(env, args[1], napi_function)) { status = napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value CreateQuaternion(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 2; napi_value args[2] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if (!IsMatchArrayType(env, args[0])) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, CREATE_QUATERNION); CHKPP(asyncCallbackInfo); std::vector<float> rotationVector; if (!GetFloatArray(env, args[0], rotationVector)) { ThrowErr(env, PARAMETER_ERROR, "Get rotationVector fail"); return nullptr; } std::vector<float> quaternion(QUATERNION_LENGTH); SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.CreateQuaternion(rotationVector, quaternion); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "CreateQuaternion fail"); return nullptr; } else { asyncCallbackInfo->data.reserveData.length = QUATERNION_LENGTH; for (int32_t i = 0; i < QUATERNION_LENGTH; ++i) { asyncCallbackInfo->data.reserveData.reserve[i] = quaternion[i]; } } if (argc >= 2 && IsMatchType(env, args[1], napi_function)) { status = napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value GetAltitude(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 3; napi_value args[3] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 2) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if ((!IsMatchType(env, args[0], napi_number)) || (!IsMatchType(env, args[1], napi_number))) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_ALTITUDE); CHKPP(asyncCallbackInfo); float seaPressure = 0; if (!GetNativeFloat(env, args[0], seaPressure)) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get seaPressure fail"); return nullptr; } float currentPressure = 0; if (!GetNativeFloat(env, args[1], currentPressure)) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get currentPressure fail"); return nullptr; } float altitude = 0; SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.GetAltitude(seaPressure, currentPressure, &altitude); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "Get altitude fail"); return nullptr; } else { asyncCallbackInfo->data.reserveData.reserve[0] = altitude; } if (argc >= 3 && IsMatchType(env, args[2], napi_function)) { status = napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value GetGeomagneticDip(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 2; napi_value args[2] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if (!IsMatchArrayType(env, args[0])) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_GEOMAGNETIC_DIP); CHKPP(asyncCallbackInfo); std::vector<float> inclinationMatrix; if (!GetFloatArray(env, args[0], inclinationMatrix)) { ThrowErr(env, PARAMETER_ERROR, "Get inclinationMatrix fail"); return nullptr; } float geomagneticDip = 0; SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.GetGeomagneticDip(inclinationMatrix, &geomagneticDip); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "Get geomagnetic dip fail"); return nullptr; } else { asyncCallbackInfo->data.reserveData.reserve[0] = geomagneticDip; } if (argc >= 2 && IsMatchType(env, args[1], napi_function)) { status = napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value CreateRotationAndInclination(const napi_env &env, napi_value args[], size_t argc) { CALL_LOG_ENTER; if (argc < 2) { ThrowErr(env, PARAMETER_ERROR, "The number of parameters is not valid"); return nullptr; } std::vector<float> gravity; if (!GetFloatArray(env, args[0], gravity)) { ThrowErr(env, PARAMETER_ERROR, "Get gravity fail"); return nullptr; } std::vector<float> geomagnetic; if (!GetFloatArray(env, args[1], geomagnetic)) { ThrowErr(env, PARAMETER_ERROR, "Get geomagnetic fail"); return nullptr; } std::vector<float> rotation(THREE_DIMENSIONAL_MATRIX_LENGTH); std::vector<float> inclination(THREE_DIMENSIONAL_MATRIX_LENGTH); sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ROTATION_INCLINATION_MATRIX); CHKPP(asyncCallbackInfo); SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.CreateRotationAndInclination(gravity, geomagnetic, rotation, inclination); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "Create rotation and inclination matrix fail"); return nullptr; } else { asyncCallbackInfo->data.reserveData.length = THREE_DIMENSIONAL_MATRIX_LENGTH; for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) { asyncCallbackInfo->data.rationMatrixData.rotationMatrix[i] = rotation[i]; } for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) { asyncCallbackInfo->data.rationMatrixData.inclinationMatrix[i] = inclination[i]; } } napi_status status; if (argc >= 3 && IsMatchType(env, args[2], napi_function)) { status = napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value GetRotationMatrix(const napi_env &env, napi_value args[], size_t argc) { CALL_LOG_ENTER; if (argc < 1) { ThrowErr(env, PARAMETER_ERROR, "The number of parameters is not valid"); return nullptr; } std::vector<float> rotationVector; if (!GetFloatArray(env, args[0], rotationVector)) { ThrowErr(env, PARAMETER_ERROR, "Get rotationVector fail"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, CREATE_ROTATION_MATRIX); CHKPP(asyncCallbackInfo); std::vector<float> rotationMatrix(THREE_DIMENSIONAL_MATRIX_LENGTH); SensorAlgorithm sensorAlgorithm; int32_t ret = sensorAlgorithm.CreateRotationMatrix(rotationVector, rotationMatrix); if (ret != OHOS::ERR_OK) { ThrowErr(env, ret, "Create rotation matrix fail"); return nullptr; } else { asyncCallbackInfo->data.reserveData.length = THREE_DIMENSIONAL_MATRIX_LENGTH; for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) { asyncCallbackInfo->data.reserveData.reserve[i] = rotationMatrix[i]; } } napi_status status; if (argc >= 2 && IsMatchType(env, args[1], napi_function)) { status = napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value CreateRotationMatrix(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 3; napi_value args[3] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if (!IsMatchArrayType(env, args[0])) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array"); return nullptr; } if (argc >= 2 && IsMatchArrayType(env, args[1])) { return CreateRotationAndInclination(env, args, argc); } else { return GetRotationMatrix(env, args, argc); } } static napi_value GetSensorList(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 1; napi_value args[1] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_SENSOR_LIST); CHKPP(asyncCallbackInfo); SensorInfo *sensorInfos = nullptr; int32_t count = 0; int32_t ret = GetAllSensors(&sensorInfos, &count); if (ret != OHOS::ERR_OK) { SEN_HILOGE("Get sensor list fail"); asyncCallbackInfo->type = FAIL; asyncCallbackInfo->error.code = ret; } else { for (int32_t i = 0; i < count; ++i) { asyncCallbackInfo->sensorInfos.push_back(*(sensorInfos + i)); } } if (argc >= 1 && IsMatchType(env, args[0], napi_function)) { status = napi_create_reference(env, args[0], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } static napi_value GetSingleSensor(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 2; napi_value args[2] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } int32_t sensorTypeId = INVALID_SENSOR_ID; if (!GetNativeInt32(env, args[0], sensorTypeId)) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get number fail"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_SINGLE_SENSOR); CHKPP(asyncCallbackInfo); SensorInfo *sensorInfos = nullptr; int32_t count = 0; int32_t ret = GetAllSensors(&sensorInfos, &count); if (ret != OHOS::ERR_OK) { SEN_HILOGE("Get sensor list fail"); asyncCallbackInfo->type = FAIL; asyncCallbackInfo->error.code = ret; } else { for (int32_t i = 0; i < count; ++i) { if (sensorInfos[i].sensorTypeId == sensorTypeId) { asyncCallbackInfo->sensorInfos.push_back(*(sensorInfos + i)); break; } } if (asyncCallbackInfo->sensorInfos.empty()) { ThrowErr(env, PARAMETER_ERROR, "Can't find the sensorId"); return nullptr; } } if (argc >= 2 && IsMatchType(env, args[1], napi_function)) { status = napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail"); return nullptr; } EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } napi_value promise = nullptr; status = napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_create_promise fail"); return nullptr; } EmitPromiseWork(asyncCallbackInfo); return promise; } napi_value Subscribe(napi_env env, napi_callback_info info, int32_t sensorTypeId, CallbackDataType type) { CALL_LOG_ENTER; size_t argc = 1; napi_value args[1] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if (!IsMatchType(env, args[0], napi_object)) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be object"); return nullptr; } string interval = "normal"; if ((sensorTypeId == SENSOR_TYPE_ID_ACCELEROMETER) || ((sensorTypeId == SENSOR_TYPE_ID_ORIENTATION) && (type != SUBSCRIBE_COMPASS)) || (sensorTypeId == SENSOR_TYPE_ID_GYROSCOPE)) { napi_value napiInterval = GetNamedProperty(env, args[0], "interval"); CHKCP(GetStringValue(env, napiInterval, interval), "get interval fail"); } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, type); CHKPP(asyncCallbackInfo); napi_value napiSuccess = GetNamedProperty(env, args[0], "success"); CHKCP(IsMatchType(env, napiSuccess, napi_function), "get napiSuccess fail"); CHKCP(RegisterNapiCallback(env, napiSuccess, asyncCallbackInfo->callback[0]), "register success callback fail"); napi_value napiFail = GetNamedProperty(env, args[0], "fail"); if (IsMatchType(env, napiFail, napi_function)) { SEN_HILOGD("Has fail callback"); CHKCP(RegisterNapiCallback(env, napiFail, asyncCallbackInfo->callback[1]), "register fail callback fail"); } if (auto iter = g_samplingPeriod.find(interval); iter == g_samplingPeriod.end()) { CHKCP(IsMatchType(env, napiFail, napi_function), "input error, interval is invalid"); CreateFailMessage(SUBSCRIBE_FAIL, INPUT_ERROR, "input error", asyncCallbackInfo); EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } int32_t ret = SubscribeSensor(sensorTypeId, g_samplingPeriod[interval], DataCallbackImpl); if (ret != OHOS::ERR_OK) { CHKCP(IsMatchType(env, napiFail, napi_function), "subscribe fail"); CreateFailMessage(SUBSCRIBE_FAIL, SENSOR_SUBSCRIBE_FAILURE, "subscribe fail", asyncCallbackInfo); EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } std::lock_guard<std::mutex> subscribeLock(mutex_); std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_subscribeCallbacks[sensorTypeId]; callbackInfos.push_back(asyncCallbackInfo); g_subscribeCallbacks[sensorTypeId] = callbackInfos; return nullptr; } static bool RemoveSubscribeCallback(napi_env env, int32_t sensorTypeId) { CALL_LOG_ENTER; std::lock_guard<std::mutex> subscribeCallbackLock(mutex_); std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_subscribeCallbacks[sensorTypeId]; for (auto iter = callbackInfos.begin(); iter != callbackInfos.end();) { CHKPC(*iter); if ((*iter)->env != env) { ++iter; continue; } iter = callbackInfos.erase(iter); } if (callbackInfos.empty()) { g_subscribeCallbacks.erase(sensorTypeId); return true; } return false; } napi_value Unsubscribe(napi_env env, napi_callback_info info, int32_t sensorTypeId) { CALL_LOG_ENTER; size_t argc = 1; napi_value args[1] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail"); return nullptr; } if (!RemoveSubscribeCallback(env, sensorTypeId) || CheckSubscribe(sensorTypeId)) { SEN_HILOGW("There are other client subscribe as well, not need unsubscribe"); return nullptr; } if (UnsubscribeSensor(sensorTypeId) != OHOS::ERR_OK) { SEN_HILOGW("UnsubscribeSensor failed"); return nullptr; } return nullptr; } napi_value GetBodyState(napi_env env, napi_callback_info info) { CALL_LOG_ENTER; size_t argc = 1; napi_value args[1] = { 0 }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); if (status != napi_ok || argc < 1) { ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid"); return nullptr; } if (!IsMatchType(env, args[0], napi_object)) { ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be object"); return nullptr; } sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_BODY_STATE); CHKPP(asyncCallbackInfo); napi_value napiSuccess = GetNamedProperty(env, args[0], "success"); CHKCP(IsMatchType(env, napiSuccess, napi_function), "get napiSuccess fail"); CHKCP(RegisterNapiCallback(env, napiSuccess, asyncCallbackInfo->callback[0]), "register success callback fail"); std::lock_guard<std::mutex> onBodyLock(bodyMutex_); asyncCallbackInfo->data.sensorData.data[0] = (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false; EmitUvEventLoop(asyncCallbackInfo); return nullptr; } static napi_value EnumClassConstructor(napi_env env, napi_callback_info info) { size_t argc = 0; napi_value args[1] = {0}; napi_value ret = nullptr; void *data = nullptr; CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &ret, &data), "napi_get_cb_info"); return ret; } static napi_value CreateEnumSensorType(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ACCELEROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GYROSCOPE", GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_AMBIENT_LIGHT", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_LIGHT)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_MAGNETIC_FIELD", GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_BAROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_BAROMETER)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HALL", GetNapiInt32(env, SENSOR_TYPE_ID_HALL)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_TEMPERATURE", GetNapiInt32(env, SENSOR_TYPE_ID_TEMPERATURE)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PROXIMITY", GetNapiInt32(env, SENSOR_TYPE_ID_PROXIMITY)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HUMIDITY", GetNapiInt32(env, SENSOR_TYPE_ID_HUMIDITY)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_COLOR", GetNapiInt32(env, SENSOR_TYPE_ID_COLOR)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_SAR", GetNapiInt32(env, SENSOR_TYPE_ID_SAR)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ORIENTATION", GetNapiInt32(env, SENSOR_TYPE_ID_ORIENTATION)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GRAVITY", GetNapiInt32(env, SENSOR_TYPE_ID_GRAVITY)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_LINEAR_ACCELERATION", GetNapiInt32(env, SENSOR_TYPE_ID_LINEAR_ACCELERATION)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ROTATION_VECTOR", GetNapiInt32(env, SENSOR_TYPE_ID_ROTATION_VECTOR)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_AMBIENT_TEMPERATURE", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_TEMPERATURE)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED", GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED", GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_SIGNIFICANT_MOTION", GetNapiInt32(env, SENSOR_TYPE_ID_SIGNIFICANT_MOTION)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PEDOMETER_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER_DETECTION)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PEDOMETER", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HEART_RATE", GetNapiInt32(env, SENSOR_TYPE_ID_HEART_RATE)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_WEAR_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_WEAR_DETECTION)), DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED", GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED)), }; napi_value result = nullptr; CHKNRP(env, napi_define_class(env, "SensorType", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr, sizeof(desc) / sizeof(*desc), desc, &result), "napi_define_class"); CHKNRP(env, napi_set_named_property(env, exports, "SensorType", result), "napi_set_named_property fail"); return exports; } static napi_value CreateEnumSensorId(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { DECLARE_NAPI_STATIC_PROPERTY("ACCELEROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER)), DECLARE_NAPI_STATIC_PROPERTY("GYROSCOPE", GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE)), DECLARE_NAPI_STATIC_PROPERTY("AMBIENT_LIGHT", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_LIGHT)), DECLARE_NAPI_STATIC_PROPERTY("MAGNETIC_FIELD", GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD)), DECLARE_NAPI_STATIC_PROPERTY("BAROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_BAROMETER)), DECLARE_NAPI_STATIC_PROPERTY("HALL", GetNapiInt32(env, SENSOR_TYPE_ID_HALL)), DECLARE_NAPI_STATIC_PROPERTY("TEMPERATURE", GetNapiInt32(env, SENSOR_TYPE_ID_TEMPERATURE)), DECLARE_NAPI_STATIC_PROPERTY("PROXIMITY", GetNapiInt32(env, SENSOR_TYPE_ID_PROXIMITY)), DECLARE_NAPI_STATIC_PROPERTY("HUMIDITY", GetNapiInt32(env, SENSOR_TYPE_ID_HUMIDITY)), DECLARE_NAPI_STATIC_PROPERTY("COLOR", GetNapiInt32(env, SENSOR_TYPE_ID_COLOR)), DECLARE_NAPI_STATIC_PROPERTY("SAR", GetNapiInt32(env, SENSOR_TYPE_ID_SAR)), DECLARE_NAPI_STATIC_PROPERTY("ORIENTATION", GetNapiInt32(env, SENSOR_TYPE_ID_ORIENTATION)), DECLARE_NAPI_STATIC_PROPERTY("GRAVITY", GetNapiInt32(env, SENSOR_TYPE_ID_GRAVITY)), DECLARE_NAPI_STATIC_PROPERTY("LINEAR_ACCELEROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_LINEAR_ACCELERATION)), DECLARE_NAPI_STATIC_PROPERTY("ROTATION_VECTOR", GetNapiInt32(env, SENSOR_TYPE_ID_ROTATION_VECTOR)), DECLARE_NAPI_STATIC_PROPERTY("AMBIENT_TEMPERATURE", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_TEMPERATURE)), DECLARE_NAPI_STATIC_PROPERTY("MAGNETIC_FIELD_UNCALIBRATED", GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED)), DECLARE_NAPI_STATIC_PROPERTY("GYROSCOPE_UNCALIBRATED", GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED)), DECLARE_NAPI_STATIC_PROPERTY("SIGNIFICANT_MOTION", GetNapiInt32(env, SENSOR_TYPE_ID_SIGNIFICANT_MOTION)), DECLARE_NAPI_STATIC_PROPERTY("PEDOMETER_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER_DETECTION)), DECLARE_NAPI_STATIC_PROPERTY("PEDOMETER", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER)), DECLARE_NAPI_STATIC_PROPERTY("HEART_RATE", GetNapiInt32(env, SENSOR_TYPE_ID_HEART_RATE)), DECLARE_NAPI_STATIC_PROPERTY("WEAR_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_WEAR_DETECTION)), DECLARE_NAPI_STATIC_PROPERTY("ACCELEROMETER_UNCALIBRATED", GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED)), }; napi_value result = nullptr; CHKNRP(env, napi_define_class(env, "SensorId", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr, sizeof(desc) / sizeof(*desc), desc, &result), "napi_define_class"); CHKNRP(env, napi_set_named_property(env, exports, "SensorId", result), "napi_set_named_property fail"); return exports; } static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { DECLARE_NAPI_FUNCTION("on", On), DECLARE_NAPI_FUNCTION("once", Once), DECLARE_NAPI_FUNCTION("off", Off), DECLARE_NAPI_FUNCTION("getGeomagneticField", GetGeomagneticField), DECLARE_NAPI_FUNCTION("getGeomagneticInfo", GetGeomagneticField), DECLARE_NAPI_FUNCTION("transformCoordinateSystem", TransformCoordinateSystem), DECLARE_NAPI_FUNCTION("transformRotationMatrix", TransformCoordinateSystem), DECLARE_NAPI_FUNCTION("getAngleModify", GetAngleModify), DECLARE_NAPI_FUNCTION("getAngleVariation", GetAngleModify), DECLARE_NAPI_FUNCTION("getDirection", GetDirection), DECLARE_NAPI_FUNCTION("getOrientation", GetDirection), DECLARE_NAPI_FUNCTION("createQuaternion", CreateQuaternion), DECLARE_NAPI_FUNCTION("getQuaternion", CreateQuaternion), DECLARE_NAPI_FUNCTION("getAltitude", GetAltitude), DECLARE_NAPI_FUNCTION("getDeviceAltitude", GetAltitude), DECLARE_NAPI_FUNCTION("getGeomagneticDip", GetGeomagneticDip), DECLARE_NAPI_FUNCTION("getInclination", GetGeomagneticDip), DECLARE_NAPI_FUNCTION("createRotationMatrix", CreateRotationMatrix), DECLARE_NAPI_FUNCTION("getRotationMatrix", CreateRotationMatrix), DECLARE_NAPI_FUNCTION("getSensorList", GetSensorList), DECLARE_NAPI_FUNCTION("getSingleSensor", GetSingleSensor), DECLARE_NAPI_FUNCTION("subscribeAccelerometer", SubscribeAccelerometer), DECLARE_NAPI_FUNCTION("unsubscribeAccelerometer", UnsubscribeAccelerometer), DECLARE_NAPI_FUNCTION("subscribeCompass", SubscribeCompass), DECLARE_NAPI_FUNCTION("unsubscribeCompass", UnsubscribeCompass), DECLARE_NAPI_FUNCTION("subscribeProximity", SubscribeProximity), DECLARE_NAPI_FUNCTION("unsubscribeProximity", UnsubscribeProximity), DECLARE_NAPI_FUNCTION("subscribeLight", SubscribeLight), DECLARE_NAPI_FUNCTION("unsubscribeLight", UnsubscribeLight), DECLARE_NAPI_FUNCTION("subscribeStepCounter", SubscribeStepCounter), DECLARE_NAPI_FUNCTION("unsubscribeStepCounter", UnsubscribeStepCounter), DECLARE_NAPI_FUNCTION("subscribeBarometer", SubscribeBarometer), DECLARE_NAPI_FUNCTION("unsubscribeBarometer", UnsubscribeBarometer), DECLARE_NAPI_FUNCTION("subscribeHeartRate", SubscribeHeartRate), DECLARE_NAPI_FUNCTION("unsubscribeHeartRate", UnsubscribeHeartRate), DECLARE_NAPI_FUNCTION("subscribeOnBodyState", SubscribeOnBodyState), DECLARE_NAPI_FUNCTION("unsubscribeOnBodyState", UnsubscribeOnBodyState), DECLARE_NAPI_FUNCTION("getOnBodyState", GetOnBodyState), DECLARE_NAPI_FUNCTION("subscribeDeviceOrientation", SubscribeDeviceOrientation), DECLARE_NAPI_FUNCTION("unsubscribeDeviceOrientation", UnsubscribeDeviceOrientation), DECLARE_NAPI_FUNCTION("subscribeGyroscope", SubscribeGyroscope), DECLARE_NAPI_FUNCTION("unsubscribeGyroscope", UnsubscribeGyroscope), DECLARE_NAPI_FUNCTION("subscribeGravity", SubscribeGravity), DECLARE_NAPI_FUNCTION("unsubscribeGravity", UnsubscribeGravity), DECLARE_NAPI_FUNCTION("subscribeMagnetic", SubscribeMagnetic), DECLARE_NAPI_FUNCTION("unsubscribeMagnetic", UnsubscribeMagnetic), DECLARE_NAPI_FUNCTION("subscribeHall", SubscribeHall), DECLARE_NAPI_FUNCTION("unsubscribeHall", UnsubscribeHall), }; CHKNRP(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc), "napi_define_properties"); CHKCP(CreateEnumSensorType(env, exports), "Create enum sensor type fail"); CHKCP(CreateEnumSensorId(env, exports), "Create enum sensor id fail"); return exports; } static napi_module _module = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "sensor", .nm_priv = ((void *)0), .reserved = {0} }; extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&_module); } } // namespace Sensors } // namespace OHOS