From 8d437f809710b8314f793ccce1b735a96dfc0f03 Mon Sep 17 00:00:00 2001 From: hellohyh001 Date: Mon, 28 Mar 2022 19:48:22 +0800 Subject: [PATCH 1/3] Add vibrator system api Signed-off-by: hellohyh001 --- interfaces/plugin/BUILD.gn | 1 + .../vibrator/include/vibrator_napi_utils.h | 61 ++-- .../plugin/vibrator/src/vibrator_js.cpp | 273 ++++++++++-------- .../vibrator/src/vibrator_napi_utils.cpp | 245 +++++++++++----- .../test/unittest/ExampleJsunit.test.js | 94 ++++++ 5 files changed, 457 insertions(+), 217 deletions(-) mode change 100755 => 100644 interfaces/plugin/vibrator/test/unittest/ExampleJsunit.test.js diff --git a/interfaces/plugin/BUILD.gn b/interfaces/plugin/BUILD.gn index 292ebf0..565142f 100644 --- a/interfaces/plugin/BUILD.gn +++ b/interfaces/plugin/BUILD.gn @@ -21,6 +21,7 @@ ohos_shared_library("vibrator") { "./include", "./vibrator/include", "//utils/native/base/include", + "//base/sensors/miscdevice/utils/include", ] defines = [ "APP_LOG_TAG = \"vibratorJs\"", diff --git a/interfaces/plugin/vibrator/include/vibrator_napi_utils.h b/interfaces/plugin/vibrator/include/vibrator_napi_utils.h index 7d88935..102e446 100644 --- a/interfaces/plugin/vibrator/include/vibrator_napi_utils.h +++ b/interfaces/plugin/vibrator/include/vibrator_napi_utils.h @@ -12,35 +12,54 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef VIBRATOR_NAPI_UTILS_H +#define VIBRATOR_NAPI_UTILS_H #include "napi/native_api.h" #include "napi/native_node_api.h" #include #include +#include "refbase.h" +namespace OHOS { +namespace Sensors { using std::string; -const int32_t CALLBACK_RESULT_LENGTH = 2; -struct AsyncCallbackError { - int32_t code; - string message; - string name; - string stack; -}; +constexpr int32_t CALLBACK_NUM = 3; +constexpr uint32_t TYPE_SYSTEM_VIBRATE = 1; +constexpr uint32_t STRING_LENGTH_MAX = 64; + +class AsyncCallbackInfo : public RefBase { +public: + struct AsyncCallbackError { + int32_t code {0}; + string message; + string name; + string stack; + }; -struct AsyncCallbackInfo { - napi_env env; - napi_async_work asyncWork; - napi_deferred deferred; - napi_ref callback[1] = { 0 }; + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback[CALLBACK_NUM] = {0}; AsyncCallbackError error; + uint32_t callbackType = 0; + sptr callbackInfo = nullptr; + AsyncCallbackInfo(napi_env env) : env(env) {} + ~AsyncCallbackInfo(); +private: }; -bool IsMatchType(napi_value value, napi_valuetype type, napi_env env); -napi_value GetNapiInt32(int32_t number, napi_env env); -int32_t GetCppInt32(napi_value value, napi_env env); -void EmitAsyncCallbackWork(AsyncCallbackInfo *async_callback_info); -int64_t GetCppInt64(napi_value value, napi_env env); -napi_value NapiGetNamedProperty(napi_value jsonObject, string name, napi_env env); -void EmitPromiseWork(AsyncCallbackInfo *asyncCallbackInfo); -napi_value GreateBusinessError(napi_env env, int32_t errCode, string errMessage, - string errName, string errStack); \ No newline at end of file +bool IsMatchType(const napi_env &env, const napi_value &value, const napi_valuetype &type); +bool GetNapiInt32(const napi_env &env, const int32_t value, napi_value &result); +bool GetInt32Value(const napi_env &env, const napi_value &value, int32_t &result); +bool GetUint32Value(const napi_env &env, const napi_value &value, uint32_t &result); +bool GetStringValue(const napi_env &env, const napi_value &value, string &result); +bool GetNapiParam(const napi_env &env, const napi_callback_info &info, size_t &argc, napi_value &argv); +void EmitAsyncCallbackWork(sptr async_callback_info); +bool GetInt64Value(const napi_env &env, const napi_value &value, int32_t &result); +void EmitPromiseWork(sptr asyncCallbackInfo); +napi_value GreateCallbackError(const napi_env &env, const int32_t errCode, + const string errMessage, const string errName, const string errStack); +} // namespace Sensors +} // namespace OHOS +#endif // VIBRATOR_NAPI_UTILS_H \ No newline at end of file diff --git a/interfaces/plugin/vibrator/src/vibrator_js.cpp b/interfaces/plugin/vibrator/src/vibrator_js.cpp index faebb5a..123d60b 100644 --- a/interfaces/plugin/vibrator/src/vibrator_js.cpp +++ b/interfaces/plugin/vibrator/src/vibrator_js.cpp @@ -19,136 +19,171 @@ #include #include "hilog/log.h" +#include "miscdevice_log.h" #include "napi/native_api.h" #include "napi/native_node_api.h" #include "vibrator_agent.h" #include "vibrator_napi_utils.h" +namespace OHOS { +namespace Sensors { using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002757, "VibratorJsAPI" }; +static constexpr uint32_t VIBRATE_SHORT_DURATION = 35; +static constexpr uint32_t VIBRATE_LONG_DURATION = 1000; - -static napi_value Vibrate(napi_env env, napi_callback_info info) +static napi_value VibrateTime(napi_env env, napi_value args[], size_t argc) { - size_t argc = 2; - napi_value args[CALLBACK_RESULT_LENGTH]; - napi_value thisArg; - napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr); - if (argc < 1 || argc > CALLBACK_RESULT_LENGTH) { - HiLog::Error(LABEL, "%{public}s the number of input parameters does not match", __func__); + NAPI_ASSERT(env, (argc == 1 || argc == 2), "Wrong argument number"); + int32_t duration = 0; + NAPI_ASSERT(env, GetInt32Value(env, args[0], duration), "Get int number fail"); + sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env); + CHKPP(asyncCallbackInfo); + if (duration < 0) { + MISC_HILOGE("Vibrate duration is invalid, duration: %{public}d", duration); + asyncCallbackInfo->error.code = ERROR; + asyncCallbackInfo->error.message = "Vibrate duration is invalid"; + } else { + asyncCallbackInfo->error.code = StartVibratorOnce(static_cast(duration)); + } + + if (argc == 2) { + NAPI_ASSERT(env, IsMatchType(env, args[1], napi_function), "Wrong argument type. function expected"); + NAPI_CALL(env, napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0])); + EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } - if (!IsMatchType(args[0], napi_number, env) && !IsMatchType(args[0], napi_string, env)) { - HiLog::Error(LABEL, "%{public}s input parameter type does not match number or string", __func__); + + napi_deferred deferred = nullptr; + napi_value promise = nullptr; + NAPI_CALL(env, napi_create_promise(env, &deferred, &promise)); + asyncCallbackInfo->deferred = deferred; + EmitPromiseWork(asyncCallbackInfo); + return promise; +} + +static napi_value VibrateEffectId(napi_env env, napi_value args[], size_t argc) +{ + NAPI_ASSERT(env, (argc == 1 || argc == 2), "Wrong argument number"); + string effectId; + NAPI_ASSERT(env, GetStringValue(env, args[0], effectId), "Wrong argument type. String or function expected"); + sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env); + CHKPP(asyncCallbackInfo); + asyncCallbackInfo->error.code = StartVibrator(effectId.c_str()); + + if (argc == 2) { + NAPI_ASSERT(env, IsMatchType(env, args[1], napi_function), "Wrong argument type. function expected"); + NAPI_CALL(env, napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0])); + EmitAsyncCallbackWork(asyncCallbackInfo); return nullptr; } - AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { - .env = env, - .asyncWork = nullptr, - .deferred = nullptr, - }; - if (IsMatchType(args[0], napi_number, env)) { - int32_t duration = GetCppInt32(args[0], env); - asyncCallbackInfo->error.code = StartVibratorOnce(duration); - } else if (IsMatchType(args[0], napi_string, env)) { - size_t bufLength = 0; - napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &bufLength); - if (status != napi_ok) { - HiLog::Error(LABEL, "%{public}s input parameter is invalid", __func__); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; - return nullptr; - } - char *vibratorEffect = static_cast(malloc((bufLength + 1) * sizeof(char))); - if (vibratorEffect == nullptr) { - HiLog::Error(LABEL, "%{public}s malloc fail", __func__); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; - return nullptr; - } - status = napi_get_value_string_utf8(env, args[0], vibratorEffect, bufLength + 1, &bufLength); - asyncCallbackInfo->error.code = StartVibrator(vibratorEffect); - if (vibratorEffect != nullptr) { - free(vibratorEffect); - } + + napi_deferred deferred = nullptr; + napi_value promise = nullptr; + NAPI_CALL(env, napi_create_promise(env, &deferred, &promise)); + asyncCallbackInfo->deferred = deferred; + EmitPromiseWork(asyncCallbackInfo); + return promise; +} + +static bool GetCallbackInfo(const napi_env &env, napi_value args[], + sptr &asyncCallbackInfo, string &mode) +{ + CHKPF(asyncCallbackInfo); + CHKPF(args); + napi_value value = nullptr; + NAPI_CALL_BASE(env, napi_get_named_property(env, args[0], "success", &value), false); + NAPI_CALL_BASE(env, napi_create_reference(env, value, 1, &asyncCallbackInfo->callback[0]), false); + + bool result = false; + NAPI_CALL_BASE(env, napi_has_named_property(env, args[0], "mode", &result), false); + if (result) { + NAPI_CALL_BASE(env, napi_get_named_property(env, args[0], "mode", &value), false); + NAPI_ASSERT_BASE(env, GetStringValue(env, value, mode), "Wrong argument type. String or function expected", false); + NAPI_ASSERT_BASE(env, (mode == "long" || mode == "short"), + "Wrong argument type. Invalid mode value", false); } - if (argc == CALLBACK_RESULT_LENGTH) { - if (!IsMatchType(args[1], napi_function, env)) { - HiLog::Error(LABEL, "%{public}s input parameter type does not match function", __func__); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; - return nullptr; - } - napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); - EmitAsyncCallbackWork(asyncCallbackInfo); - } else if (argc == 1) { - napi_deferred deferred; - napi_value promise; - napi_create_promise(env, &deferred, &promise); - asyncCallbackInfo->deferred = deferred; - EmitPromiseWork(asyncCallbackInfo); - return promise; + NAPI_CALL_BASE(env, napi_has_named_property(env, args[0], "fail", &result), false); + if (result) { + NAPI_CALL_BASE(env, napi_get_named_property(env, args[0], "fail", &value), false); + NAPI_CALL_BASE(env, napi_create_reference(env, value, 1, &asyncCallbackInfo->callback[1]), false); } - return nullptr; + NAPI_CALL_BASE(env, napi_has_named_property(env, args[0], "complete", &result), false); + if (result) { + NAPI_CALL_BASE(env, napi_get_named_property(env, args[0], "complete", &value), false); + NAPI_CALL_BASE(env, napi_create_reference(env, value, 1, &asyncCallbackInfo->callback[2]), false); + } + return true; } -static napi_value Stop(napi_env env, napi_callback_info info) +static napi_value VibrateMode(napi_env env, napi_value args[], size_t argc) { - size_t argc = 2; - napi_value args[2]; - napi_value thisArg; - napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr); - if (argc < 1 || argc > CALLBACK_RESULT_LENGTH) { - HiLog::Error(LABEL, "%{public}s the number of input parameters does not match", __func__); + if (argc == 0) { + NAPI_ASSERT(env, (StartVibratorOnce(VIBRATE_LONG_DURATION) == 0), "Vibrate long mode fail"); return nullptr; } - if (!IsMatchType(args[0], napi_string, env)) { - HiLog::Error(LABEL, "%{public}s input parameter type does not match string", __func__); - return nullptr; + NAPI_ASSERT(env, (argc == 1), "Param number is invalid"); + sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env); + CHKPP(asyncCallbackInfo); + asyncCallbackInfo->callbackType = TYPE_SYSTEM_VIBRATE; + string mode = "long"; + NAPI_ASSERT(env, GetCallbackInfo(env, args, asyncCallbackInfo, mode), "Get callback info fail"); + uint32_t duration = ((mode == "long") ? VIBRATE_LONG_DURATION : VIBRATE_SHORT_DURATION); + asyncCallbackInfo->error.code = StartVibratorOnce(duration); + if (asyncCallbackInfo->error.code != SUCCESS) { + asyncCallbackInfo->error.message = "Vibrator vibrate fail"; } - AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { - .env = env, - .asyncWork = nullptr, - .deferred = nullptr, - }; - size_t bufLength = 0; - napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &bufLength); - if (status != napi_ok) { - HiLog::Error(LABEL, "%{public}s input parameter is invalid", __func__); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; - return nullptr; + EmitAsyncCallbackWork(asyncCallbackInfo); + return nullptr; +} + +static napi_value Vibrate(napi_env env, napi_callback_info info) +{ + CHKPP(env); + CHKPP(info); + size_t argc = 2; + napi_value args[2] = {}; + napi_value thisArg = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr)); + NAPI_ASSERT(env, (argc <= 2), "Wrong argument number"); + + if (IsMatchType(env, args[0], napi_number)) { + return VibrateTime(env, args, argc); } - char *mode = static_cast(malloc((bufLength + 1) * sizeof(char))); - if (mode == nullptr) { - HiLog::Error(LABEL, "%{public}s malloc fail", __func__); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; - return nullptr; + if (IsMatchType(env, args[0], napi_string)) { + return VibrateEffectId(env, args, argc); } - status = napi_get_value_string_utf8(env, args[0], mode, bufLength + 1, &bufLength); - asyncCallbackInfo->error.code = StopVibrator(mode); - if (mode != nullptr) { - free(mode); + if (IsMatchType(env, args[0], napi_object)) { + return VibrateMode(env, args, argc); } - if (argc == CALLBACK_RESULT_LENGTH) { - if (!IsMatchType(args[1], napi_function, env) || !IsMatchType(args[0], napi_string, env)) { - HiLog::Error(LABEL, "%{public}s input parameter type does not match", __func__); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; - return nullptr; - } - napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); + NAPI_CALL(env, napi_throw_error((env), nullptr, "Wrong argument type")); + return nullptr; +} + +static napi_value Stop(napi_env env, napi_callback_info info) +{ + size_t argc = 2; + napi_value args[2] = {}; + napi_value thisArg = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr)); + NAPI_ASSERT(env, (argc == 1 || argc == 2), "Wrong argument number"); + string mode; + NAPI_ASSERT(env, GetStringValue(env, args[0], mode), "Wrong argument type. String or function expected"); + sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env); + CHKPP(asyncCallbackInfo); + asyncCallbackInfo->error.code = StopVibrator(mode.c_str()); + if (argc == 2) { + NAPI_ASSERT(env, IsMatchType(env, args[1], napi_function), "Wrong argument type. function expected"); + NAPI_CALL(env, napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0])); EmitAsyncCallbackWork(asyncCallbackInfo); - } else if (argc == 1) { - napi_deferred deferred; - napi_value promise; - napi_create_promise(env, &deferred, &promise); - asyncCallbackInfo->deferred = deferred; - EmitPromiseWork(asyncCallbackInfo); - return promise; + return nullptr; } - return nullptr; + napi_deferred deferred = nullptr; + napi_value promise = nullptr; + NAPI_CALL(env, napi_create_promise(env, &deferred, &promise)); + asyncCallbackInfo->deferred = deferred; + EmitPromiseWork(asyncCallbackInfo); + return promise; } static napi_value EnumClassConstructor(const napi_env env, const napi_callback_info info) @@ -157,10 +192,7 @@ static napi_value EnumClassConstructor(const napi_env env, const napi_callback_i napi_value args[1] = {0}; napi_value res = nullptr; void *data = nullptr; - napi_status status = napi_get_cb_info(env, info, &argc, args, &res, &data); - if (status != napi_ok) { - return nullptr; - } + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &res, &data)); return res; } @@ -168,17 +200,17 @@ static napi_value CreateEnumStopMode(const napi_env env, napi_value exports) { napi_value timeMode = nullptr; napi_value presetMode = nullptr; - napi_create_string_utf8(env, "time", NAPI_AUTO_LENGTH, &timeMode); - napi_create_string_utf8(env, "preset", NAPI_AUTO_LENGTH, &presetMode); + NAPI_CALL(env, napi_create_string_utf8(env, "time", NAPI_AUTO_LENGTH, &timeMode)); + NAPI_CALL(env, napi_create_string_utf8(env, "preset", NAPI_AUTO_LENGTH, &presetMode)); napi_property_descriptor desc[] = { DECLARE_NAPI_STATIC_PROPERTY("VIBRATOR_STOP_MODE_TIME", timeMode), DECLARE_NAPI_STATIC_PROPERTY("VIBRATOR_STOP_MODE_PRESET", presetMode), }; napi_value result = nullptr; - napi_define_class(env, "VibratorStopMode", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr, - sizeof(desc) / sizeof(*desc), desc, &result); - napi_set_named_property(env, exports, "VibratorStopMode", result); + NAPI_CALL(env, napi_define_class(env, "VibratorStopMode", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr, + sizeof(desc) / sizeof(*desc), desc, &result)); + NAPI_CALL(env, napi_set_named_property(env, exports, "VibratorStopMode", result)); return exports; } @@ -191,14 +223,12 @@ static napi_value CreateEnumEffectId(const napi_env env, const napi_value export DECLARE_NAPI_STATIC_PROPERTY("EFFECT_CLOCK_TIMER", clockTime), }; napi_value result = nullptr; - napi_define_class(env, "EffectId", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr, - sizeof(desc) / sizeof(*desc), desc, &result); - napi_set_named_property(env, exports, "EffectId", result); + NAPI_CALL(env, napi_define_class(env, "EffectId", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr, + sizeof(desc) / sizeof(*desc), desc, &result)); + NAPI_CALL(env, napi_set_named_property(env, exports, "EffectId", result)); return exports; } -EXTERN_C_START - static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { @@ -206,11 +236,10 @@ static napi_value Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("stop", Stop) }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc)); - CreateEnumStopMode(env, exports); - CreateEnumEffectId(env, exports); + NAPI_ASSERT_BASE(env, CreateEnumStopMode(env, exports) != nullptr, "Create enum stop mode fail", exports); + NAPI_ASSERT_BASE(env, CreateEnumEffectId(env, exports) != nullptr, "Create enum effect id fail", exports); return exports; } -EXTERN_C_END static napi_module _module = { .nm_version = 1, @@ -226,3 +255,5 @@ extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&_module); } +} // namespace Sensors +} // namespace OHOS diff --git a/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp b/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp index addb216..dc9b277 100644 --- a/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp +++ b/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp @@ -16,128 +16,223 @@ #include "vibrator_napi_utils.h" #include #include "hilog/log.h" +#include "miscdevice_log.h" - +namespace OHOS { +namespace Sensors { using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "VibratorJsAPI"}; -bool IsMatchType(napi_value value, napi_valuetype type, napi_env env) +AsyncCallbackInfo::~AsyncCallbackInfo() +{ + CALL_LOG_ENTER; + if (asyncWork != nullptr) { + HiLog::Debug(LABEL, "%{public}s delete work", __func__); + napi_delete_async_work(env, asyncWork); + } + for (size_t i = 0; i < CALLBACK_NUM; ++i) { + if (callback[i] != nullptr) { + HiLog::Debug(LABEL, "%{public}s delete reference, i: %{public}d", __func__, i); + napi_delete_reference(env, callback[i]); + } + } +} + +bool IsMatchType(const napi_env &env, const napi_value &value, const napi_valuetype &type) { - napi_valuetype paramType; - napi_typeof(env, value, ¶mType); + napi_valuetype paramType = napi_undefined; + NAPI_CALL_BASE(env, napi_typeof(env, value, ¶mType), false); if (paramType != type) { - HiLog::Error(LABEL, "%{public}s failed!", __func__); + HiLog::Error(LABEL, "%{public}s Type mismatch", __func__); return false; } return true; } -napi_value GetNapiInt32(int32_t number, napi_env env) +bool GetNapiInt32(const napi_env &env, const int32_t value, napi_value &result) +{ + CALL_LOG_ENTER; + NAPI_CALL_BASE(env, napi_create_int32(env, value, &result), false); + return true; +} + +bool GetInt32Value(const napi_env &env, const napi_value &value, int32_t &result) { - napi_value value; - napi_create_int32(env, number, &value); - return value; + CALL_LOG_ENTER; + napi_valuetype valuetype = napi_undefined; + NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false); + NAPI_ASSERT_BASE(env, valuetype == napi_number, + "Wrong argument type. Number or function expected", false); + NAPI_CALL_BASE(env, napi_get_value_int32(env, value, &result), false); + return true; } -napi_value NapiGetNamedProperty(napi_value jsonObject, string name, napi_env env) +bool GetUint32Value(const napi_env &env, const napi_value &value, uint32_t &result) { - napi_value value; - napi_get_named_property(env, jsonObject, name.c_str(), &value); - return value; + CALL_LOG_ENTER; + napi_valuetype valuetype = napi_undefined; + NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false); + NAPI_ASSERT_BASE(env, valuetype == napi_number, + "Wrong argument type. Number or function expected", false); + NAPI_CALL_BASE(env, napi_get_value_uint32(env, value, &result), false); + return true; } -int32_t GetCppInt32(napi_value value, napi_env env) +bool GetInt64Value(const napi_env &env, const napi_value &value, int64_t &result) { - int32_t number; - napi_get_value_int32(env, value, &number); - return number; + CALL_LOG_ENTER; + napi_valuetype valuetype = napi_undefined; + NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false); + NAPI_ASSERT_BASE(env, valuetype == napi_number, + "Wrong argument type. Number or function expected", false); + NAPI_CALL_BASE(env, napi_get_value_int64(env, value, &result), false); + return true; } -int64_t GetCppInt64(napi_value value, napi_env env) +bool GetStringValue(const napi_env &env, const napi_value &value, string &result) { - int64_t number; - napi_get_value_int64(env, value, &number); - return number; + CALL_LOG_ENTER; + napi_valuetype valuetype = napi_undefined; + NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false); + NAPI_ASSERT_BASE(env, (valuetype == napi_string), "Wrong argument type. String or function expected", false); + size_t bufLength = 0; + NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength), false); + char str[STRING_LENGTH_MAX] = {0}; + size_t strLen = 0; + NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, str, bufLength, &strLen), false); + result = str; + return true; } -napi_value GreateBusinessError(napi_env env, int32_t errCode, string errMessage, string errName, string errStack) +napi_value GreateCallbackError(const napi_env &env, const int32_t errCode, + const string errMessage, const string errName, const string errStack) { - napi_value result = nullptr; napi_value code = nullptr; + NAPI_CALL(env, napi_create_int32(env, errCode, &code)); napi_value message = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, errMessage.data(), NAPI_AUTO_LENGTH, &message)); napi_value name = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, errName.data(), NAPI_AUTO_LENGTH, &name)); napi_value stack = nullptr; - napi_create_int32(env, errCode, &code); - napi_create_string_utf8(env, errMessage.data(), NAPI_AUTO_LENGTH, &message); - napi_create_string_utf8(env, errName.data(), NAPI_AUTO_LENGTH, &name); - napi_create_string_utf8(env, errStack.data(), NAPI_AUTO_LENGTH, &stack); - napi_create_object(env, &result); - napi_set_named_property(env, result, "code", code); - napi_set_named_property(env, result, "message", message); - napi_set_named_property(env, result, "name", name); - napi_set_named_property(env, result, "stack", stack); + NAPI_CALL(env, napi_create_string_utf8(env, errStack.data(), NAPI_AUTO_LENGTH, &stack)); + napi_value result = nullptr; + NAPI_CALL(env, napi_create_object(env, &result)); + NAPI_CALL(env, napi_set_named_property(env, result, "code", code)); + NAPI_CALL(env, napi_set_named_property(env, result, "message", message)); + NAPI_CALL(env, napi_set_named_property(env, result, "name", name)); + NAPI_CALL(env, napi_set_named_property(env, result, "stack", stack)); return result; } -void EmitAsyncCallbackWork(AsyncCallbackInfo *asyncCallbackInfo) +void emitSystemCallback(const napi_env &env, sptr asyncCallbackInfo ) { - HiLog::Debug(LABEL, "%s begin", __func__); - if (asyncCallbackInfo == nullptr) { - HiLog::Error(LABEL, "%s asyncCallbackInfo is nullptr!", __func__); + CHKPV(asyncCallbackInfo); + if (asyncCallbackInfo->error.code == SUCCESS) { + CHKPV(asyncCallbackInfo->callback[0]); + napi_value callback = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback)); + napi_value result = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result)); + napi_value callResult = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback, 1, &result, &callResult)); return; } - napi_value resourceName; - napi_create_string_latin1(asyncCallbackInfo->env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName); - napi_create_async_work( - asyncCallbackInfo->env, nullptr, resourceName, [](napi_env env, void* data) {}, - [](napi_env env, napi_status status, void* data) { - AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data; - napi_value callback; - napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback); + CHKPV(asyncCallbackInfo->callback[1]); + napi_value callback = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback[1], &callback)); + napi_value result[2] = {0}; + NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, asyncCallbackInfo->error.message.data(), + NAPI_AUTO_LENGTH, &result[0])); + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, asyncCallbackInfo->error.code, &result[1])); + napi_value callResult = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback, 1, result, &callResult)); +} + +void EmitAsyncCallbackWork(sptr asyncCallbackInfo) +{ + CALL_LOG_ENTER; + CHKPV(asyncCallbackInfo); + CHKPV(asyncCallbackInfo->env); + napi_env env = asyncCallbackInfo->env; + napi_value resourceName = nullptr; + NAPI_CALL_RETURN_VOID(env, + napi_create_string_latin1(env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName)); + // Make the reference count of asyncCallbackInfo add 1, and the function exits the non-destructor + asyncCallbackInfo->callbackInfo = asyncCallbackInfo; + napi_status status = napi_create_async_work( + env, nullptr, resourceName, [](napi_env env, void* data) {}, + [](napi_env env, napi_status status, void* data) { + CHKPV(data); + sptr asyncCallbackInfo = reinterpret_cast(data)->callbackInfo; + // The reference count of asyncCallbackInfo is subtracted by 1, and the function exits the destructor + asyncCallbackInfo->callbackInfo = nullptr; + if (asyncCallbackInfo->callbackType == TYPE_SYSTEM_VIBRATE) { + emitSystemCallback(env, asyncCallbackInfo); + return; + } + CHKPV(asyncCallbackInfo->callback[0]); + napi_value callback = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback)); napi_value result = nullptr; - napi_value callResult = nullptr; if (asyncCallbackInfo->error.code < 0) { - result = GreateBusinessError(env, asyncCallbackInfo->error.code, asyncCallbackInfo->error.message, + result = GreateCallbackError(env, asyncCallbackInfo->error.code, asyncCallbackInfo->error.message, asyncCallbackInfo->error.name, asyncCallbackInfo->error.stack); + CHKPV(result); } else { - napi_get_undefined(env, &result); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result)); } - napi_call_function(env, nullptr, callback, 1, &result, &callResult); - napi_delete_reference(env, asyncCallbackInfo->callback[0]); - napi_delete_async_work(env, asyncCallbackInfo->asyncWork); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; + napi_value callResult = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback, 1, &result, &callResult)); }, - asyncCallbackInfo, &asyncCallbackInfo->asyncWork); - napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork); - HiLog::Debug(LABEL, "%{public}s end", __func__); + asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork); + if (status != napi_ok + || napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork) != napi_ok) { + MISC_HILOGE("Create async work fail"); + // The reference count of asyncCallbackInfo is subtracted by 1, and the function exits the destructor + asyncCallbackInfo->callbackInfo = nullptr; + } } -void EmitPromiseWork(AsyncCallbackInfo *asyncCallbackInfo) +void EmitPromiseWork(sptr asyncCallbackInfo) { - if (asyncCallbackInfo == nullptr) { - HiLog::Error(LABEL, "%s asyncCallbackInfo is nullptr!", __func__); - return; - } - napi_value resourceName; - napi_create_string_latin1(asyncCallbackInfo->env, "Promise", NAPI_AUTO_LENGTH, &resourceName); - napi_create_async_work( + CALL_LOG_ENTER; + CHKPV(asyncCallbackInfo); + CHKPV(asyncCallbackInfo->env); + napi_env env = asyncCallbackInfo->env; + napi_value resourceName = nullptr; + NAPI_CALL_RETURN_VOID(env, + napi_create_string_latin1(asyncCallbackInfo->env, "Promise", NAPI_AUTO_LENGTH, &resourceName)); + // Make the reference count of asyncCallbackInfo add 1, and the function exits the non-destructor + asyncCallbackInfo->callbackInfo = asyncCallbackInfo; + napi_status status = napi_create_async_work( asyncCallbackInfo->env, nullptr, resourceName, [](napi_env env, void* data) {}, [](napi_env env, napi_status status, void* data) { - AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data; + CHKPV(data); + sptr asyncCallbackInfo = reinterpret_cast(data)->callbackInfo; + // The reference count of asyncCallbackInfo is subtracted by 1, and the function exits the destructor + asyncCallbackInfo->callbackInfo = nullptr; + CHKPV(asyncCallbackInfo->deferred); + if (asyncCallbackInfo->callbackType == TYPE_SYSTEM_VIBRATE) { + emitSystemCallback(env, asyncCallbackInfo); + return; + } napi_value result = nullptr; if (asyncCallbackInfo->error.code == 0) { - napi_get_undefined(env, &result); - napi_resolve_deferred(env, asyncCallbackInfo->deferred, result); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result)); + NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result)); } else { - result = GreateBusinessError(env, asyncCallbackInfo->error.code, asyncCallbackInfo->error.message, + result = GreateCallbackError(env, asyncCallbackInfo->error.code, asyncCallbackInfo->error.message, asyncCallbackInfo->error.name, asyncCallbackInfo->error.stack); - napi_reject_deferred(env, asyncCallbackInfo->deferred, result); + CHKPV(result); + NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result)); } - napi_delete_async_work(env, asyncCallbackInfo->asyncWork); - delete asyncCallbackInfo; - asyncCallbackInfo = nullptr; - }, - (void*)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); - napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork); -} \ No newline at end of file + }, asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork); + if (status != napi_ok + || napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork) != napi_ok) { + MISC_HILOGE("Create async work fail"); + // The reference count of asyncCallbackInfo is subtracted by 1, and the function exits the destructor + asyncCallbackInfo->callbackInfo = nullptr; + } +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/plugin/vibrator/test/unittest/ExampleJsunit.test.js b/interfaces/plugin/vibrator/test/unittest/ExampleJsunit.test.js old mode 100755 new mode 100644 index 0b05cda..7896dab --- a/interfaces/plugin/vibrator/test/unittest/ExampleJsunit.test.js +++ b/interfaces/plugin/vibrator/test/unittest/ExampleJsunit.test.js @@ -13,6 +13,7 @@ * limitations under the License. */ import vibrator from '@ohos.vibrator' +import systemVibrator from '@system.vibrator' import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' @@ -499,4 +500,97 @@ describe("VibratorJsTest", function () { }) done(); }) + + /* + * @tc.name:VibratorJsTest019 + * @tc.desc:verify app info is not null + * @tc.type: FUNC + * @tc.require: Issue Number + */ + it("VibratorJsTest019", 0, async function (done) { + systemVibrator.vibrate({ + mode: 'short', + success: function() { + expect(true).assertTrue(); + console.log('vibrate is successful'); + done(); + }, + fail: function(data, code) { + expect(false).assertTrue(); + console.log('vibrate is failed, data: ' + data + "code: " + code); + done(); + }, + complete: function() { + console.log('vibrate is completed'); + done(); + } + }); + }) + + /* + * @tc.name:VibratorJsTest020 + * @tc.desc:verify app info is not null + * @tc.type: FUNC + * @tc.require: Issue Number + */ + it("VibratorJsTest020", 0, async function (done) { + systemVibrator.vibrate({ + mode: 'long', + success: function() { + expect(true).assertTrue(); + console.log('vibrate is successful'); + done(); + }, + fail: function(data, code) { + expect(false).assertTrue(); + console.log('vibrate is failed, data: ' + data + "code: " + code); + done(); + }, + complete: function() { + console.log('vibrate is completed'); + done(); + } + }); + }) + + /* + * @tc.name:VibratorJsTest021 + * @tc.desc:verify app info is not null + * @tc.type: FUNC + * @tc.require: Issue Number + */ + it("VibratorJsTest021", 0, async function (done) { + systemVibrator.vibrate({ + success: function() { + expect(true).assertTrue(); + console.log('vibrate is successful'); + done(); + }, + fail: function(data, code) { + expect(false).assertTrue(); + console.log('vibrate is failed, data: ' + data + "code: " + code); + done(); + }, + complete: function() { + console.log('vibrate is completed'); + done(); + } + }); + }) + + /* + * @tc.name:VibratorJsTest022 + * @tc.desc:verify app info is not null + * @tc.type: FUNC + * @tc.require: Issue Number + */ + it("VibratorJsTest022", 0, async function (done) { + systemVibrator.vibrate({ + success: function() { + expect(true).assertTrue(); + console.log('vibrate is successful'); + done(); + }, + }); + }) }) -- Gitee From 16d43e6eef036f056abed8cebc7bc5072364476a Mon Sep 17 00:00:00 2001 From: hellohyh001 Date: Mon, 28 Mar 2022 20:03:43 +0800 Subject: [PATCH 2/3] Add vibrator system api Signed-off-by: hellohyh001 --- interfaces/plugin/vibrator/src/vibrator_js.cpp | 3 ++- interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/interfaces/plugin/vibrator/src/vibrator_js.cpp b/interfaces/plugin/vibrator/src/vibrator_js.cpp index 123d60b..65eb12e 100644 --- a/interfaces/plugin/vibrator/src/vibrator_js.cpp +++ b/interfaces/plugin/vibrator/src/vibrator_js.cpp @@ -99,7 +99,8 @@ static bool GetCallbackInfo(const napi_env &env, napi_value args[], NAPI_CALL_BASE(env, napi_has_named_property(env, args[0], "mode", &result), false); if (result) { NAPI_CALL_BASE(env, napi_get_named_property(env, args[0], "mode", &value), false); - NAPI_ASSERT_BASE(env, GetStringValue(env, value, mode), "Wrong argument type. String or function expected", false); + NAPI_ASSERT_BASE(env, GetStringValue(env, value, mode), + "Wrong argument type. String or function expected", false); NAPI_ASSERT_BASE(env, (mode == "long" || mode == "short"), "Wrong argument type. Invalid mode value", false); } diff --git a/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp b/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp index dc9b277..f4887da 100644 --- a/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp +++ b/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp @@ -124,7 +124,7 @@ napi_value GreateCallbackError(const napi_env &env, const int32_t errCode, return result; } -void emitSystemCallback(const napi_env &env, sptr asyncCallbackInfo ) +void emitSystemCallback(const napi_env &env, sptr asyncCallbackInfo) { CHKPV(asyncCallbackInfo); if (asyncCallbackInfo->error.code == SUCCESS) { -- Gitee From ef896f4deb8f8994fb364c97c9bab379fcd1ad37 Mon Sep 17 00:00:00 2001 From: hellohyh001 Date: Mon, 28 Mar 2022 20:30:05 +0800 Subject: [PATCH 3/3] Add vibrator system api Signed-off-by: hellohyh001 --- interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp b/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp index f4887da..2213eab 100644 --- a/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp +++ b/interfaces/plugin/vibrator/src/vibrator_napi_utils.cpp @@ -30,7 +30,7 @@ AsyncCallbackInfo::~AsyncCallbackInfo() HiLog::Debug(LABEL, "%{public}s delete work", __func__); napi_delete_async_work(env, asyncWork); } - for (size_t i = 0; i < CALLBACK_NUM; ++i) { + for (int32_t i = 0; i < CALLBACK_NUM; ++i) { if (callback[i] != nullptr) { HiLog::Debug(LABEL, "%{public}s delete reference, i: %{public}d", __func__, i); napi_delete_reference(env, callback[i]); -- Gitee