/* * Copyright (c) 2021-2024 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 "module_template.h" #include #include #include #include #include #include #include "event_manager.h" #include "netstack_log.h" namespace OHOS::NetStack::ModuleTemplate { static constexpr const int EVENT_PARAM_NUM = 2; static constexpr const char *INTERFACE_LOCAL_SOCKET = "LocalSocket"; static constexpr const char *INTERFACE_TLS_SOCKET = "TLSSocket"; static constexpr const char *INTERFACE_WEB_SOCKET = "WebSocket"; static constexpr const char *INTERFACE_HTTP_REQUEST = "OHOS_NET_HTTP_HttpRequest"; napi_value OnManagerWrapper(napi_env env, napi_callback_info info, const std::initializer_list &events, bool asyncCallback) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string || NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } EventManagerWrapper *wrapper = nullptr; auto napiRet = napi_unwrap(env, thisVal, reinterpret_cast(&wrapper)); if (napiRet != napi_ok) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (wrapper == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } auto manager = wrapper->sharedManager; if (manager == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (manager != nullptr) { manager->AddListener(env, event, params[1], false, asyncCallback); } return NapiUtils::GetUndefined(env); } napi_value OnceManagerWrapper(napi_env env, napi_callback_info info, const std::initializer_list &events, bool asyncCallback) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string || NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } EventManagerWrapper *wrapper = nullptr; auto napiRet = napi_unwrap(env, thisVal, reinterpret_cast(&wrapper)); if (napiRet != napi_ok) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (wrapper == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } auto manager = wrapper->sharedManager; if (manager != nullptr) { manager->AddListener(env, event, params[1], true, asyncCallback); } return NapiUtils::GetUndefined(env); } napi_value OffManagerWrapper(napi_env env, napi_callback_info info, const std::initializer_list &events) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if ((paramsCount != 1 && paramsCount != EVENT_PARAM_NUM) || NapiUtils::GetValueType(env, params[0]) != napi_string) { NETSTACK_LOGE("on off once interface para: [string, function?]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } if (paramsCount == EVENT_PARAM_NUM && NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } EventManagerWrapper *wrapper = nullptr; auto napiRet = napi_unwrap(env, thisVal, reinterpret_cast(&wrapper)); if (napiRet != napi_ok) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (wrapper == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } auto manager = wrapper->sharedManager; if (manager == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (manager != nullptr) { if (paramsCount == EVENT_PARAM_NUM) { manager->DeleteListener(event, params[1]); } else { manager->DeleteListener(event); } } return NapiUtils::GetUndefined(env); } napi_value OnSharedManager(napi_env env, napi_callback_info info, const std::initializer_list &events, bool asyncCallback) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string || NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } std::shared_ptr *sharedManager = nullptr; auto napiRet = napi_unwrap(env, thisVal, reinterpret_cast(&sharedManager)); if (napiRet != napi_ok) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (sharedManager == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } auto manager = *sharedManager; if (manager == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (manager != nullptr) { manager->AddListener(env, event, params[1], false, asyncCallback); } return NapiUtils::GetUndefined(env); } napi_value OnceSharedManager(napi_env env, napi_callback_info info, const std::initializer_list &events, bool asyncCallback) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string || NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } std::shared_ptr *sharedManager = nullptr; auto napiRet = napi_unwrap(env, thisVal, reinterpret_cast(&sharedManager)); if (napiRet != napi_ok) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (sharedManager == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } auto manager = *sharedManager; if (manager != nullptr) { manager->AddListener(env, event, params[1], true, asyncCallback); } return NapiUtils::GetUndefined(env); } napi_value OffSharedManager(napi_env env, napi_callback_info info, const std::initializer_list &events) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if ((paramsCount != 1 && paramsCount != EVENT_PARAM_NUM) || NapiUtils::GetValueType(env, params[0]) != napi_string) { NETSTACK_LOGE("on off once interface para: [string, function?]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } if (paramsCount == EVENT_PARAM_NUM && NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } std::shared_ptr *sharedManager = nullptr; auto napiRet = napi_unwrap(env, thisVal, reinterpret_cast(&sharedManager)); if (napiRet != napi_ok) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (sharedManager == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } auto manager = *sharedManager; if (manager == nullptr) { NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet); return NapiUtils::GetUndefined(env); } if (manager != nullptr) { if (paramsCount == EVENT_PARAM_NUM) { manager->DeleteListener(event, params[1]); } else { manager->DeleteListener(event); } } return NapiUtils::GetUndefined(env); } napi_value On(napi_env env, napi_callback_info info, const std::initializer_list &events, bool asyncCallback) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string || NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } EventManager *manager = nullptr; napi_unwrap(env, thisVal, reinterpret_cast(&manager)); if (manager != nullptr) { manager->AddListener(env, event, params[1], false, asyncCallback); } return NapiUtils::GetUndefined(env); } napi_value Once(napi_env env, napi_callback_info info, const std::initializer_list &events, bool asyncCallback) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string || NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } EventManager *manager = nullptr; napi_unwrap(env, thisVal, reinterpret_cast(&manager)); if (manager != nullptr) { manager->AddListener(env, event, params[1], true, asyncCallback); } return NapiUtils::GetUndefined(env); } napi_value Off(napi_env env, napi_callback_info info, const std::initializer_list &events) { napi_value thisVal = nullptr; size_t paramsCount = MAX_PARAM_NUM; napi_value params[MAX_PARAM_NUM] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr)); if ((paramsCount != 1 && paramsCount != EVENT_PARAM_NUM) || NapiUtils::GetValueType(env, params[0]) != napi_string) { NETSTACK_LOGE("on off once interface para: [string, function?]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } if (paramsCount == EVENT_PARAM_NUM && NapiUtils::GetValueType(env, params[1]) != napi_function) { NETSTACK_LOGE("on off once interface para: [string, function]"); napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG); return NapiUtils::GetUndefined(env); } std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]); if (std::find(events.begin(), events.end(), event) == events.end()) { return NapiUtils::GetUndefined(env); } EventManager *manager = nullptr; napi_unwrap(env, thisVal, reinterpret_cast(&manager)); if (manager != nullptr) { if (paramsCount == EVENT_PARAM_NUM) { manager->DeleteListener(event, params[1]); } else { manager->DeleteListener(event); } } return NapiUtils::GetUndefined(env); } void DefineClass(napi_env env, napi_value exports, const std::initializer_list &properties, const std::string &className) { auto constructor = [](napi_env env, napi_callback_info info) -> napi_value { napi_value thisVal = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr)); return thisVal; }; napi_value jsConstructor = nullptr; napi_property_descriptor descriptors[properties.size()]; std::copy(properties.begin(), properties.end(), descriptors); NAPI_CALL_RETURN_VOID(env, napi_define_class(env, className.c_str(), NAPI_AUTO_LENGTH, constructor, nullptr, properties.size(), descriptors, &jsConstructor)); (void)exports; auto global = NapiUtils::GetGlobal(env); NapiUtils::SetNamedProperty(env, global, className, jsConstructor); } napi_value NewInstanceWithManagerWrapper(napi_env env, napi_callback_info info, const std::string &className, Finalizer finalizer) { NETSTACK_LOGD("create new instance for %{public}s", className.c_str()); napi_value thisVal = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr)); auto global = NapiUtils::GetGlobal(env); napi_value jsConstructor = NapiUtils::GetNamedProperty(env, global, className); if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) { return nullptr; } napi_value result = nullptr; NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result)); auto wrapper = new EventManagerWrapper; auto manager = std::make_shared(); wrapper->sharedManager = manager; if (className == INTERFACE_HTTP_REQUEST || className == INTERFACE_LOCAL_SOCKET || className == INTERFACE_TLS_SOCKET || className == INTERFACE_WEB_SOCKET) { NETSTACK_LOGD("create reference for %{public}s", className.c_str()); manager->CreateEventReference(env, thisVal); } napi_wrap(env, result, reinterpret_cast(wrapper), finalizer, nullptr, nullptr); return result; } napi_value NewInstanceWithSharedManager(napi_env env, napi_callback_info info, const std::string &className, Finalizer finalizer) { NETSTACK_LOGD("create new instance for %{public}s", className.c_str()); napi_value thisVal = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr)); auto global = NapiUtils::GetGlobal(env); napi_value jsConstructor = NapiUtils::GetNamedProperty(env, global, className); if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) { return nullptr; } napi_value result = nullptr; NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result)); auto sharedManager = new (std::nothrow) std::shared_ptr(); if (sharedManager == nullptr) { return result; } auto manager = std::make_shared(); *sharedManager = manager; if (className == INTERFACE_HTTP_REQUEST || className == INTERFACE_LOCAL_SOCKET || className == INTERFACE_TLS_SOCKET || className == INTERFACE_WEB_SOCKET) { NETSTACK_LOGD("create reference for %{public}s", className.c_str()); manager->CreateEventReference(env, thisVal); } napi_wrap(env, result, reinterpret_cast(sharedManager), finalizer, nullptr, nullptr); return result; } napi_value NewInstance(napi_env env, napi_callback_info info, const std::string &className, Finalizer finalizer) { NETSTACK_LOGD("create new instance for %{public}s", className.c_str()); napi_value thisVal = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr)); auto global = NapiUtils::GetGlobal(env); napi_value jsConstructor = NapiUtils::GetNamedProperty(env, global, className); if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) { return nullptr; } napi_value result = nullptr; NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result)); auto manager = new EventManager(); EventManager::SetValid(manager); if (className == INTERFACE_HTTP_REQUEST || className == INTERFACE_LOCAL_SOCKET || className == INTERFACE_TLS_SOCKET || className == INTERFACE_WEB_SOCKET) { NETSTACK_LOGD("create reference for %{public}s", className.c_str()); manager->CreateEventReference(env, thisVal); } napi_wrap(env, result, reinterpret_cast(manager), finalizer, nullptr, nullptr); return result; } napi_value NewInstanceNoManager(napi_env env, napi_callback_info info, const std::string &name, Finalizer finalizer) { napi_value thisVal = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr)); (void)thisVal; auto global = NapiUtils::GetGlobal(env); napi_value jsConstructor = NapiUtils::GetNamedProperty(env, global, name); if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) { return nullptr; } napi_value result = nullptr; NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result)); return result; } } // namespace OHOS::NetStack::ModuleTemplate