1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "module_template.h"
17
18 #include <algorithm>
19 #include <functional>
20 #include <initializer_list>
21 #include <new>
22 #include <string>
23
24 #include "event_manager.h"
25 #include "netstack_log.h"
26 #include "http_module.h"
27
28 namespace OHOS::NetStack::ModuleTemplate {
29 static constexpr const int EVENT_PARAM_NUM = 2;
30
On(napi_env env,napi_callback_info info,const std::initializer_list<std::string> & events,bool asyncCallback)31 napi_value On(napi_env env, napi_callback_info info, const std::initializer_list<std::string> &events,
32 bool asyncCallback)
33 {
34 napi_value thisVal = nullptr;
35 size_t paramsCount = MAX_PARAM_NUM;
36 napi_value params[MAX_PARAM_NUM] = {nullptr};
37 NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr));
38
39 if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string ||
40 NapiUtils::GetValueType(env, params[1]) != napi_function) {
41 NETSTACK_LOGE("on off once interface para: [string, function]");
42 napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG);
43 return NapiUtils::GetUndefined(env);
44 }
45
46 std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
47 if (std::find(events.begin(), events.end(), event) == events.end()) {
48 return NapiUtils::GetUndefined(env);
49 }
50
51 EventManager *manager = nullptr;
52 napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager));
53 if (manager != nullptr) {
54 manager->AddListener(env, event, params[1], false, asyncCallback);
55 }
56
57 return NapiUtils::GetUndefined(env);
58 }
59
Once(napi_env env,napi_callback_info info,const std::initializer_list<std::string> & events,bool asyncCallback)60 napi_value Once(napi_env env, napi_callback_info info, const std::initializer_list<std::string> &events,
61 bool asyncCallback)
62 {
63 napi_value thisVal = nullptr;
64 size_t paramsCount = MAX_PARAM_NUM;
65 napi_value params[MAX_PARAM_NUM] = {nullptr};
66 NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr));
67
68 if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string ||
69 NapiUtils::GetValueType(env, params[1]) != napi_function) {
70 NETSTACK_LOGE("on off once interface para: [string, function]");
71 return NapiUtils::GetUndefined(env);
72 }
73
74 std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
75 if (std::find(events.begin(), events.end(), event) == events.end()) {
76 return NapiUtils::GetUndefined(env);
77 }
78
79 EventManager *manager = nullptr;
80 napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager));
81 if (manager != nullptr) {
82 manager->AddListener(env, event, params[1], true, asyncCallback);
83 }
84
85 return NapiUtils::GetUndefined(env);
86 }
87
Off(napi_env env,napi_callback_info info,const std::initializer_list<std::string> & events)88 napi_value Off(napi_env env, napi_callback_info info, const std::initializer_list<std::string> &events)
89 {
90 napi_value thisVal = nullptr;
91 size_t paramsCount = MAX_PARAM_NUM;
92 napi_value params[MAX_PARAM_NUM] = {nullptr};
93 NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr));
94
95 if ((paramsCount != 1 && paramsCount != EVENT_PARAM_NUM) ||
96 NapiUtils::GetValueType(env, params[0]) != napi_string) {
97 NETSTACK_LOGE("on off once interface para: [string, function?]");
98 napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG);
99 return NapiUtils::GetUndefined(env);
100 }
101
102 if (paramsCount == EVENT_PARAM_NUM && NapiUtils::GetValueType(env, params[1]) != napi_function) {
103 NETSTACK_LOGE("on off once interface para: [string, function]");
104 napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG);
105 return NapiUtils::GetUndefined(env);
106 }
107
108 std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
109 if (std::find(events.begin(), events.end(), event) == events.end()) {
110 return NapiUtils::GetUndefined(env);
111 }
112
113 EventManager *manager = nullptr;
114 napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager));
115 if (manager != nullptr) {
116 if (paramsCount == EVENT_PARAM_NUM) {
117 manager->DeleteListener(event, params[1]);
118 } else {
119 manager->DeleteListener(event);
120 }
121 }
122
123 return NapiUtils::GetUndefined(env);
124 }
125
DefineClass(napi_env env,napi_value exports,const std::initializer_list<napi_property_descriptor> & properties,const std::string & className)126 void DefineClass(napi_env env, napi_value exports, const std::initializer_list<napi_property_descriptor> &properties,
127 const std::string &className)
128 {
129 auto constructor = [](napi_env env, napi_callback_info info) -> napi_value {
130 napi_value thisVal = nullptr;
131 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
132
133 return thisVal;
134 };
135
136 napi_value jsConstructor = nullptr;
137
138 napi_property_descriptor descriptors[properties.size()];
139 std::copy(properties.begin(), properties.end(), descriptors);
140
141 NAPI_CALL_RETURN_VOID(env, napi_define_class(env, className.c_str(), NAPI_AUTO_LENGTH, constructor, nullptr,
142 properties.size(), descriptors, &jsConstructor));
143
144 NapiUtils::SetNamedProperty(env, exports, className, jsConstructor);
145 }
146
NewInstance(napi_env env,napi_callback_info info,const std::string & className,Finalizer finalizer)147 napi_value NewInstance(napi_env env, napi_callback_info info, const std::string &className, Finalizer finalizer)
148 {
149 napi_value thisVal = nullptr;
150 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
151
152 napi_value jsConstructor = NapiUtils::GetNamedProperty(env, thisVal, className);
153 if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) {
154 return nullptr;
155 }
156
157 napi_value result = nullptr;
158 NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result));
159
160 auto manager = new EventManager();
161 EventManager::SetValid(manager);
162 if (className == Http::HttpModuleExports::INTERFACE_HTTP_REQUEST) {
163 manager->CreateEventReference(env, thisVal);
164 }
165 napi_wrap(env, result, reinterpret_cast<void *>(manager), finalizer, nullptr, nullptr);
166
167 return result;
168 }
169
NewInstanceNoManager(napi_env env,napi_callback_info info,const std::string & name,Finalizer finalizer)170 napi_value NewInstanceNoManager(napi_env env, napi_callback_info info, const std::string &name, Finalizer finalizer)
171 {
172 napi_value thisVal = nullptr;
173 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
174
175 napi_value jsConstructor = NapiUtils::GetNamedProperty(env, thisVal, name);
176 if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) {
177 return nullptr;
178 }
179
180 napi_value result = nullptr;
181 NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result));
182
183 return result;
184 }
185 } // namespace OHOS::NetStack::ModuleTemplate
186