From ebcbdc0da21f4dbcbe2490856b52a869287f4bc8 Mon Sep 17 00:00:00 2001 From: wuzhihuitmac Date: Wed, 12 Mar 2025 15:04:15 +0800 Subject: [PATCH] Modify the problem about data repeat Signed-off-by: wuzhihuitmac Change-Id: Ic3e70e2dab75b601c03a21ee7b450c4bbcdc3193 --- .../js/napi/include/sensor_napi_utils.h | 3 + frameworks/js/napi/src/sensor_js.cpp | 39 +++++++- frameworks/js/napi/src/sensor_napi_utils.cpp | 90 +++++++++++++++++++ 3 files changed, 130 insertions(+), 2 deletions(-) diff --git a/frameworks/js/napi/include/sensor_napi_utils.h b/frameworks/js/napi/include/sensor_napi_utils.h index cbd70ed3..0a569f15 100644 --- a/frameworks/js/napi/include/sensor_napi_utils.h +++ b/frameworks/js/napi/include/sensor_napi_utils.h @@ -42,6 +42,7 @@ napi_value GetNapiInt32(const napi_env &env, int32_t number); bool GetStringValue(const napi_env &env, const napi_value &value, string &result); void EmitAsyncCallbackWork(sptr asyncCallbackInfo); void EmitUvEventLoop(sptr asyncCallbackInfo); +void EmitOnUvEventLoop(sptr asyncCallbackInfo, std::shared_ptr cb); void EmitPromiseWork(sptr asyncCallbackInfo); bool ConvertToFailData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); bool ConvertToGeomagneticData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); @@ -49,6 +50,8 @@ bool ConvertToNumber(const napi_env &env, sptr asyncCallbackI bool ConvertToArray(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); bool ConvertToRotationMatrix(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); bool ConvertToSensorData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); +bool ConvertOnSensorData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2], + std::shared_ptr data); bool CreateNapiArray(const napi_env &env, float *data, int32_t dataLength, napi_value &result); bool ConvertToSensorInfos(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); bool ConvertToSingleSensor(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); diff --git a/frameworks/js/napi/src/sensor_js.cpp b/frameworks/js/napi/src/sensor_js.cpp index f1d3140a..e79496e6 100644 --- a/frameworks/js/napi/src/sensor_js.cpp +++ b/frameworks/js/napi/src/sensor_js.cpp @@ -98,6 +98,40 @@ static bool copySensorData(sptr callbackInfo, SensorEvent *ev return true; } +static bool copyOnSensorData(sptr callbackInfo, SensorEvent *event, + std::shared_ptr cb) +{ + CHKPF(callbackInfo); + CHKPF(event); + int32_t sensorTypeId = event->sensorTypeId; + cb->sensorTypeId = sensorTypeId; + cb->dataLength = event->dataLen; + cb->timestamp = event->timestamp; + cb->sensorAccuracy = event->option; + CHKPF(event->data); + if (event->dataLen < sizeof(float)) { + SEN_HILOGE("Event dataLen less than float size"); + return false; + } + auto data = reinterpret_cast(event->data); + if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && callbackInfo->type == SUBSCRIBE_CALLBACK) { + std::lock_guard onBodyLock(g_bodyMutex); + g_bodyState = *data; + cb->data[0] = (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false; + return true; + } + if (sizeof(cb->data) < event->dataLen) { + SEN_HILOGE("callbackInfo space is insufficient"); + return false; + } + if (memcpy_s(cb->data, sizeof(cb->data), + data, event->dataLen) != EOK) { + SEN_HILOGE("Copy data failed"); + return false; + } + return true; +} + static bool CheckSystemSubscribe(int32_t sensorTypeId) { std::lock_guard subscribeLock(g_mutex); @@ -136,11 +170,12 @@ static void EmitOnCallback(SensorEvent *event) std::lock_guard onCallbackLock(g_onMutex); auto onCallbackInfos = g_onCallbackInfos[sensorTypeId]; for (auto &onCallbackInfo : onCallbackInfos) { - if (!copySensorData(onCallbackInfo, event)) { + std::shared_ptr cb = std::make_shared(); + if (!copyOnSensorData(onCallbackInfo, event, cb)) { SEN_HILOGE("Copy sensor data failed"); continue; } - EmitUvEventLoop(onCallbackInfo); + EmitOnUvEventLoop(onCallbackInfo, cb); } } diff --git a/frameworks/js/napi/src/sensor_napi_utils.cpp b/frameworks/js/napi/src/sensor_napi_utils.cpp index 66d14d78..809d2846 100644 --- a/frameworks/js/napi/src/sensor_napi_utils.cpp +++ b/frameworks/js/napi/src/sensor_napi_utils.cpp @@ -352,6 +352,45 @@ bool ConvertToSensorData(const napi_env &env, sptr asyncCallb return true; } +bool ConvertOnSensorData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2], + std::shared_ptr data) +{ + CHKPF(asyncCallbackInfo); + int32_t sensorTypeId = data->sensorTypeId; + std::lock_guard sensorAttrListLock(g_sensorAttrListMutex); + CHKNCF(env, (g_sensorAttributeList.find(sensorTypeId) != g_sensorAttributeList.end()), "Invalid sensor type"); + if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && asyncCallbackInfo->type == SUBSCRIBE_CALLBACK) { + CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object"); + napi_value status = nullptr; + CHKNRF(env, napi_get_boolean(env, data->data[0], &status), + "napi_get_boolean"); + CHKNRF(env, napi_set_named_property(env, result[1], "value", status), "napi_set_named_property"); + return true; + } + size_t size = g_sensorAttributeList[sensorTypeId].size(); + uint32_t dataLength = data->dataLength / sizeof(float); + CHKNCF(env, (size <= dataLength), "Data length mismatch"); + + CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object"); + napi_value message = nullptr; + auto sensorAttributes = g_sensorAttributeList[sensorTypeId]; + for (uint32_t i = 0; i < size; ++i) { + CHKNRF(env, napi_create_double(env, data->data[i], &message), + "napi_create_double"); + CHKNRF(env, napi_set_named_property(env, result[1], sensorAttributes[i].c_str(), message), + "napi_set_named_property"); + message = nullptr; + } + CHKNRF(env, napi_create_int64(env, data->timestamp, &message), + "napi_create_int64"); + CHKNRF(env, napi_set_named_property(env, result[1], "timestamp", message), "napi_set_named_property"); + message = nullptr; + CHKNRF(env, napi_create_int32(env, data->sensorAccuracy, &message), + "napi_create_int32"); + CHKNRF(env, napi_set_named_property(env, result[1], "accuracy", message), "napi_set_named_property"); + return true; +} + bool ConvertToGeomagneticData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]) { CALL_LOG_ENTER; @@ -572,6 +611,57 @@ void EmitUvEventLoop(sptr asyncCallbackInfo) } } +void EmitOnUvEventLoop(sptr asyncCallbackInfo, std::shared_ptr cb) +{ + CHKPV(asyncCallbackInfo); + asyncCallbackInfo->IncStrongRef(nullptr); + auto event = asyncCallbackInfo.GetRefPtr(); + auto task = [event, cb]() { + sptr asyncCallbackInfo(static_cast(event)); + /** + * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced + * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the + * asynchronous task is created, and subtract 1 from the reference count after the naked + * pointer is converted to a pointer when the asynchronous task is executed, the reference + * count of the smart pointer is guaranteed to be 1. + */ + asyncCallbackInfo->DecStrongRef(nullptr); + napi_handle_scope scope = nullptr; + napi_open_handle_scope(asyncCallbackInfo->env, &scope); + if (scope == nullptr) { + SEN_HILOGE("napi_handle_scope is nullptr"); + ReleaseCallback(asyncCallbackInfo); + return; + } + napi_env env = asyncCallbackInfo->env; + napi_value callback = nullptr; + if (napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) != napi_ok) { + SEN_HILOGE("napi_get_reference_value fail"); + napi_throw_error(env, nullptr, "napi_get_reference_value fail"); + ReleaseCallback(asyncCallbackInfo); + napi_close_handle_scope(asyncCallbackInfo->env, scope); + return; + } + napi_value callResult = nullptr; + napi_value result[2] = {0}; + ConvertOnSensorData(env, asyncCallbackInfo, result, cb); + if (napi_call_function(env, nullptr, callback, 1, &result[1], &callResult) != napi_ok) { + SEN_HILOGE("napi_call_function callback fail"); + napi_throw_error(env, nullptr, "napi_call_function callback fail"); + ReleaseCallback(asyncCallbackInfo); + napi_close_handle_scope(asyncCallbackInfo->env, scope); + return; + } + ReleaseCallback(asyncCallbackInfo); + napi_close_handle_scope(asyncCallbackInfo->env, scope); + }; + auto ret = napi_send_event(asyncCallbackInfo->env, task, napi_eprio_immediate); + if (ret != napi_ok) { + SEN_HILOGE("Failed to SendEvent, ret:%{public}d", ret); + asyncCallbackInfo->DecStrongRef(nullptr); + } +} + void EmitPromiseWork(sptr asyncCallbackInfo) { CALL_LOG_ENTER; -- Gitee