• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "config_policy_napi.h"
17 
18 #include <vector>
19 
20 #include "hilog/log.h"
21 #include "config_policy_utils.h"
22 #include "hisysevent_adapter.h"
23 
24 namespace OHOS {
25 namespace Customization {
26 namespace ConfigPolicy {
27 using namespace OHOS::HiviewDFX;
28 
29 static constexpr size_t ARGS_SIZE_ONE = 1;
30 static constexpr size_t ARGS_SIZE_TWO = 2;
31 static constexpr size_t ARGS_SIZE_THREE = 3;
32 static constexpr size_t ARGS_SIZE_FOUR = 4;
33 static constexpr int32_t ARR_INDEX_ZERO = 0;
34 static constexpr int32_t ARR_INDEX_ONE = 1;
35 static constexpr int32_t ARR_INDEX_TWO = 2;
36 static constexpr int32_t ARR_INDEX_THREE = 3;
37 static constexpr int32_t NAPI_RETURN_ZERO = 0;
38 static constexpr int32_t NAPI_RETURN_ONE = 1;
39 // Param Error Code
40 static constexpr int32_t PARAM_ERROR = 401;
41 static constexpr HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "ConfigPolicyJs" };
42 
Init(napi_env env,napi_value exports)43 napi_value ConfigPolicyNapi::Init(napi_env env, napi_value exports)
44 {
45     napi_value nFollowXMode = nullptr;
46     NAPI_CALL(env, napi_create_object(env, &nFollowXMode));
47     CreateFollowXModeObject(env, nFollowXMode);
48 
49     napi_property_descriptor property[] = {
50         DECLARE_NAPI_FUNCTION("getOneCfgFile", ConfigPolicyNapi::NAPIGetOneCfgFile),
51         DECLARE_NAPI_FUNCTION("getOneCfgFileSync", ConfigPolicyNapi::NAPIGetOneCfgFileSync),
52         DECLARE_NAPI_FUNCTION("getCfgFiles", ConfigPolicyNapi::NAPIGetCfgFiles),
53         DECLARE_NAPI_FUNCTION("getCfgFilesSync", ConfigPolicyNapi::NAPIGetCfgFilesSync),
54         DECLARE_NAPI_FUNCTION("getCfgDirList", ConfigPolicyNapi::NAPIGetCfgDirList),
55         DECLARE_NAPI_FUNCTION("getCfgDirListSync", ConfigPolicyNapi::NAPIGetCfgDirListSync),
56 
57         DECLARE_NAPI_PROPERTY("FollowXMode", nFollowXMode)
58     };
59     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
60     return exports;
61 }
62 
CreateFollowXModeObject(napi_env env,napi_value value)63 void ConfigPolicyNapi::CreateFollowXModeObject(napi_env env, napi_value value)
64 {
65     napi_value nDefaultMode;
66     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(FOLLOWX_MODE_DEFAULT), &nDefaultMode));
67     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "DEFAULT", nDefaultMode));
68     napi_value nNoFollowMode;
69     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(FOLLOWX_MODE_NO_RULE_FOLLOWED),
70                           &nNoFollowMode));
71     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "NO_RULE_FOLLOWED", nNoFollowMode));
72     napi_value nSimDefaultMode;
73     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(FOLLOWX_MODE_SIM_DEFAULT),
74         &nSimDefaultMode));
75     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "SIM_DEFAULT", nSimDefaultMode));
76     napi_value nSim1Mode;
77     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(FOLLOWX_MODE_SIM_1), &nSim1Mode));
78     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "SIM_1", nSim1Mode));
79     napi_value nSim2Mode;
80     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(FOLLOWX_MODE_SIM_2), &nSim2Mode));
81     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "SIM_2", nSim2Mode));
82     napi_value nUserDefineMode;
83     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(FOLLOWX_MODE_USER_DEFINED),
84         &nUserDefineMode));
85     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "USER_DEFINED", nUserDefineMode));
86 }
87 
NAPIGetOneCfgFile(napi_env env,napi_callback_info info)88 napi_value ConfigPolicyNapi::NAPIGetOneCfgFile(napi_env env, napi_callback_info info)
89 {
90     HiLog::Debug(LABEL, "NAPIGetOneCfgFile start.");
91     return GetOneCfgFileOrAllCfgFiles(env, info, "NAPIGetOneCfgFile", NativeGetOneCfgFile);
92 }
93 
NAPIGetOneCfgFileSync(napi_env env,napi_callback_info info)94 napi_value ConfigPolicyNapi::NAPIGetOneCfgFileSync(napi_env env, napi_callback_info info)
95 {
96     HiLog::Debug(LABEL, "NAPIGetOneCfgFileSync start.");
97     return GetOneCfgFileOrAllCfgFilesSync(env, info, NativeGetOneCfgFileSync);
98 }
99 
GetOneCfgFileOrAllCfgFilesSync(napi_env env,napi_callback_info info,NapiFunction func)100 napi_value ConfigPolicyNapi::GetOneCfgFileOrAllCfgFilesSync(napi_env env, napi_callback_info info, NapiFunction func)
101 {
102     size_t argc = ARGS_SIZE_THREE;
103     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
104     napi_value thisVar = nullptr;
105     void *data = nullptr;
106     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
107     if (argc < ARGS_SIZE_ONE) {
108         return ThrowNapiError(env, PARAM_ERROR, "Parameter error. The number of parameters is incorrect.");
109     }
110 
111     auto asyncContext = std::make_shared<ConfigAsyncContext>();
112     asyncContext->followMode_ = FOLLOWX_MODE_DEFAULT;
113     bool hasExtra = false;
114     if (ParseRelPath(env, asyncContext->relPath_, argv[ARR_INDEX_ZERO]) == nullptr) {
115         return nullptr;
116     }
117 
118     if (argc == ARGS_SIZE_TWO) {
119         if (ParseFollowMode(env, asyncContext->followMode_, argv[ARR_INDEX_ONE], hasExtra) == nullptr) {
120             return nullptr;
121         }
122     }
123     if (argc >= ARGS_SIZE_THREE) {
124         hasExtra = true;
125         if (ParseFollowMode(env, asyncContext->followMode_, argv[ARR_INDEX_ONE], hasExtra) == nullptr ||
126             ParseExtra(env, asyncContext->extra_, argv[ARR_INDEX_TWO]) == nullptr) {
127             return nullptr;
128         }
129     }
130     return func(env, asyncContext);
131 }
132 
GetOneCfgFileOrAllCfgFiles(napi_env env,napi_callback_info info,const std::string & workName,napi_async_execute_callback execute)133 napi_value ConfigPolicyNapi::GetOneCfgFileOrAllCfgFiles(napi_env env, napi_callback_info info,
134     const std::string &workName, napi_async_execute_callback execute)
135 {
136     size_t argc = ARGS_SIZE_FOUR;
137     napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
138     napi_value thisVar = nullptr;
139     void *data = nullptr;
140     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
141     if (argc < ARGS_SIZE_ONE) {
142         return ThrowNapiError(env, PARAM_ERROR, "Parameter error. The number of parameters is incorrect.");
143     }
144 
145     auto asyncContext = std::make_unique<ConfigAsyncContext>();
146     asyncContext->followMode_ = FOLLOWX_MODE_DEFAULT;
147     bool hasExtra = false;
148     if (ParseRelPath(env, asyncContext->relPath_, argv[ARR_INDEX_ZERO]) == nullptr) {
149         return nullptr;
150     }
151     if (argc == ARGS_SIZE_TWO) {
152         if (MatchValueType(env, argv[ARR_INDEX_ONE], napi_function)) {
153             napi_create_reference(env, argv[ARR_INDEX_ONE], NAPI_RETURN_ONE, &asyncContext->callbackRef_);
154         } else {
155             if (ParseFollowMode(env, asyncContext->followMode_, argv[ARR_INDEX_ONE], hasExtra) == nullptr) {
156                 return nullptr;
157             }
158         }
159     }
160 
161     if (argc == ARGS_SIZE_THREE) {
162         if (MatchValueType(env, argv[ARR_INDEX_TWO], napi_function)) {
163             napi_create_reference(env, argv[ARR_INDEX_TWO], NAPI_RETURN_ONE, &asyncContext->callbackRef_);
164         } else {
165             if (ParseExtra(env, asyncContext->extra_, argv[ARR_INDEX_TWO]) == nullptr) {
166                 return nullptr;
167             }
168             hasExtra = true;
169         }
170         if (ParseFollowMode(env, asyncContext->followMode_, argv[ARR_INDEX_ONE], hasExtra) == nullptr) {
171             return nullptr;
172         }
173     }
174 
175     if (argc == ARGS_SIZE_FOUR) {
176         hasExtra = true;
177         if (ParseFollowMode(env, asyncContext->followMode_, argv[ARR_INDEX_ONE], hasExtra) == nullptr ||
178             ParseExtra(env, asyncContext->extra_, argv[ARR_INDEX_TWO]) == nullptr) {
179             return nullptr;
180         }
181         if (!MatchValueType(env, argv[ARR_INDEX_THREE], napi_function)) {
182             return ThrowNapiError(env, PARAM_ERROR, "Parameter error. The fourth parameter must be Callback.");
183         }
184         napi_create_reference(env, argv[ARR_INDEX_THREE], NAPI_RETURN_ONE, &asyncContext->callbackRef_);
185     }
186     return HandleAsyncWork(env, asyncContext.release(), workName, execute, NativeCallbackComplete);
187 }
188 
NAPIGetCfgFiles(napi_env env,napi_callback_info info)189 napi_value ConfigPolicyNapi::NAPIGetCfgFiles(napi_env env, napi_callback_info info)
190 {
191     HiLog::Debug(LABEL, "NAPIGetCfgFiles start.");
192     return GetOneCfgFileOrAllCfgFiles(env, info, "NAPIGetCfgFiles", NativeGetCfgFiles);
193 }
194 
NAPIGetCfgFilesSync(napi_env env,napi_callback_info info)195 napi_value ConfigPolicyNapi::NAPIGetCfgFilesSync(napi_env env, napi_callback_info info)
196 {
197     HiLog::Debug(LABEL, "NAPIGetCfgFilesSync start.");
198     return GetOneCfgFileOrAllCfgFilesSync(env, info, NativeGetCfgFilesSync);
199 }
200 
NAPIGetCfgDirList(napi_env env,napi_callback_info info)201 napi_value ConfigPolicyNapi::NAPIGetCfgDirList(napi_env env, napi_callback_info info)
202 {
203     size_t argc = ARGS_SIZE_ONE;
204     napi_value argv[ARGS_SIZE_ONE] = {nullptr};
205     napi_value thisVar = nullptr;
206     void *data = nullptr;
207     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
208 
209     auto asyncContext = std::make_unique<ConfigAsyncContext>();
210     if (argc == ARGS_SIZE_ONE) {
211         bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_function);
212         if (!matchFlag) {
213             return ThrowNapiError(env, PARAM_ERROR, "Parameter error. The first parameter must be Callback.");
214         }
215         napi_create_reference(env, argv[ARR_INDEX_ZERO], NAPI_RETURN_ONE, &asyncContext->callbackRef_);
216     }
217     return HandleAsyncWork(env, asyncContext.release(), "NAPIGetCfgDirList", NativeGetCfgDirList,
218         NativeCallbackComplete);
219 }
220 
NAPIGetCfgDirListSync(napi_env env,napi_callback_info info)221 napi_value ConfigPolicyNapi::NAPIGetCfgDirListSync(napi_env env, napi_callback_info info)
222 {
223     auto asyncContext = std::make_shared<ConfigAsyncContext>();
224     return NativeGetCfgDirListSync(env, asyncContext);
225 }
226 
CreateUndefined(napi_env env)227 napi_value ConfigPolicyNapi::CreateUndefined(napi_env env)
228 {
229     napi_value result = nullptr;
230     napi_get_undefined(env, &result);
231     return result;
232 }
233 
GetStringFromNAPI(napi_env env,napi_value value)234 std::string ConfigPolicyNapi::GetStringFromNAPI(napi_env env, napi_value value)
235 {
236     std::string result;
237     size_t size = 0;
238 
239     if (napi_get_value_string_utf8(env, value, nullptr, NAPI_RETURN_ZERO, &size) != napi_ok) {
240         HiLog::Error(LABEL, "can not get string size.");
241         return "";
242     }
243     result.reserve(size + NAPI_RETURN_ONE);
244     result.resize(size);
245     if (napi_get_value_string_utf8(env, value, result.data(), (size + NAPI_RETURN_ONE), &size) != napi_ok) {
246         HiLog::Error(LABEL, "can not get string value.");
247         return "";
248     }
249     return result;
250 }
251 
HandleAsyncWork(napi_env env,ConfigAsyncContext * context,std::string workName,napi_async_execute_callback execute,napi_async_complete_callback complete)252 napi_value ConfigPolicyNapi::HandleAsyncWork(napi_env env, ConfigAsyncContext *context, std::string workName,
253     napi_async_execute_callback execute, napi_async_complete_callback complete)
254 {
255     HiLog::Debug(LABEL, "HandleAsyncWork start.");
256     if (context == nullptr) {
257         HiLog::Error(LABEL, "context is nullptr");
258         return nullptr;
259     }
260 
261     napi_value result = nullptr;
262     if (context->callbackRef_ == nullptr) {
263         napi_create_promise(env, &context->deferred_, &result);
264     } else {
265         napi_get_undefined(env, &result);
266     }
267     napi_value resource = CreateUndefined(env);
268     napi_value resourceName = nullptr;
269     napi_create_string_utf8(env, workName.data(), NAPI_AUTO_LENGTH, &resourceName);
270     napi_create_async_work(env, resource, resourceName, execute, complete, static_cast<void *>(context),
271         &context->work_);
272     napi_queue_async_work_with_qos(env, context->work_, napi_qos_default);
273     HiLog::Debug(LABEL, "HandleAsyncWork end.");
274     return result;
275 }
276 
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)277 bool ConfigPolicyNapi::MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
278 {
279     napi_valuetype valueType = napi_undefined;
280     napi_typeof(env, value, &valueType);
281     return valueType == targetType;
282 }
283 
NativeGetOneCfgFile(napi_env env,void * data)284 void ConfigPolicyNapi::NativeGetOneCfgFile(napi_env env, void *data)
285 {
286     HiLog::Debug(LABEL, "NativeGetOneCfgFile start.");
287     if (data == nullptr) {
288         HiLog::Error(LABEL, "data is nullptr");
289         return;
290     }
291     ConfigAsyncContext *asyncCallbackInfo = static_cast<ConfigAsyncContext *>(data);
292     char outBuf[MAX_PATH_LEN] = {0};
293     char *filePath = GetOneCfgFileEx(asyncCallbackInfo->relPath_.c_str(), outBuf, MAX_PATH_LEN,
294                                      asyncCallbackInfo->followMode_, asyncCallbackInfo->extra_.c_str());
295     if (filePath == nullptr) {
296         HiLog::Info(LABEL, "GetOneCfgFileEx result is nullptr.");
297     } else {
298         asyncCallbackInfo->pathValue_ = std::string(filePath);
299     }
300     ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getOneCfgFile", "");
301     asyncCallbackInfo->createValueFunc_ = [](napi_env env, ConfigAsyncContext &context) -> napi_value {
302         napi_value result;
303         NAPI_CALL(env, napi_create_string_utf8(env, context.pathValue_.c_str(), NAPI_AUTO_LENGTH, &result));
304         return result;
305     };
306 }
307 
NativeGetOneCfgFileSync(napi_env env,std::shared_ptr<ConfigAsyncContext> context)308 napi_value ConfigPolicyNapi::NativeGetOneCfgFileSync(napi_env env, std::shared_ptr<ConfigAsyncContext> context)
309 {
310     HiLog::Debug(LABEL, "NativeGetOneCfgFileSync start.");
311     char outBuf[MAX_PATH_LEN] = {0};
312     char *filePath = GetOneCfgFileEx(context->relPath_.c_str(), outBuf, MAX_PATH_LEN,
313                                      context->followMode_, context->extra_.c_str());
314     if (filePath == nullptr) {
315         HiLog::Info(LABEL, "GetOneCfgFileEx result is nullptr.");
316     } else {
317         context->pathValue_ = std::string(filePath);
318     }
319     ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getOneCfgFileSync", "");
320     napi_value result = nullptr;
321     NAPI_CALL(env, napi_create_string_utf8(env, context->pathValue_.c_str(), NAPI_AUTO_LENGTH, &result));
322     return result;
323 }
324 
NativeGetCfgFiles(napi_env env,void * data)325 void ConfigPolicyNapi::NativeGetCfgFiles(napi_env env, void *data)
326 {
327     HiLog::Debug(LABEL, "NativeGetCfgFiles start.");
328     if (data == nullptr) {
329         HiLog::Error(LABEL, "data is nullptr");
330         return;
331     }
332 
333     ConfigAsyncContext *asyncCallbackInfo = static_cast<ConfigAsyncContext *>(data);
334     CfgFiles *cfgFiles = GetCfgFilesEx(asyncCallbackInfo->relPath_.c_str(), asyncCallbackInfo->followMode_,
335                                        asyncCallbackInfo->extra_.c_str());
336     if (cfgFiles != nullptr) {
337         for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
338             if (cfgFiles->paths[i] != nullptr) {
339                 asyncCallbackInfo->paths_.push_back(cfgFiles->paths[i]);
340             }
341         }
342         FreeCfgFiles(cfgFiles);
343     }
344     CreateArraysValueFunc(*asyncCallbackInfo);
345     ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getCfgFiles", "");
346 }
347 
NativeGetCfgFilesSync(napi_env env,std::shared_ptr<ConfigAsyncContext> context)348 napi_value ConfigPolicyNapi::NativeGetCfgFilesSync(napi_env env, std::shared_ptr<ConfigAsyncContext> context)
349 {
350     HiLog::Debug(LABEL, "NativeGetCfgFiles start.");
351     CfgFiles *cfgFiles = GetCfgFilesEx(context->relPath_.c_str(), context->followMode_,
352                                        context->extra_.c_str());
353     if (cfgFiles != nullptr) {
354         for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
355             if (cfgFiles->paths[i] != nullptr) {
356                 context->paths_.push_back(cfgFiles->paths[i]);
357             }
358         }
359         FreeCfgFiles(cfgFiles);
360     }
361     ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getCfgFilesSync", "");
362     return CreateArraysValue(env, context);
363 }
364 
NativeGetCfgDirList(napi_env env,void * data)365 void ConfigPolicyNapi::NativeGetCfgDirList(napi_env env, void *data)
366 {
367     HiLog::Debug(LABEL, "NativeGetCfgDirList start.");
368     if (data == nullptr) {
369         HiLog::Error(LABEL, "data is nullptr.");
370         return;
371     }
372 
373     ConfigAsyncContext *asyncCallbackInfo = static_cast<ConfigAsyncContext *>(data);
374     CfgDir *cfgDir = GetCfgDirList();
375     for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
376         if (cfgDir != nullptr && cfgDir->paths[i] != nullptr) {
377             asyncCallbackInfo->paths_.push_back(cfgDir->paths[i]);
378         }
379     }
380     FreeCfgDirList(cfgDir);
381     CreateArraysValueFunc(*asyncCallbackInfo);
382     ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getCfgDirList", "");
383 }
384 
NativeGetCfgDirListSync(napi_env env,std::shared_ptr<ConfigAsyncContext> context)385 napi_value ConfigPolicyNapi::NativeGetCfgDirListSync(napi_env env, std::shared_ptr<ConfigAsyncContext> context)
386 {
387     HiLog::Debug(LABEL, "NativeGetCfgDirListSync start.");
388     CfgDir *cfgDir = GetCfgDirList();
389     if (cfgDir != nullptr) {
390         for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
391             if (cfgDir->paths[i] != nullptr) {
392                 context->paths_.push_back(cfgDir->paths[i]);
393             }
394         }
395         FreeCfgDirList(cfgDir);
396     }
397     ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getCfgDirListSync", "");
398     return CreateArraysValue(env, context);
399 }
400 
CreateArraysValue(napi_env env,std::shared_ptr<ConfigAsyncContext> context)401 napi_value ConfigPolicyNapi::CreateArraysValue(napi_env env, std::shared_ptr<ConfigAsyncContext> context)
402 {
403     napi_value result = nullptr;
404     NAPI_CALL(env, napi_create_array_with_length(env, context->paths_.size(), &result));
405     for (size_t i = 0; i < context->paths_.size(); i++) {
406         napi_value element = nullptr;
407         NAPI_CALL(env, napi_create_string_utf8(env, context->paths_[i].c_str(), NAPI_AUTO_LENGTH, &element));
408         NAPI_CALL(env, napi_set_element(env, result, i, element));
409     }
410     return result;
411 }
412 
CreateArraysValueFunc(ConfigAsyncContext & asyncCallbackInfo)413 void ConfigPolicyNapi::CreateArraysValueFunc(ConfigAsyncContext &asyncCallbackInfo)
414 {
415     asyncCallbackInfo.createValueFunc_ = [](napi_env env, ConfigAsyncContext &context) -> napi_value {
416         napi_value result = nullptr;
417         NAPI_CALL(env, napi_create_array_with_length(env, context.paths_.size(), &result));
418         for (size_t i = 0; i < context.paths_.size(); i++) {
419             napi_value element = nullptr;
420             NAPI_CALL(env, napi_create_string_utf8(env, context.paths_[i].c_str(), NAPI_AUTO_LENGTH, &element));
421             NAPI_CALL(env, napi_set_element(env, result, i, element));
422         }
423         return result;
424     };
425 }
426 
NativeCallbackComplete(napi_env env,napi_status status,void * data)427 void ConfigPolicyNapi::NativeCallbackComplete(napi_env env, napi_status status, void *data)
428 {
429     HiLog::Debug(LABEL, "NativeCallbackComplete start.");
430     if (data == nullptr) {
431         HiLog::Error(LABEL, "data is nullptr");
432         return;
433     }
434 
435     napi_value finalResult = nullptr;
436     ConfigAsyncContext *asyncContext = static_cast<ConfigAsyncContext *>(data);
437     if (asyncContext->createValueFunc_ != nullptr) {
438         finalResult = asyncContext->createValueFunc_(env, *asyncContext);
439     }
440 
441     napi_value result[] = { nullptr, nullptr };
442     napi_get_null(env, &result[0]);
443     result[1] = finalResult;
444 
445     if (asyncContext->deferred_ != nullptr) {
446         napi_resolve_deferred(env, asyncContext->deferred_, result[1]);
447     } else {
448         napi_value callback = nullptr;
449         napi_value userRet = nullptr;
450         napi_get_reference_value(env, asyncContext->callbackRef_, &callback);
451         napi_call_function(env, nullptr, callback, sizeof(result) / sizeof(napi_value), result, &userRet);
452         napi_delete_reference(env, asyncContext->callbackRef_);
453     }
454     napi_delete_async_work(env, asyncContext->work_);
455     delete asyncContext;
456     HiLog::Debug(LABEL, "NativeCallbackComplete end.");
457 }
458 
ParseRelPath(napi_env env,std::string & param,napi_value args)459 napi_value ConfigPolicyNapi::ParseRelPath(napi_env env, std::string &param, napi_value args)
460 {
461     bool matchFlag = MatchValueType(env, args, napi_string);
462     if (!matchFlag) {
463         return ThrowNapiError(env, PARAM_ERROR, "Parameter error. The type of relPath must be string.");
464     }
465     param = GetStringFromNAPI(env, args);
466     napi_value result = nullptr;
467     NAPI_CALL(env, napi_create_int32(env, NAPI_RETURN_ONE, &result));
468     return result;
469 }
470 
ParseExtra(napi_env env,std::string & param,napi_value args)471 napi_value ConfigPolicyNapi::ParseExtra(napi_env env, std::string &param, napi_value args)
472 {
473     bool matchFlag = MatchValueType(env, args, napi_string);
474     if (!matchFlag) {
475         return ThrowNapiError(env, PARAM_ERROR, "Parameter error. The type of extra must be string.");
476     }
477     param = GetStringFromNAPI(env, args);
478     napi_value result = nullptr;
479     NAPI_CALL(env, napi_create_int32(env, NAPI_RETURN_ONE, &result));
480     return result;
481 }
482 
ParseFollowMode(napi_env env,int32_t & param,napi_value args,bool hasExtra)483 napi_value ConfigPolicyNapi::ParseFollowMode(napi_env env, int32_t &param, napi_value args, bool hasExtra)
484 {
485     bool matchFlag = MatchValueType(env, args, napi_number);
486     if (!matchFlag) {
487         return ThrowNapiError(env, PARAM_ERROR, "Parameter error. The type of followMode must be number.");
488     }
489     if (napi_get_value_int32(env, args, &param) != napi_ok) {
490         HiLog::Error(LABEL, "can not get int32 value.");
491         return ThrowNapiError(env, PARAM_ERROR, "Parameter error. Get the value of followMode failed.");
492     }
493 
494     switch (param) {
495         case FOLLOWX_MODE_DEFAULT:
496             [[fallthrough]];
497         case FOLLOWX_MODE_NO_RULE_FOLLOWED:
498             [[fallthrough]];
499         case FOLLOWX_MODE_SIM_DEFAULT:
500             [[fallthrough]];
501         case FOLLOWX_MODE_SIM_1:
502             [[fallthrough]];
503         case FOLLOWX_MODE_SIM_2:
504             break;
505         case FOLLOWX_MODE_USER_DEFINED:
506             if (!hasExtra) {
507                 return ThrowNapiError(env, PARAM_ERROR,
508                     "Parameter error. The followMode is USER_DEFINED, extra must be set.");
509             }
510             break;
511         default:
512             return ThrowNapiError(env, PARAM_ERROR,
513                 "Parameter error. The value of followMode should be in the enumeration value of FollowXMode.");
514     }
515 
516     napi_value result = nullptr;
517     NAPI_CALL(env, napi_create_int32(env, NAPI_RETURN_ONE, &result));
518     return result;
519 }
520 
ThrowNapiError(napi_env env,int32_t errCode,const std::string & errMessage)521 napi_value ConfigPolicyNapi::ThrowNapiError(napi_env env, int32_t errCode, const std::string &errMessage)
522 {
523     napi_throw_error(env, std::to_string(errCode).c_str(), errMessage.c_str());
524     return nullptr;
525 }
526 
ConfigPolicyInit(napi_env env,napi_value exports)527 static napi_value ConfigPolicyInit(napi_env env, napi_value exports)
528 {
529     return ConfigPolicyNapi::Init(env, exports);
530 }
531 
532 static napi_module g_configPolicyModule = {
533     .nm_version = 1,
534     .nm_flags = 0,
535     .nm_filename = nullptr,
536     .nm_register_func = ConfigPolicyInit,
537     .nm_modname = "configPolicy",
538     .nm_priv = ((void *)0),
539     .reserved = { 0 }
540 };
541 
ConfigPolicyRegister()542 extern "C" __attribute__((constructor)) void ConfigPolicyRegister()
543 {
544     napi_module_register(&g_configPolicyModule);
545 }
546 } // namespace ConfigPolicy
547 } // namespace Customization
548 } // namespace OHOS
549