1 /*
2  * Copyright (C) 2021 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 "napi_common.h"
17 #include "net_mgr_log_wrapper.h"
18 
19 namespace OHOS {
20 namespace NetManagerStandard {
21 namespace {
22 constexpr const char *CODE = "code";
23 constexpr const char *MSG = "message";
24 } // namespace
25 
IsValidEvent(const std::string & eventInfo,int32_t & eventId)26 bool NapiCommon::IsValidEvent(const std::string &eventInfo, int32_t &eventId)
27 {
28     bool isEvent = true;
29     if (!eventInfo.compare(NET_UID_POLICY_CHANGE)) {
30         eventId = EVENT_NET_UID_POLICY_CHANGE;
31     } else if (!eventInfo.compare(NET_CELLULAR_POLICY_CHANGE)) {
32         eventId = EVENT_NET_CELLULAR_POLICY_CHANGE;
33     } else if (!eventInfo.compare(NET_STRATEGY_SWITCH_CHANGE)) {
34         eventId = EVENT_NET_STRATEGY_SWITCH_CHANGE;
35     } else if (!eventInfo.compare(NET_AVAILABLE_CHANGE)) {
36         eventId = EVENT_NET_AVAILABLE_CHANGE;
37     } else if (!eventInfo.compare(NET_CAPABILITIES_CHANGE)) {
38         eventId = EVENT_NET_CAPABILITIES_CHANGE;
39     } else if (!eventInfo.compare(NET_CONNECTION_CHANGE)) {
40         eventId = EVENT_NET_CONNECTION_CHANGE;
41     } else if (!eventInfo.compare(NET_LOST_CHANGE)) {
42         eventId = EVENT_NET_LOST_CHANGE;
43     } else if (!eventInfo.compare(NET_STATS_CHANGE)) {
44         eventId = EVENT_NET_STATS_CHANGE;
45     } else if (!eventInfo.compare(NET_BLOCK_STATUS_CHANGE)) {
46         eventId = EVENT_NET_BLOCK_STATUS_CHANGE;
47     } else if (!eventInfo.compare(NET_UNAVAILABLE_CHANGE)) {
48         eventId = EVENT_NET_UNAVAILABLE_CHANGE;
49     } else {
50         isEvent = false;
51     }
52     return isEvent;
53 }
54 
CreateCodeMessage(napi_env env,const std::string & msg,int32_t code)55 napi_value NapiCommon::CreateCodeMessage(napi_env env, const std::string &msg, int32_t code)
56 {
57     napi_value messageCodeInfo = nullptr;
58     napi_value messageInfo = nullptr;
59     napi_value codeInfo = nullptr;
60     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), msg.length(), &messageInfo));
61     NAPI_CALL(
62         env, napi_create_string_utf8(env, std::to_string(code).c_str(), std::to_string(code).length(), &codeInfo));
63     NAPI_CALL(env, napi_create_error(env, codeInfo, messageInfo, &messageCodeInfo));
64     return messageCodeInfo;
65 }
66 
SetPropertyBool(napi_env env,napi_value object,const std::string & propertyName,bool property)67 void NapiCommon::SetPropertyBool(
68     napi_env env, napi_value object, const std::string &propertyName, bool property)
69 {
70     napi_value propertyDest = nullptr;
71     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, property, &propertyDest));
72     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, propertyName.c_str(), propertyDest));
73 }
74 
SetPropertyInt32(napi_env env,napi_value object,const std::string & propertyName,int32_t property)75 void NapiCommon::SetPropertyInt32(
76     napi_env env, napi_value object, const std::string &propertyName, int32_t property)
77 {
78     napi_value propertyDest = nullptr;
79     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, property, &propertyDest));
80     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, propertyName.c_str(), propertyDest));
81 }
82 
SetPropertyInt64(napi_env env,napi_value object,const std::string & propertyName,int64_t property)83 void NapiCommon::SetPropertyInt64(
84     napi_env env, napi_value object, const std::string &propertyName, int64_t property)
85 {
86     napi_value propertyDest = nullptr;
87     NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, property, &propertyDest));
88     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, propertyName.c_str(), propertyDest));
89 }
90 
SetPropertyUint32(napi_env env,napi_value object,const std::string & propertyName,uint32_t property)91 void NapiCommon::SetPropertyUint32(
92     napi_env env, napi_value object, const std::string &propertyName, uint32_t property)
93 {
94     napi_value propertyDest = nullptr;
95     NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, property, &propertyDest));
96     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, propertyName.c_str(), propertyDest));
97 }
98 
SetPropertyString(napi_env env,napi_value object,const std::string & propertyName,const std::string & property)99 void NapiCommon::SetPropertyString(
100     napi_env env, napi_value object, const std::string &propertyName, const std::string &property)
101 {
102     napi_value propertyDest = nullptr;
103     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, property.c_str(), property.length(), &propertyDest));
104     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, propertyName.c_str(), propertyDest));
105 }
106 
GetPropertyString(napi_env env,napi_value object,const std::string & propertyName,std::string & property)107 void NapiCommon::GetPropertyString(
108     napi_env env, napi_value object, const std::string &propertyName, std::string &property)
109 {
110     napi_value value = nullptr;
111     char propertyBuffer[PROPERTY_MAX_BYTE] = {0};
112     size_t realByte = 0;
113     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
114     NAPI_CALL_RETURN_VOID(
115         env, napi_get_value_string_utf8(env, value, propertyBuffer, PROPERTY_MAX_BYTE, &realByte));
116     property = propertyBuffer;
117 }
118 
GetPropertyInt32(napi_env env,napi_value object,const std::string & propertyName,int32_t & property)119 void NapiCommon::GetPropertyInt32(
120     napi_env env, napi_value object, const std::string &propertyName, int32_t &property)
121 {
122     napi_value value = nullptr;
123     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
124     NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, value, &property));
125 }
126 
GetPropertyInt64(napi_env env,napi_value object,const std::string & propertyName,int64_t & property)127 void NapiCommon::GetPropertyInt64(
128     napi_env env, napi_value object, const std::string &propertyName, int64_t &property)
129 {
130     napi_value value = nullptr;
131     NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
132     NAPI_CALL_RETURN_VOID(env, napi_get_value_int64(env, value, &property));
133 }
134 
NapiValueByInt32(napi_env env,int32_t property)135 napi_value NapiCommon::NapiValueByInt32(napi_env env, int32_t property)
136 {
137     napi_value value = nullptr;
138     NAPI_CALL(env, napi_create_int32(env, property, &value));
139     return value;
140 }
141 
GetNapiStringValue(napi_env env,napi_value napiValue,const std::string & name,const std::string & defValue)142 std::string NapiCommon::GetNapiStringValue(
143     napi_env env, napi_value napiValue, const std::string &name, const std::string &defValue)
144 {
145     napi_value value = GetNamedProperty(env, napiValue, name);
146     if (value != nullptr) {
147         return GetStringFromValue(env, value);
148     } else {
149         return defValue;
150     }
151 }
152 
GetStringFromValue(napi_env env,napi_value value)153 std::string NapiCommon::GetStringFromValue(napi_env env, napi_value value)
154 {
155     char msgChars[MAX_TEXT_LENGTH] = {0};
156     size_t msgLength = 0;
157     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, msgChars, MAX_TEXT_LENGTH, &msgLength), "");
158     if (msgLength > 0) {
159         return std::string(msgChars, 0, msgLength);
160     } else {
161         return "";
162     }
163 }
164 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)165 napi_value NapiCommon::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
166 {
167     napi_value value = nullptr;
168     bool hasProperty = false;
169     NAPI_CALL(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty));
170     if (hasProperty) {
171         NAPI_CALL(env, napi_get_named_property(env, object, propertyName.data(), &value));
172     }
173     return value;
174 }
175 
GetNapiInt32Value(napi_env env,napi_value napiValue,const std::string & name,const int32_t & defValue)176 int32_t NapiCommon::GetNapiInt32Value(
177     napi_env env, napi_value napiValue, const std::string &name, const int32_t &defValue)
178 {
179     napi_value value = GetNamedProperty(env, napiValue, name);
180     if (value != nullptr) {
181         int32_t intValue = 0;
182         napi_status getIntStatus = napi_get_value_int32(env, value, &intValue);
183         if (getIntStatus == napi_ok) {
184             return intValue;
185         }
186     }
187     return defValue;
188 }
189 
GetNapiInt64Value(napi_env env,napi_value napiValue,const std::string & name,const int64_t & defValue)190 int64_t NapiCommon::GetNapiInt64Value(
191     napi_env env, napi_value napiValue, const std::string &name, const int64_t &defValue)
192 {
193     napi_value value = GetNamedProperty(env, napiValue, name);
194     if (value != nullptr) {
195         int64_t intValue = 0;
196         napi_status getIntStatus = napi_get_value_int64(env, value, &intValue);
197         if (getIntStatus == napi_ok) {
198             return intValue;
199         }
200     }
201     return defValue;
202 }
203 
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)204 bool NapiCommon::MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
205 {
206     napi_valuetype valueType = napi_undefined;
207     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
208     return valueType == targetType;
209 }
210 
MatchParameters(napi_env env,const napi_value parameters[],std::initializer_list<napi_valuetype> valueTypes)211 bool NapiCommon::MatchParameters(
212     napi_env env, const napi_value parameters[], std::initializer_list<napi_valuetype> valueTypes)
213 {
214     if (parameters == nullptr) {
215         return false;
216     }
217     int i = 0;
218     for (auto beg = valueTypes.begin(); beg != valueTypes.end(); ++beg) {
219         if (!MatchValueType(env, parameters[i], *beg)) {
220             return false;
221         }
222         ++i;
223     }
224     return true;
225 }
226 
CreateUndefined(napi_env env)227 napi_value NapiCommon::CreateUndefined(napi_env env)
228 {
229     napi_value result = nullptr;
230     NAPI_CALL(env, napi_get_undefined(env, &result));
231     return result;
232 }
233 
HandleAsyncWork(napi_env env,BaseContext * baseContext,const std::string & workName,napi_async_execute_callback execute,napi_async_complete_callback complete)234 napi_value NapiCommon::HandleAsyncWork(napi_env env, BaseContext *baseContext, const std::string &workName,
235     napi_async_execute_callback execute, napi_async_complete_callback complete)
236 {
237     NETMGR_LOG_I("NapiCommon HandleAsyncWork workName = %{public}s", workName.c_str());
238     std::unique_ptr<BaseContext> context(baseContext);
239     if (context == nullptr) {
240         std::string errorCode = std::to_string(napi_invalid_arg);
241         std::string errorMessage = "error at baseContext is nullptr";
242         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
243         napi_value res = nullptr;
244         NAPI_CALL(env, napi_get_undefined(env, &res));
245         return res;
246     }
247     napi_value result = nullptr;
248     if (context->callbackRef == nullptr) {
249         NAPI_CALL(env, napi_create_promise(env, &context->deferred, &result));
250     } else {
251         NAPI_CALL(env, napi_get_undefined(env, &result));
252     }
253     napi_value resource = CreateUndefined(env);
254     napi_value resourceName = nullptr;
255     NAPI_CALL(env, napi_create_string_utf8(env, workName.data(), NAPI_AUTO_LENGTH, &resourceName));
256     NAPI_CALL(env,
257         napi_create_async_work(
258             env, resource, resourceName, execute, complete, static_cast<void *>(context.get()), &context->work));
259     napi_status queueWorkStatus = napi_queue_async_work_with_qos(env, context->work, napi_qos_default);
260     if (queueWorkStatus == napi_ok) {
261         context.release();
262         NETMGR_LOG_I("NapiCommon HandleAsyncWork napi_queue_async_work_with_qos ok");
263     } else {
264         std::string errorCode = std::to_string(queueWorkStatus);
265         std::string errorMessage = "error at napi_queue_async_work_with_qos";
266         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
267     }
268     NETMGR_LOG_I("NapiCommon HandleAsyncWork end");
269     return result;
270 }
271 
Handle1ValueCallback(napi_env env,BaseContext * baseContext,napi_value callbackValue)272 void NapiCommon::Handle1ValueCallback(napi_env env, BaseContext *baseContext, napi_value callbackValue)
273 {
274     NETMGR_LOG_I("Handle1ValueCallback start");
275     if (baseContext == nullptr) {
276         NETMGR_LOG_I("Handle1ValueCallback serious error baseContext nullptr");
277         std::string errorCode = std::to_string(napi_invalid_arg);
278         std::string errorMessage = "error at baseContext is nullptr";
279         NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
280         return;
281     }
282     if (baseContext->callbackRef != nullptr) {
283         NETMGR_LOG_I("Handle1ValueCallback start normal callback");
284         napi_value recv = CreateUndefined(env);
285         napi_value callbackFunc = nullptr;
286         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
287         napi_value callbackValues[] = {callbackValue};
288         napi_value result = nullptr;
289         NAPI_CALL_RETURN_VOID(
290             env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
291         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
292         NETMGR_LOG_I("Handle1ValueCallback normal callback end");
293     } else if (baseContext->deferred != nullptr) {
294         NETMGR_LOG_I("Handle1ValueCallback start promise callback");
295         if (baseContext->resolved) {
296             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, baseContext->deferred, callbackValue));
297             NETMGR_LOG_I("Handle1ValueCallback napi_resolve_deferred end");
298         } else {
299             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, callbackValue));
300             NETMGR_LOG_I("Handle1ValueCallback napi_reject_deferred end");
301         }
302         NETMGR_LOG_I("Handle1ValueCallback promise callback end");
303     }
304     napi_delete_async_work(env, baseContext->work);
305     delete baseContext;
306     NETMGR_LOG_I("Handle1ValueCallback end");
307 }
308 
Handle2ValueCallback(napi_env env,BaseContext * baseContext,napi_value callbackValue)309 void NapiCommon::Handle2ValueCallback(napi_env env, BaseContext *baseContext, napi_value callbackValue)
310 {
311     NETMGR_LOG_I("Handle2ValueCallback start");
312     if (baseContext == nullptr) {
313         NETMGR_LOG_I("Handle2ValueCallback serious error baseContext nullptr");
314         std::string errorCode = std::to_string(napi_invalid_arg);
315         std::string errorMessage = "error at baseContext is nullptr";
316         NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
317         return;
318     }
319     if (baseContext->callbackRef != nullptr) {
320         NETMGR_LOG_I("Handle2ValueCallback start normal callback");
321         napi_value recv = CreateUndefined(env);
322         napi_value callbackFunc = nullptr;
323         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
324         napi_value callbackValues[] = {nullptr, nullptr};
325         callbackValues[0] = baseContext->resolved ? CreateUndefined(env) : callbackValue;
326         callbackValues[1] = baseContext->resolved ? callbackValue : CreateUndefined(env);
327         napi_value result = nullptr;
328         NAPI_CALL_RETURN_VOID(
329             env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
330         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
331         NETMGR_LOG_I("Handle2ValueCallback normal callback end");
332     } else if (baseContext->deferred != nullptr) {
333         NETMGR_LOG_I("Handle2ValueCallback start promise callback");
334         if (baseContext->resolved) {
335             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, baseContext->deferred, callbackValue));
336         } else {
337             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, callbackValue));
338         }
339         NETMGR_LOG_I("Handle2ValueCallback promise callback end");
340     }
341     napi_delete_async_work(env, baseContext->work);
342     delete baseContext;
343     NETMGR_LOG_I("Handle2ValueCallback end");
344 }
345 
HasNamedTypeProperty(napi_env env,napi_value object,napi_valuetype type,const std::string & propertyName)346 bool NapiCommon::HasNamedTypeProperty(
347     napi_env env, napi_value object, napi_valuetype type, const std::string &propertyName)
348 {
349     bool hasProperty = false;
350     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
351     if (hasProperty) {
352         napi_value value = nullptr;
353         NAPI_CALL_BASE(env, napi_get_named_property(env, object, propertyName.data(), &value), false);
354         return NapiCommon::MatchValueType(env, value, type);
355     }
356     return false;
357 }
358 
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)359 bool NapiCommon::HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
360 {
361     bool hasProperty = false;
362     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
363     return hasProperty;
364 }
365 
MatchObjectProperty(napi_env env,napi_value object,std::initializer_list<std::pair<std::string,napi_valuetype>> pairList)366 bool NapiCommon::MatchObjectProperty(
367     napi_env env, napi_value object, std::initializer_list<std::pair<std::string, napi_valuetype>> pairList)
368 {
369     if (object == nullptr) {
370         return false;
371     }
372     for (auto beg = pairList.begin(); beg != pairList.end(); ++beg) {
373         if (!HasNamedTypeProperty(env, object, beg->second, beg->first)) {
374             return false;
375         }
376     }
377     return true;
378 }
379 
CreateEnumConstructor(napi_env env,napi_callback_info info)380 napi_value NapiCommon::CreateEnumConstructor(napi_env env, napi_callback_info info)
381 {
382     napi_value thisArg = nullptr;
383     void *data = nullptr;
384     napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
385     napi_value global = nullptr;
386     napi_get_global(env, &global);
387     return thisArg;
388 }
389 
CreateObject(napi_env env)390 napi_value NapiCommon::CreateObject(napi_env env)
391 {
392     napi_value object = nullptr;
393     NAPI_CALL(env, napi_create_object(env, &object));
394     return object;
395 }
396 
CreateErrorMessage(napi_env env,int32_t errorCode,const std::string & errorMessage)397 napi_value NapiCommon::CreateErrorMessage(napi_env env, int32_t errorCode, const std::string &errorMessage)
398 {
399     napi_value result = CreateObject(env);
400     SetPropertyInt32(env, result, CODE, errorCode);
401     SetPropertyString(env, result, MSG, errorMessage);
402     return result;
403 }
404 } // namespace NetManagerStandard
405 } // namespace OHOS
406