diff --git a/frameworks/js/napi/include/async_callback_info.h b/frameworks/js/napi/include/async_callback_info.h index 017ea65a86cb965f2c9ec6208d0a7ac815bb79a2..f0f817f8edea3ee8be67036946c3ec69cc3e3d0f 100644 --- a/frameworks/js/napi/include/async_callback_info.h +++ b/frameworks/js/napi/include/async_callback_info.h @@ -130,6 +130,18 @@ public: } } +private: +}; + +class ReportDataInfo : public RefBase { +public: + napi_env env = nullptr; + napi_ref callback[CALLBACK_NUM] = { 0 }; + CallbackData data; + CallbackDataType type; + ReportDataInfo(napi_env env, CallbackDataType type) : env(env), type(type) {} + ~ReportDataInfo() { } + private: }; } // namespace Sensors diff --git a/frameworks/js/napi/include/sensor_napi_utils.h b/frameworks/js/napi/include/sensor_napi_utils.h index cbd70ed370f51ceeab3f05336e30f9695b4daa95..a1ef7a5e1537d5c35f0e5dd997305970521dc8c3 100644 --- a/frameworks/js/napi/include/sensor_napi_utils.h +++ b/frameworks/js/napi/include/sensor_napi_utils.h @@ -27,6 +27,8 @@ using std::vector; using std::string; using ConvertDataFunc = bool(*)(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); +using SensorDataFunc = bool(*)(const napi_env &env, sptr reportDataInfo, + napi_value result[2]); bool IsSameValue(const napi_env &env, const napi_value &lhs, const napi_value &rhs); bool IsMatchType(const napi_env &env, const napi_value &value, const napi_valuetype &type); @@ -41,22 +43,21 @@ bool GetNativeFloat(const napi_env &env, const napi_value &value, float &number) 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 EmitUvEventLoop(sptr reportDataInfo); 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]); bool ConvertToNumber(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); 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 ConvertToSensorData(const napi_env &env, sptr reportDataInfo, napi_value result[2]); 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]); bool ConvertToSensorInfo(const napi_env &env, const SensorInfo &sensorInfo, napi_value &result); -bool ConvertToBodyData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); +bool ConvertToBodyData(const napi_env &env, sptr reportDataInfo, napi_value result[2]); bool CreateFailMessage(CallbackDataType type, int32_t code, string message, sptr &asyncCallbackInfo); -bool ConvertToBodyData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); bool ConvertToCompass(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]); void ReleaseCallback(sptr asyncCallbackInfo); bool GetSelfTargetVersion(uint32_t &targetVersion); diff --git a/frameworks/js/napi/src/sensor_js.cpp b/frameworks/js/napi/src/sensor_js.cpp index f1d3140adf2709ec3ec7174fb9927f74812451e3..215caa8fd7e605c02a4058b2abc438ab16e349d9 100644 --- a/frameworks/js/napi/src/sensor_js.cpp +++ b/frameworks/js/napi/src/sensor_js.cpp @@ -64,33 +64,33 @@ static bool CheckSubscribe(int32_t sensorTypeId) return iter != g_onCallbackInfos.end(); } -static bool copySensorData(sptr callbackInfo, SensorEvent *event) +static bool copySensorData(sptr reportDataInfo, SensorEvent *event) { - CHKPF(callbackInfo); + CHKPF(reportDataInfo); CHKPF(event); int32_t sensorTypeId = event->sensorTypeId; - callbackInfo->data.sensorData.sensorTypeId = sensorTypeId; - callbackInfo->data.sensorData.dataLength = event->dataLen; - callbackInfo->data.sensorData.timestamp = event->timestamp; - callbackInfo->data.sensorData.sensorAccuracy = event->option; + reportDataInfo->data.sensorData.sensorTypeId = sensorTypeId; + reportDataInfo->data.sensorData.dataLength = event->dataLen; + reportDataInfo->data.sensorData.timestamp = event->timestamp; + reportDataInfo->data.sensorData.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) { + if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && reportDataInfo->type == SUBSCRIBE_CALLBACK) { std::lock_guard onBodyLock(g_bodyMutex); g_bodyState = *data; - callbackInfo->data.sensorData.data[0] = + reportDataInfo->data.sensorData.data[0] = (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false; return true; } - if (sizeof(callbackInfo->data.sensorData.data) < event->dataLen) { - SEN_HILOGE("callbackInfo space is insufficient"); + if (sizeof(reportDataInfo->data.sensorData.data) < event->dataLen) { + SEN_HILOGE("reportDataInfo space is insufficient"); return false; } - if (memcpy_s(callbackInfo->data.sensorData.data, sizeof(callbackInfo->data.sensorData.data), + if (memcpy_s(reportDataInfo->data.sensorData.data, sizeof(reportDataInfo->data.sensorData.data), data, event->dataLen) != EOK) { SEN_HILOGE("Copy data failed"); return false; @@ -118,11 +118,14 @@ static void EmitSubscribeCallback(SensorEvent *event) std::lock_guard subscribeLock(g_mutex); auto callbacks = g_subscribeCallbacks[sensorTypeId]; for (auto &callback : callbacks) { - if (!copySensorData(callback, event)) { + sptr reportDataInfo = new (std::nothrow) ReportDataInfo(callback->env, callback->type); + CHKPV(reportDataInfo); + reportDataInfo->callback[0] = callback->callback[0]; + if (!copySensorData(reportDataInfo, event)) { SEN_HILOGE("Copy sensor data failed"); continue; } - EmitUvEventLoop(callback); + EmitUvEventLoop(reportDataInfo); } } @@ -136,11 +139,14 @@ static void EmitOnCallback(SensorEvent *event) std::lock_guard onCallbackLock(g_onMutex); auto onCallbackInfos = g_onCallbackInfos[sensorTypeId]; for (auto &onCallbackInfo : onCallbackInfos) { - if (!copySensorData(onCallbackInfo, event)) { + sptr reportDataInfo = new (std::nothrow) ReportDataInfo(onCallbackInfo->env, onCallbackInfo->type); + CHKPV(reportDataInfo); + reportDataInfo->callback[0] = onCallbackInfo->callback[0]; + if (!copySensorData(reportDataInfo, event)) { SEN_HILOGE("Copy sensor data failed"); continue; } - EmitUvEventLoop(onCallbackInfo); + EmitUvEventLoop(reportDataInfo); } } @@ -158,11 +164,14 @@ static void EmitOnceCallback(SensorEvent *event) auto onceCallbackInfo = onceCallbackInfos.front(); auto beginIter = onceCallbackInfos.begin(); onceCallbackInfos.erase(beginIter); - if (!copySensorData(onceCallbackInfo, event)) { + sptr reportDataInfo = new (std::nothrow) ReportDataInfo(onceCallbackInfo->env, onceCallbackInfo->type); + CHKPV(reportDataInfo); + reportDataInfo->callback[0] = onceCallbackInfo->callback[0]; + if (!copySensorData(reportDataInfo, event)) { SEN_HILOGE("Copy sensor data failed"); continue; } - EmitUvEventLoop(std::move(onceCallbackInfo)); + EmitUvEventLoop(std::move(reportDataInfo)); } g_onceCallbackInfos.erase(sensorTypeId); @@ -1300,7 +1309,10 @@ napi_value GetBodyState(napi_env env, napi_callback_info info) std::lock_guard onBodyLock(g_bodyMutex); asyncCallbackInfo->data.sensorData.data[0] = (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false; - EmitUvEventLoop(asyncCallbackInfo); + sptr reportDataInfo = new (std::nothrow) ReportDataInfo(asyncCallbackInfo->env, asyncCallbackInfo->type); + CHKPP(reportDataInfo); + reportDataInfo->callback[0] = asyncCallbackInfo->callback[0]; + EmitUvEventLoop(reportDataInfo); return nullptr; } diff --git a/frameworks/js/napi/src/sensor_napi_utils.cpp b/frameworks/js/napi/src/sensor_napi_utils.cpp index 66d14d784bb7301e0c63eb5fc910100cbb32a614..fe63d9b47c783d680e903ca31db0a173d8844b7b 100644 --- a/frameworks/js/napi/src/sensor_napi_utils.cpp +++ b/frameworks/js/napi/src/sensor_napi_utils.cpp @@ -193,8 +193,6 @@ std::map> g_sensorAttributeList = { std::map g_convertfuncList = { {FAIL, ConvertToFailData}, - {ON_CALLBACK, ConvertToSensorData}, - {ONCE_CALLBACK, ConvertToSensorData}, {GET_GEOMAGNETIC_FIELD, ConvertToGeomagneticData}, {GET_ALTITUDE, ConvertToNumber}, {GET_GEOMAGNETIC_DIP, ConvertToNumber}, @@ -206,9 +204,14 @@ std::map g_convertfuncList = { {ROTATION_INCLINATION_MATRIX, ConvertToRotationMatrix}, {GET_SENSOR_LIST, ConvertToSensorInfos}, {GET_SINGLE_SENSOR, ConvertToSingleSensor}, + {SUBSCRIBE_COMPASS, ConvertToCompass}, +}; + +std::map g_sensordatafuncList = { + {ON_CALLBACK, ConvertToSensorData}, + {ONCE_CALLBACK, ConvertToSensorData}, {GET_BODY_STATE, ConvertToBodyData}, {SUBSCRIBE_CALLBACK, ConvertToSensorData}, - {SUBSCRIBE_COMPASS, ConvertToCompass}, }; bool getJsonObject(const napi_env &env, sptr asyncCallbackInfo, napi_value &result) @@ -319,34 +322,34 @@ bool ConvertToFailData(const napi_env &env, sptr asyncCallbac return (result[0] != nullptr); } -bool ConvertToSensorData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]) +bool ConvertToSensorData(const napi_env &env, sptr reportDataInfo, napi_value result[2]) { - CHKPF(asyncCallbackInfo); - int32_t sensorTypeId = asyncCallbackInfo->data.sensorData.sensorTypeId; + CHKPF(reportDataInfo); + int32_t sensorTypeId = reportDataInfo->data.sensorData.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) { - return ConvertToBodyData(env, asyncCallbackInfo, result); + if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && reportDataInfo->type == SUBSCRIBE_CALLBACK) { + return ConvertToBodyData(env, reportDataInfo, result); } size_t size = g_sensorAttributeList[sensorTypeId].size(); - uint32_t dataLength = asyncCallbackInfo->data.sensorData.dataLength / sizeof(float); + uint32_t dataLength = reportDataInfo->data.sensorData.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, asyncCallbackInfo->data.sensorData.data[i], &message), + CHKNRF(env, napi_create_double(env, reportDataInfo->data.sensorData.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, asyncCallbackInfo->data.sensorData.timestamp, &message), + CHKNRF(env, napi_create_int64(env, reportDataInfo->data.sensorData.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, asyncCallbackInfo->data.sensorData.sensorAccuracy, &message), + CHKNRF(env, napi_create_int32(env, reportDataInfo->data.sensorData.sensorAccuracy, &message), "napi_create_int32"); CHKNRF(env, napi_set_named_property(env, result[1], "accuracy", message), "napi_set_named_property"); return true; @@ -358,13 +361,13 @@ bool ConvertToGeomagneticData(const napi_env &env, sptr async return getJsonObject(env, asyncCallbackInfo, result[1]); } -bool ConvertToBodyData(const napi_env &env, sptr asyncCallbackInfo, napi_value result[2]) +bool ConvertToBodyData(const napi_env &env, sptr reportDataInfo, napi_value result[2]) { CALL_LOG_ENTER; - CHKPF(asyncCallbackInfo); + CHKPF(reportDataInfo); CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object"); napi_value status = nullptr; - CHKNRF(env, napi_get_boolean(env, asyncCallbackInfo->data.sensorData.data[0], &status), + CHKNRF(env, napi_get_boolean(env, reportDataInfo->data.sensorData.data[0], &status), "napi_get_boolean"); CHKNRF(env, napi_set_named_property(env, result[1], "value", status), "napi_set_named_property"); return true; @@ -433,13 +436,13 @@ bool CreateNapiArray(const napi_env &env, float data[], int32_t dataLength, napi return true; } -void ReleaseCallback(sptr asyncCallbackInfo) +void ReleaseCallback(sptr reportDataInfo) { - CHKPV(asyncCallbackInfo); - if (asyncCallbackInfo->type == ONCE_CALLBACK) { - napi_env env = asyncCallbackInfo->env; + CHKPV(reportDataInfo); + if (reportDataInfo->type == ONCE_CALLBACK) { + napi_env env = reportDataInfo->env; CHKPV(env); - napi_ref callback = asyncCallbackInfo->callback[0]; + napi_ref callback = reportDataInfo->callback[0]; if (callback != nullptr) { napi_delete_reference(env, callback); } @@ -500,75 +503,61 @@ void EmitAsyncCallbackWork(sptr asyncCallbackInfo) } } -void DeleteWork(uv_work_t *work) -{ - CHKPV(work); - delete work; - work = nullptr; -} - -void EmitUvEventLoop(sptr asyncCallbackInfo) +void EmitUvEventLoop(sptr reportDataInfo) { - CHKPV(asyncCallbackInfo); - uv_loop_s *loop(nullptr); - CHKCV((napi_get_uv_event_loop(asyncCallbackInfo->env, &loop) == napi_ok), "napi_get_uv_event_loop fail"); - CHKPV(loop); - uv_work_t *work = new(std::nothrow) uv_work_t; - CHKPV(work); - asyncCallbackInfo->IncStrongRef(nullptr); - work->data = asyncCallbackInfo.GetRefPtr(); - int32_t ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) { }, [] (uv_work_t *work, int status) { - CHKPV(work); - sptr asyncCallbackInfo(static_cast(work->data)); - DeleteWork(work); + CHKPV(reportDataInfo); + reportDataInfo->IncStrongRef(nullptr); + auto event = reportDataInfo.GetRefPtr(); + auto task = [event]() { + sptr reportDataInfo(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 + * After the asynchronous task is created, the reportDataInfo reference count is reduced + * to 0 destruction, so you need to add 1 to the reportDataInfo 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); + reportDataInfo->DecStrongRef(nullptr); napi_handle_scope scope = nullptr; - napi_open_handle_scope(asyncCallbackInfo->env, &scope); + napi_open_handle_scope(reportDataInfo->env, &scope); if (scope == nullptr) { SEN_HILOGE("napi_handle_scope is nullptr"); - ReleaseCallback(asyncCallbackInfo); + ReleaseCallback(reportDataInfo); return; } - napi_env env = asyncCallbackInfo->env; + napi_env env = reportDataInfo->env; napi_value callback = nullptr; - if (napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) != napi_ok) { + if (napi_get_reference_value(env, reportDataInfo->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); + ReleaseCallback(reportDataInfo); + napi_close_handle_scope(reportDataInfo->env, scope); return; } napi_value callResult = nullptr; napi_value result[2] = {0}; - if (!(g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end())) { - SEN_HILOGE("asyncCallbackInfo type is invalid"); - napi_throw_error(env, nullptr, "asyncCallbackInfo type is invalid"); - ReleaseCallback(asyncCallbackInfo); - napi_close_handle_scope(asyncCallbackInfo->env, scope); + if (!(g_sensordatafuncList.find(reportDataInfo->type) != g_sensordatafuncList.end())) { + SEN_HILOGE("reportDataInfo type is invalid"); + napi_throw_error(env, nullptr, "reportDataInfo type is invalid"); + ReleaseCallback(reportDataInfo); + napi_close_handle_scope(reportDataInfo->env, scope); return; } - g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result); + g_sensordatafuncList[reportDataInfo->type](env, reportDataInfo, result); 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); + ReleaseCallback(reportDataInfo); + napi_close_handle_scope(reportDataInfo->env, scope); return; } - ReleaseCallback(asyncCallbackInfo); - napi_close_handle_scope(asyncCallbackInfo->env, scope); - }, uv_qos_default); - if (ret != 0) { - SEN_HILOGE("uv_queue_work_with_qos fail"); - asyncCallbackInfo->DecStrongRef(nullptr); - DeleteWork(work); + ReleaseCallback(reportDataInfo); + napi_close_handle_scope(reportDataInfo->env, scope); + }; + auto ret = napi_send_event(reportDataInfo->env, task, napi_eprio_immediate); + if (ret != napi_ok) { + SEN_HILOGE("Failed to SendEvent, ret:%{public}d", ret); + reportDataInfo->DecStrongRef(nullptr); } }