• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #include "napi_data_ability_helper.h"
16 
17 #include <cstring>
18 #include <uv.h>
19 #include <vector>
20 #include <string>
21 
22 #include "data_ability_helper.h"
23 #include "data_ability_observer_interface.h"
24 #include "uri.h"
25 
26 #include "napi_common_ability.h"
27 #include "data_ability_operation.h"
28 #include "data_ability_result.h"
29 #include "hilog_wrapper.h"
30 #include "message_parcel.h"
31 #include "napi_base_context.h"
32 #include "napi_data_ability_operation.h"
33 #include "napi_data_ability_predicates.h"
34 #include "napi_rdb_predicates.h"
35 #include "napi_result_set.h"
36 #include "securec.h"
37 
38 #ifndef SUPPORT_GRAPHICS
39 #define DBL_MIN ((double)2.22507385850720138309e-308L)
40 #define DBL_MAX ((double)2.22507385850720138309e-308L)
41 #endif
42 
43 using namespace OHOS::AAFwk;
44 using namespace OHOS::AppExecFwk;
45 
46 namespace OHOS {
47 namespace AppExecFwk {
48 std::list<std::shared_ptr<DataAbilityHelper>> g_dataAbilityHelperList;
49 std::vector<DAHelperOnOffCB *> g_registerInstances;
50 
51 /**
52  * @brief DataAbilityHelper NAPI module registration.
53  *
54  * @param env The environment that the Node-API call is invoked under.
55  * @param exports An empty object via the exports parameter as a convenience.
56  *
57  * @return The return value from Init is treated as the exports object for the module.
58  */
DataAbilityHelperInit(napi_env env,napi_value exports)59 napi_value DataAbilityHelperInit(napi_env env, napi_value exports)
60 {
61     HILOG_DEBUG("called");
62     napi_property_descriptor properties[] = {
63         DECLARE_NAPI_FUNCTION("insert", NAPI_Insert),
64         DECLARE_NAPI_FUNCTION("notifyChange", NAPI_NotifyChange),
65         DECLARE_NAPI_FUNCTION("on", NAPI_Register),
66         DECLARE_NAPI_FUNCTION("off", NAPI_UnRegister),
67         DECLARE_NAPI_FUNCTION("delete", NAPI_Delete),
68         DECLARE_NAPI_FUNCTION("query", NAPI_Query),
69         DECLARE_NAPI_FUNCTION("update", NAPI_Update),
70         DECLARE_NAPI_FUNCTION("batchInsert", NAPI_BatchInsert),
71         DECLARE_NAPI_FUNCTION("openFile", NAPI_OpenFile),
72         DECLARE_NAPI_FUNCTION("getType", NAPI_GetType),
73         DECLARE_NAPI_FUNCTION("getFileTypes", NAPI_GetFileTypes),
74         DECLARE_NAPI_FUNCTION("normalizeUri", NAPI_NormalizeUri),
75         DECLARE_NAPI_FUNCTION("denormalizeUri", NAPI_DenormalizeUri),
76         DECLARE_NAPI_FUNCTION("executeBatch", NAPI_ExecuteBatch),
77         DECLARE_NAPI_FUNCTION("call", NAPI_Call),
78     };
79 
80     napi_value constructor;
81     NAPI_CALL(env,
82         napi_define_class(env,
83             "dataAbilityHelper",
84             NAPI_AUTO_LENGTH,
85             DataAbilityHelperConstructor,
86             nullptr,
87             sizeof(properties) / sizeof(*properties),
88             properties,
89             &constructor));
90     NAPI_CALL(env, SaveGlobalDataAbilityHelper(env, constructor));
91     return exports;
92 }
93 
DataAbilityHelperConstructor(napi_env env,napi_callback_info info)94 napi_value DataAbilityHelperConstructor(napi_env env, napi_callback_info info)
95 {
96     size_t argc = ARGS_TWO;
97     napi_value argv[ARGS_TWO] = {nullptr};
98     napi_value thisVar = nullptr;
99     auto& dataAbilityHelperStatus = GetDataAbilityHelperStatus();
100     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
101     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments");
102 
103     std::shared_ptr<DataAbilityHelper> dataAbilityHelper = nullptr;
104     bool stageMode = false;
105     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, argv[0], stageMode);
106     if (status != napi_ok) {
107         auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
108         if (ability == nullptr) {
109             HILOG_ERROR("Failed to get native context instance");
110             return nullptr;
111         }
112         std::string strUri = NapiValueToStringUtf8(env, argv[0]);
113         HILOG_INFO("FA Model: strUri = %{public}s", strUri.c_str());
114         dataAbilityHelper = DataAbilityHelper::Creator(ability->GetContext(), std::make_shared<Uri>(strUri));
115     } else {
116         if (stageMode) {
117             auto context = OHOS::AbilityRuntime::GetStageModeContext(env, argv[0]);
118             if (context == nullptr) {
119                 HILOG_ERROR("Failed to get native context instance");
120                 return nullptr;
121             }
122             std::string strUri = NapiValueToStringUtf8(env, argv[PARAM1]);
123             HILOG_INFO("Stage Model: strUri = %{public}s", strUri.c_str());
124             dataAbilityHelper = DataAbilityHelper::Creator(context, std::make_shared<Uri>(strUri));
125         } else {
126             auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
127             if (ability == nullptr) {
128                 HILOG_ERROR("Failed to get native context instance");
129                 return nullptr;
130             }
131             std::string strUri = NapiValueToStringUtf8(env, argv[PARAM1]);
132             HILOG_INFO("FA Model: strUri = %{public}s", strUri.c_str());
133             dataAbilityHelper = DataAbilityHelper::Creator(ability->GetContext(), std::make_shared<Uri>(strUri));
134         }
135     }
136 
137     if (dataAbilityHelper == nullptr) {
138         HILOG_ERROR("dataAbilityHelper is nullptr");
139         dataAbilityHelperStatus = false;
140         return nullptr;
141     }
142     dataAbilityHelper->SetCallFromJs();
143     g_dataAbilityHelperList.emplace_back(dataAbilityHelper);
144     auto wrapper = new NAPIDataAbilityHelperWrapper(dataAbilityHelper);
145 
146     napi_wrap(
147         env,
148         thisVar,
149         wrapper,
150         [](napi_env env, void *data, void *hint) {
151             auto objectInfo = static_cast<NAPIDataAbilityHelperWrapper *>(data);
152             if (objectInfo == nullptr) {
153                 HILOG_WARN("DAHelper finalize_cb objectInfo is nullptr.");
154                 return;
155             }
156             HILOG_DEBUG("DAHelper finalize_cb dataAbilityHelperList.size = %{public}zu, "
157                 "regInstances_.size = %{public}zu",
158                 g_dataAbilityHelperList.size(), g_registerInstances.size());
159             for (auto iter = g_registerInstances.begin(); iter != g_registerInstances.end();) {
160                 if (!NeedErase(iter, objectInfo->GetDataAbilityHelper())) {
161                     iter = g_registerInstances.erase(iter);
162                 }
163             }
164             g_dataAbilityHelperList.remove_if(
165                 [objectInfo](const std::shared_ptr<DataAbilityHelper> &dataAbilityHelper) {
166                     return objectInfo->GetDataAbilityHelper() == dataAbilityHelper;
167                 });
168             HILOG_DEBUG("dataAbilityHelperList.size = %{public}zu, regInstances_.size = %{public}zu",
169                 g_dataAbilityHelperList.size(), g_registerInstances.size());
170             delete objectInfo;
171             objectInfo = nullptr;
172         },
173         nullptr,
174         nullptr);
175 
176     dataAbilityHelperStatus = true;
177     return thisVar;
178 }
179 
180 /**
181  * @brief DataAbilityHelper NAPI method : insert.
182  *
183  * @param env The environment that the Node-API call is invoked under.
184  * @param info The callback info passed into the callback function.
185  *
186  * @return The return value from NAPI C++ to JS for the module.
187  */
NAPI_Insert(napi_env env,napi_callback_info info)188 napi_value NAPI_Insert(napi_env env, napi_callback_info info)
189 {
190     HILOG_INFO("%{public}s,called", __func__);
191     DAHelperInsertCB *insertCB = new (std::nothrow) DAHelperInsertCB;
192     if (insertCB == nullptr) {
193         HILOG_ERROR("%{public}s, insertCB == nullptr.", __func__);
194         return WrapVoidToJS(env);
195     }
196     insertCB->cbBase.cbInfo.env = env;
197     insertCB->cbBase.asyncWork = nullptr;
198     insertCB->cbBase.deferred = nullptr;
199     insertCB->cbBase.ability = nullptr;
200 
201     napi_value ret = InsertWrap(env, info, insertCB);
202     if (ret == nullptr) {
203         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
204         delete insertCB;
205         insertCB = nullptr;
206         ret = WrapVoidToJS(env);
207     }
208     HILOG_INFO("%{public}s,called end", __func__);
209     return ret;
210 }
211 
212 /**
213  * @brief Insert processing function.
214  *
215  * @param env The environment that the Node-API call is invoked under.
216  * @param insertCB Process data asynchronously.
217  *
218  * @return Return JS data successfully, otherwise return nullptr.
219  */
InsertWrap(napi_env env,napi_callback_info info,DAHelperInsertCB * insertCB)220 napi_value InsertWrap(napi_env env, napi_callback_info info, DAHelperInsertCB *insertCB)
221 {
222     HILOG_INFO("%{public}s,called", __func__);
223     size_t argcAsync = ARGS_THREE;
224     const size_t argcPromise = ARGS_TWO;
225     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
226     napi_value args[ARGS_MAX_COUNT] = {nullptr};
227     napi_value ret = nullptr;
228     napi_value thisVar = nullptr;
229 
230     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
231     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
232         HILOG_ERROR("%{public}s, Wrong parameter count.", __func__);
233         return nullptr;
234     }
235 
236     napi_valuetype valuetype = napi_undefined;
237     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
238     if (valuetype == napi_string) {
239         insertCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
240         HILOG_INFO("%{public}s,uri=%{public}s", __func__, insertCB->uri.c_str());
241     } else {
242         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
243     }
244 
245     insertCB->valueBucket.Clear();
246     AnalysisValuesBucket(insertCB->valueBucket, env, args[PARAM1]);
247     GetDataAbilityHelper(env, thisVar, insertCB->dataAbilityHelper);
248 
249     if (argcAsync > argcPromise) {
250         ret = InsertAsync(env, args, ARGS_TWO, insertCB);
251     } else {
252         ret = InsertPromise(env, insertCB);
253     }
254     HILOG_INFO("%{public}s,end", __func__);
255     return ret;
256 }
257 
AnalysisValuesBucket(NativeRdb::ValuesBucket & valuesBucket,const napi_env & env,const napi_value & arg)258 void AnalysisValuesBucket(NativeRdb::ValuesBucket &valuesBucket, const napi_env &env, const napi_value &arg)
259 {
260     napi_value keys = nullptr;
261     napi_get_property_names(env, arg, &keys);
262     uint32_t arrLen = 0;
263     napi_status status = napi_get_array_length(env, keys, &arrLen);
264     if (status != napi_ok) {
265         HILOG_ERROR("ValuesBucket errr");
266         return;
267     }
268     HILOG_INFO("ValuesBucket num:%{public}d ", arrLen);
269     for (size_t i = 0; i < arrLen; ++i) {
270         napi_value key = nullptr;
271         (void)napi_get_element(env, keys, i, &key);
272         std::string keyStr = UnwrapStringFromJS(env, key);
273         napi_value value = nullptr;
274         napi_get_property(env, arg, key, &value);
275 
276         SetValuesBucketObject(valuesBucket, env, keyStr, value);
277     }
278 }
279 
SetValuesBucketObject(NativeRdb::ValuesBucket & valuesBucket,const napi_env & env,std::string keyStr,napi_value value)280 void SetValuesBucketObject(
281     NativeRdb::ValuesBucket &valuesBucket, const napi_env &env, std::string keyStr, napi_value value)
282 {
283     napi_valuetype valueType = napi_undefined;
284     napi_typeof(env, value, &valueType);
285     if (valueType == napi_string) {
286         std::string valueString = UnwrapStringFromJS(env, value);
287         HILOG_INFO("ValueObject type:%{public}d, key:%{public}s, value:%{private}s",
288             valueType,
289             keyStr.c_str(),
290             valueString.c_str());
291         valuesBucket.PutString(keyStr, valueString);
292     } else if (valueType == napi_number) {
293         double valueNumber = 0;
294         napi_get_value_double(env, value, &valueNumber);
295         valuesBucket.PutDouble(keyStr, valueNumber);
296         HILOG_INFO(
297             "ValueObject type:%{public}d, key:%{public}s, value:%{private}lf", valueType, keyStr.c_str(), valueNumber);
298     } else if (valueType == napi_boolean) {
299         bool valueBool = false;
300         napi_get_value_bool(env, value, &valueBool);
301         HILOG_INFO(
302             "ValueObject type:%{public}d, key:%{public}s, value:%{private}d", valueType, keyStr.c_str(), valueBool);
303         valuesBucket.PutBool(keyStr, valueBool);
304     } else if (valueType == napi_null) {
305         valuesBucket.PutNull(keyStr);
306         HILOG_INFO("ValueObject type:%{public}d, key:%{public}s, value:null", valueType, keyStr.c_str());
307     } else if (valueType == napi_object) {
308         HILOG_INFO("ValueObject type:%{public}d, key:%{public}s, value:Uint8Array", valueType, keyStr.c_str());
309         valuesBucket.PutBlob(keyStr, ConvertU8Vector(env, value));
310     } else {
311         HILOG_ERROR("valuesBucket error");
312     }
313 }
InsertAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperInsertCB * insertCB)314 napi_value InsertAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperInsertCB *insertCB)
315 {
316     HILOG_INFO("%{public}s, asyncCallback.", __func__);
317     if (args == nullptr || insertCB == nullptr) {
318         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
319         return nullptr;
320     }
321     napi_value resourceName = nullptr;
322     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
323 
324     napi_valuetype valuetype = napi_undefined;
325     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
326     if (valuetype == napi_function) {
327         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &insertCB->cbBase.cbInfo.callback));
328     }
329 
330     NAPI_CALL(env,
331         napi_create_async_work(env,
332             nullptr,
333             resourceName,
334             InsertExecuteCB,
335             InsertAsyncCompleteCB,
336             static_cast<void *>(insertCB),
337             &insertCB->cbBase.asyncWork));
338     NAPI_CALL(env, napi_queue_async_work_with_qos(env, insertCB->cbBase.asyncWork, napi_qos_user_initiated));
339     napi_value result = nullptr;
340     NAPI_CALL(env, napi_get_null(env, &result));
341     HILOG_INFO("%{public}s, asyncCallback end", __func__);
342     return result;
343 }
344 
InsertPromise(napi_env env,DAHelperInsertCB * insertCB)345 napi_value InsertPromise(napi_env env, DAHelperInsertCB *insertCB)
346 {
347     HILOG_INFO("%{public}s, promise.", __func__);
348     if (insertCB == nullptr) {
349         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
350         return nullptr;
351     }
352     napi_value resourceName;
353     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
354     napi_deferred deferred;
355     napi_value promise = nullptr;
356     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
357     insertCB->cbBase.deferred = deferred;
358 
359     NAPI_CALL(env,
360         napi_create_async_work(env,
361             nullptr,
362             resourceName,
363             InsertExecuteCB,
364             InsertPromiseCompleteCB,
365             static_cast<void *>(insertCB),
366             &insertCB->cbBase.asyncWork));
367     NAPI_CALL(env, napi_queue_async_work_with_qos(env, insertCB->cbBase.asyncWork, napi_qos_user_initiated));
368     HILOG_INFO("%{public}s, promise end", __func__);
369     return promise;
370 }
371 
InsertExecuteCB(napi_env env,void * data)372 void InsertExecuteCB(napi_env env, void *data)
373 {
374     HILOG_INFO("NAPI_Insert, worker pool thread execute.");
375     DAHelperInsertCB *insertCB = static_cast<DAHelperInsertCB *>(data);
376     if (insertCB == nullptr) {
377         HILOG_WARN("NAPI_Insert, insertCB is nullptr.");
378         return;
379     }
380     auto dataAbilityHelper = insertCB->dataAbilityHelper;
381     if (dataAbilityHelper != nullptr) {
382         insertCB->execResult = INVALID_PARAMETER;
383         if (!insertCB->uri.empty()) {
384             OHOS::Uri uri(insertCB->uri);
385             insertCB->result = dataAbilityHelper->Insert(uri, insertCB->valueBucket);
386             insertCB->execResult = NO_ERROR;
387         }
388     } else {
389         HILOG_ERROR("NAPI_Insert, dataAbilityHelper == nullptr.");
390     }
391     HILOG_INFO("NAPI_Insert, worker pool thread execute end.");
392 }
393 
InsertAsyncCompleteCB(napi_env env,napi_status status,void * data)394 void InsertAsyncCompleteCB(napi_env env, napi_status status, void *data)
395 {
396     HILOG_INFO("NAPI_Insert, main event thread complete.");
397     DAHelperInsertCB *insertCB = static_cast<DAHelperInsertCB *>(data);
398     napi_value callback = nullptr;
399     napi_value undefined = nullptr;
400     napi_value result[ARGS_TWO] = {nullptr};
401     napi_value callResult = nullptr;
402     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
403     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, insertCB->cbBase.cbInfo.callback, &callback));
404 
405     result[PARAM0] = GetCallbackErrorValue(env, insertCB->execResult);
406     napi_create_int32(env, insertCB->result, &result[PARAM1]);
407     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
408 
409     if (insertCB->cbBase.cbInfo.callback != nullptr) {
410         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, insertCB->cbBase.cbInfo.callback));
411     }
412     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, insertCB->cbBase.asyncWork));
413     delete insertCB;
414     insertCB = nullptr;
415     HILOG_INFO("NAPI_Insert, main event thread complete end.");
416 }
417 
InsertPromiseCompleteCB(napi_env env,napi_status status,void * data)418 void InsertPromiseCompleteCB(napi_env env, napi_status status, void *data)
419 {
420     HILOG_INFO("NAPI_Insert,  main event thread complete.");
421     DAHelperInsertCB *insertCB = static_cast<DAHelperInsertCB *>(data);
422     napi_value result = nullptr;
423     napi_create_int32(env, insertCB->result, &result);
424     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, insertCB->cbBase.deferred, result));
425     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, insertCB->cbBase.asyncWork));
426     delete insertCB;
427     insertCB = nullptr;
428     HILOG_INFO("NAPI_Insert,  main event thread complete end.");
429 }
430 
431 /**
432  * @brief Parse the ValuesBucket parameters.
433  *
434  * @param param Indicates the want parameters saved the parse result.
435  * @param env The environment that the Node-API call is invoked under.
436  * @param args Indicates the arguments passed into the callback.
437  *
438  * @return The return value from NAPI C++ to JS for the module.
439  */
UnwrapValuesBucket(std::string & value,napi_env env,napi_value args)440 napi_value UnwrapValuesBucket(std::string &value, napi_env env, napi_value args)
441 {
442     HILOG_INFO("%{public}s,called", __func__);
443     napi_valuetype valueType = napi_undefined;
444     napi_typeof(env, args, &valueType);
445     if (valueType != napi_object) {
446         HILOG_ERROR("%{public}s, valueType != napi_object.", __func__);
447         return nullptr;
448     }
449 
450     std::string strValue = "";
451     if (UnwrapStringByPropertyName(env, args, "value", strValue)) {
452         HILOG_INFO("%{public}s,strValue=%{private}s", __func__, strValue.c_str());
453         value = strValue;
454     } else {
455         HILOG_ERROR("%{public}s, value == nullptr.", __func__);
456         return nullptr;
457     }
458 
459     napi_value result;
460     NAPI_CALL(env, napi_create_int32(env, 1, &result));
461     HILOG_INFO("%{public}s,end", __func__);
462     return result;
463 }
464 
465 /**
466  * @brief DataAbilityHelper NAPI method : notifyChange.
467  *
468  * @param env The environment that the Node-API call is invoked under.
469  * @param info The callback info passed into the callback function.
470  *
471  * @return The return value from NAPI C++ to JS for the module.
472  */
NAPI_NotifyChange(napi_env env,napi_callback_info info)473 napi_value NAPI_NotifyChange(napi_env env, napi_callback_info info)
474 {
475     HILOG_INFO("%{public}s,called", __func__);
476     DAHelperNotifyChangeCB *notifyChangeCB = new DAHelperNotifyChangeCB;
477     notifyChangeCB->cbBase.cbInfo.env = env;
478     notifyChangeCB->cbBase.asyncWork = nullptr;
479     notifyChangeCB->cbBase.deferred = nullptr;
480     notifyChangeCB->cbBase.ability = nullptr;
481 
482     napi_value ret = NotifyChangeWrap(env, info, notifyChangeCB);
483     if (ret == nullptr) {
484         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
485         delete notifyChangeCB;
486         notifyChangeCB = nullptr;
487         ret = WrapVoidToJS(env);
488     }
489     HILOG_INFO("%{public}s,end", __func__);
490     return ret;
491 }
492 
493 /**
494  * @brief NotifyChange processing function.
495  *
496  * @param env The environment that the Node-API call is invoked under.
497  * @param notifyChangeCB Process data asynchronously.
498  *
499  * @return Return JS data successfully, otherwise return nullptr.
500  */
NotifyChangeWrap(napi_env env,napi_callback_info info,DAHelperNotifyChangeCB * notifyChangeCB)501 napi_value NotifyChangeWrap(napi_env env, napi_callback_info info, DAHelperNotifyChangeCB *notifyChangeCB)
502 {
503     HILOG_INFO("%{public}s,called", __func__);
504     size_t argcAsync = ARGS_TWO;
505     const size_t argcPromise = ARGS_ONE;
506     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
507     napi_value args[ARGS_MAX_COUNT] = {nullptr};
508     napi_value ret = nullptr;
509     napi_value thisVar = nullptr;
510 
511     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
512     if (argcAsync > argCountWithAsync) {
513         HILOG_ERROR("%{public}s, Wrong parameter count.", __func__);
514         return nullptr;
515     }
516 
517     napi_valuetype valuetype = napi_undefined;
518     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
519     if (valuetype == napi_string) {
520         notifyChangeCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
521         HILOG_INFO("%{public}s,uri=%{public}s", __func__, notifyChangeCB->uri.c_str());
522     }
523     GetDataAbilityHelper(env, thisVar, notifyChangeCB->dataAbilityHelper);
524 
525     if (argcAsync > argcPromise) {
526         ret = NotifyChangeAsync(env, args, argcAsync, argcPromise, notifyChangeCB);
527     } else {
528         ret = NotifyChangePromise(env, notifyChangeCB);
529     }
530     return ret;
531 }
532 
NotifyChangeAsync(napi_env env,napi_value * args,size_t argcAsync,const size_t argcPromise,DAHelperNotifyChangeCB * notifyChangeCB)533 napi_value NotifyChangeAsync(
534     napi_env env, napi_value *args, size_t argcAsync, const size_t argcPromise, DAHelperNotifyChangeCB *notifyChangeCB)
535 {
536     HILOG_INFO("%{public}s, asyncCallback.", __func__);
537     if (args == nullptr || notifyChangeCB == nullptr) {
538         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
539         return nullptr;
540     }
541     napi_value resourceName = nullptr;
542     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
543 
544     napi_valuetype valuetype = napi_undefined;
545     NAPI_CALL(env, napi_typeof(env, args[argcPromise], &valuetype));
546     if (valuetype == napi_function) {
547         NAPI_CALL(env, napi_create_reference(env, args[argcPromise], 1, &notifyChangeCB->cbBase.cbInfo.callback));
548     }
549 
550     NAPI_CALL(env,
551         napi_create_async_work(env,
552             nullptr,
553             resourceName,
554             NotifyChangeExecuteCB,
555             NotifyChangeAsyncCompleteCB,
556             static_cast<void *>(notifyChangeCB),
557             &notifyChangeCB->cbBase.asyncWork));
558     NAPI_CALL(env, napi_queue_async_work(env, notifyChangeCB->cbBase.asyncWork));
559     napi_value result = nullptr;
560     NAPI_CALL(env, napi_get_null(env, &result));
561     return result;
562 }
563 
NotifyChangePromise(napi_env env,DAHelperNotifyChangeCB * notifyChangeCB)564 napi_value NotifyChangePromise(napi_env env, DAHelperNotifyChangeCB *notifyChangeCB)
565 {
566     HILOG_INFO("%{public}s, promise.", __func__);
567     if (notifyChangeCB == nullptr) {
568         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
569         return nullptr;
570     }
571     napi_value resourceName;
572     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
573     napi_deferred deferred;
574     napi_value promise = nullptr;
575     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
576     notifyChangeCB->cbBase.deferred = deferred;
577 
578     NAPI_CALL(env,
579         napi_create_async_work(env,
580             nullptr,
581             resourceName,
582             NotifyChangeExecuteCB,
583             NotifyChangePromiseCompleteCB,
584             static_cast<void *>(notifyChangeCB),
585             &notifyChangeCB->cbBase.asyncWork));
586     NAPI_CALL(env, napi_queue_async_work(env, notifyChangeCB->cbBase.asyncWork));
587     return promise;
588 }
589 
NotifyChangeExecuteCB(napi_env env,void * data)590 void NotifyChangeExecuteCB(napi_env env, void *data)
591 {
592     HILOG_INFO("NAPI_NotifyChange, worker pool thread execute.");
593     DAHelperNotifyChangeCB *notifyChangeCB = static_cast<DAHelperNotifyChangeCB *>(data);
594     auto dataAbilityHelper = notifyChangeCB->dataAbilityHelper;
595     if (dataAbilityHelper != nullptr) {
596         notifyChangeCB->execResult = INVALID_PARAMETER;
597         if (!notifyChangeCB->uri.empty()) {
598             OHOS::Uri uri(notifyChangeCB->uri);
599             dataAbilityHelper->NotifyChange(uri);
600             notifyChangeCB->execResult = NO_ERROR;
601         } else {
602             HILOG_ERROR("%{public}s, notifyChangeCB uri is empty.", __func__);
603         }
604     }
605 }
606 
NotifyChangeAsyncCompleteCB(napi_env env,napi_status status,void * data)607 void NotifyChangeAsyncCompleteCB(napi_env env, napi_status status, void *data)
608 {
609     HILOG_INFO("NAPI_NotifyChange, main event thread complete.");
610     DAHelperNotifyChangeCB *notifyChangeCB = static_cast<DAHelperNotifyChangeCB *>(data);
611     napi_value callback = nullptr;
612     napi_value undefined = nullptr;
613     napi_value result[ARGS_TWO] = {nullptr};
614     napi_value callResult = nullptr;
615     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
616     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, notifyChangeCB->cbBase.cbInfo.callback, &callback));
617 
618     if (!IsTypeForNapiValue(env, callback, napi_function)) {
619         delete notifyChangeCB;
620         notifyChangeCB = nullptr;
621         HILOG_INFO("NAPI_NotifyChange, callback is invalid.");
622         return;
623     }
624 
625     result[PARAM0] = GetCallbackErrorValue(env, notifyChangeCB->execResult);
626     result[PARAM1] = WrapVoidToJS(env);
627     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
628 
629     if (notifyChangeCB->cbBase.cbInfo.callback != nullptr) {
630         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, notifyChangeCB->cbBase.cbInfo.callback));
631     }
632     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, notifyChangeCB->cbBase.asyncWork));
633     delete notifyChangeCB;
634     notifyChangeCB = nullptr;
635 }
636 
NotifyChangePromiseCompleteCB(napi_env env,napi_status status,void * data)637 void NotifyChangePromiseCompleteCB(napi_env env, napi_status status, void *data)
638 {
639     HILOG_INFO("NAPI_NotifyChange,  main event thread complete.");
640     DAHelperNotifyChangeCB *notifyChangeCB = static_cast<DAHelperNotifyChangeCB *>(data);
641     napi_value result = nullptr;
642     napi_create_int32(env, 0, &result);
643     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, notifyChangeCB->cbBase.deferred, result));
644     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, notifyChangeCB->cbBase.asyncWork));
645     delete notifyChangeCB;
646     notifyChangeCB = nullptr;
647 }
648 
649 /**
650  * @brief DataAbilityHelper NAPI method : on.
651  *
652  * @param env The environment that the Node-API call is invoked under.
653  * @param info The callback info passed into the callback function.
654  *
655  * @return The return value from NAPI C++ to JS for the module.
656  */
NAPI_Register(napi_env env,napi_callback_info info)657 napi_value NAPI_Register(napi_env env, napi_callback_info info)
658 {
659     HILOG_INFO("%{public}s,called", __func__);
660     DAHelperOnOffCB *onCB = new DAHelperOnOffCB;
661     onCB->cbBase.cbInfo.env = env;
662     onCB->cbBase.asyncWork = nullptr;
663     onCB->cbBase.deferred = nullptr;
664     onCB->cbBase.ability = nullptr;
665 
666     napi_value ret = RegisterWrap(env, info, onCB);
667     if (ret == nullptr) {
668         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
669         delete onCB;
670         onCB = nullptr;
671         ret = WrapVoidToJS(env);
672     }
673     HILOG_INFO("%{public}s,called end", __func__);
674     return ret;
675 }
676 
677 /**
678  * @brief On processing function.
679  *
680  * @param env The environment that the Node-API call is invoked under.
681  * @param onCB Process data asynchronously.
682  *
683  * @return Return JS data successfully, otherwise return nullptr.
684  */
RegisterWrap(napi_env env,napi_callback_info info,DAHelperOnOffCB * onCB)685 napi_value RegisterWrap(napi_env env, napi_callback_info info, DAHelperOnOffCB *onCB)
686 {
687     HILOG_INFO("%{public}s,start", __func__);
688     size_t argcAsync = ARGS_THREE;
689     const size_t argcPromise = ARGS_TWO;
690     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
691     napi_value args[ARGS_MAX_COUNT] = {nullptr};
692     napi_value ret = nullptr;
693     napi_value thisVar = nullptr;
694 
695     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
696     if (argcAsync > argCountWithAsync) {
697         HILOG_ERROR("%{public}s, Wrong parameter count.", __func__);
698         return nullptr;
699     }
700 
701     onCB->result = NO_ERROR;
702     napi_valuetype valuetype = napi_undefined;
703     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
704     if (valuetype == napi_string) {
705         std::string type = NapiValueToStringUtf8(env, args[PARAM0]);
706         if (type == "dataChange") {
707             HILOG_INFO("%{public}s, Right type=%{public}s", __func__, type.c_str());
708         } else {
709             HILOG_ERROR("%{public}s, Wrong argument type is %{public}s.", __func__, type.c_str());
710             onCB->result = INVALID_PARAMETER;
711         }
712     } else {
713         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
714         onCB->result = INVALID_PARAMETER;
715     }
716 
717     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
718     if (valuetype == napi_string) {
719         onCB->uri = NapiValueToStringUtf8(env, args[PARAM1]);
720         HILOG_INFO("%{public}s,uri=%{public}s", __func__, onCB->uri.c_str());
721     } else {
722         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
723         onCB->result = INVALID_PARAMETER;
724     }
725     GetDataAbilityHelper(env, thisVar, onCB->dataAbilityHelper);
726 
727     ret = RegisterAsync(env, args, argcAsync, argcPromise, onCB);
728     return ret;
729 }
730 
RegisterAsync(napi_env env,napi_value * args,size_t argcAsync,const size_t argcPromise,DAHelperOnOffCB * onCB)731 napi_value RegisterAsync(
732     napi_env env, napi_value *args, size_t argcAsync, const size_t argcPromise, DAHelperOnOffCB *onCB)
733 {
734     HILOG_INFO("%{public}s, asyncCallback.", __func__);
735     if (args == nullptr || onCB == nullptr) {
736         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
737         return nullptr;
738     }
739     napi_value resourceName = nullptr;
740     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
741 
742     napi_valuetype valuetype = napi_undefined;
743     NAPI_CALL(env, napi_typeof(env, args[argcPromise], &valuetype));
744     if (valuetype == napi_function) {
745         HILOG_INFO("valuetype is napi_function");
746         NAPI_CALL(env, napi_create_reference(env, args[argcPromise], 1, &onCB->cbBase.cbInfo.callback));
747     } else {
748         HILOG_INFO("not valuetype isn't napi_function");
749         onCB->result = INVALID_PARAMETER;
750     }
751 
752     sptr<NAPIDataAbilityObserver> observer(new NAPIDataAbilityObserver());
753     observer->SetEnv(env);
754     observer->SetCallbackRef(onCB->cbBase.cbInfo.callback);
755     onCB->observer = observer;
756 
757     if (onCB->result == NO_ERROR) {
758         g_registerInstances.emplace_back(onCB);
759     }
760 
761     NAPI_CALL(env,
762         napi_create_async_work(
763             env,
764             nullptr,
765             resourceName,
766             RegisterExecuteCB,
767             RegisterCompleteCB,
768             static_cast<void *>(onCB),
769             &onCB->cbBase.asyncWork));
770     NAPI_CALL(env, napi_queue_async_work(env, onCB->cbBase.asyncWork));
771     napi_value result = nullptr;
772     NAPI_CALL(env, napi_get_null(env, &result));
773     return result;
774 }
775 
RegisterExecuteCB(napi_env env,void * data)776 void RegisterExecuteCB(napi_env env, void *data)
777 {
778     HILOG_INFO("NAPI_Register, worker pool thread execute.");
779     DAHelperOnOffCB *onCB = static_cast<DAHelperOnOffCB *>(data);
780     auto onCBIter = std::find(g_registerInstances.begin(), g_registerInstances.end(), onCB);
781     if (onCBIter == g_registerInstances.end()) {
782         // onCB is invalid or onCB has been delete
783         HILOG_ERROR("%{public}s, input params onCB is invalid.", __func__);
784         return;
785     }
786 
787     auto dataAbilityHelper = onCB->dataAbilityHelper;
788     if (dataAbilityHelper != nullptr) {
789         if (onCB->result != INVALID_PARAMETER && !onCB->uri.empty() && onCB->cbBase.cbInfo.callback != nullptr) {
790             OHOS::Uri uri(onCB->uri);
791             dataAbilityHelper->RegisterObserver(uri, onCB->observer);
792         } else {
793             HILOG_ERROR("%{public}s, dataAbilityHelper uri is empty or callback is nullptr.", __func__);
794         }
795     }
796 }
797 
RegisterCompleteCB(napi_env env,napi_status status,void * data)798 void RegisterCompleteCB(napi_env env, napi_status status, void *data)
799 {
800     HILOG_INFO("NAPI_Register, main event thread complete.");
801     DAHelperOnOffCB *onCB = static_cast<DAHelperOnOffCB *>(data);
802     if (onCB == nullptr) {
803         HILOG_ERROR("%{public}s, input params onCB is nullptr.", __func__);
804         return;
805     }
806 
807     auto onCBIter = std::find(g_registerInstances.begin(), g_registerInstances.end(), onCB);
808     if (onCBIter == g_registerInstances.end()) {
809         // onCB is invalid or onCB has been delete
810         HILOG_ERROR("%{public}s, input params onCB is invalid.", __func__);
811         return;
812     }
813 
814     if (onCB->result == NO_ERROR) {
815         return;
816     }
817     HILOG_INFO("NAPI_Register, input params onCB will be release");
818     DeleteDAHelperOnOffCB(onCB);
819     HILOG_INFO("NAPI_Register, main event thread complete over an release invalid onCB.");
820 }
821 
822 /**
823  * @brief DataAbilityHelper NAPI method : Off.
824  *
825  * @param env The environment that the Node-API call is invoked under.
826  * @param info The callback info passed into the callback function.
827  *
828  * @return The return value from NAPI C++ to JS for the module.
829  */
NAPI_UnRegister(napi_env env,napi_callback_info info)830 napi_value NAPI_UnRegister(napi_env env, napi_callback_info info)
831 {
832     HILOG_INFO("%{public}s,called", __func__);
833     DAHelperOnOffCB *offCB = new DAHelperOnOffCB;
834     offCB->cbBase.cbInfo.env = env;
835     offCB->cbBase.asyncWork = nullptr;
836     offCB->cbBase.deferred = nullptr;
837     offCB->cbBase.ability = nullptr;
838 
839     napi_value ret = UnRegisterWrap(env, info, offCB);
840     if (ret == nullptr) {
841         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
842         delete offCB;
843         offCB = nullptr;
844         ret = WrapVoidToJS(env);
845     }
846     HILOG_INFO("%{public}s,called end", __func__);
847     return ret;
848 }
849 
850 /**
851  * @brief Off processing function.
852  *
853  * @param env The environment that the Node-API call is invoked under.
854  * @param offCB Process data asynchronously.
855  *
856  * @return Return JS data successfully, otherwise return nullptr.
857  */
UnRegisterWrap(napi_env env,napi_callback_info info,DAHelperOnOffCB * offCB)858 napi_value UnRegisterWrap(napi_env env, napi_callback_info info, DAHelperOnOffCB *offCB)
859 {
860     HILOG_INFO("%{public}s,called", __func__);
861     size_t argcAsync = ARGS_THREE;
862     const size_t argCountWithAsync = ARGS_TWO + ARGS_ASYNC_COUNT;
863     napi_value args[ARGS_MAX_COUNT] = {nullptr};
864     napi_value ret = nullptr;
865     napi_value thisVar = nullptr;
866 
867     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
868     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
869         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
870         return nullptr;
871     }
872 
873     offCB->result = NO_ERROR;
874     napi_valuetype valuetype = napi_undefined;
875     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
876     if (valuetype == napi_string) {
877         std::string type = NapiValueToStringUtf8(env, args[PARAM0]);
878         if (type == "dataChange") {
879             HILOG_INFO("%{public}s, Wrong type=%{public}s", __func__, type.c_str());
880         } else {
881             HILOG_ERROR("%{public}s, Wrong argument type %{public}s.", __func__, type.c_str());
882             offCB->result = INVALID_PARAMETER;
883         }
884     } else {
885         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
886         offCB->result = INVALID_PARAMETER;
887     }
888 
889     offCB->uri = "";
890     if (argcAsync > ARGS_TWO) {
891         // parse uri and callback
892         NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
893         if (valuetype == napi_string) {
894             offCB->uri = NapiValueToStringUtf8(env, args[PARAM1]);
895             HILOG_INFO("%{public}s,uri=%{public}s", __func__, offCB->uri.c_str());
896         } else {
897             HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
898             offCB->result = INVALID_PARAMETER;
899         }
900         NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valuetype));
901         if (valuetype == napi_function) {
902             NAPI_CALL(env, napi_create_reference(env, args[PARAM2], 1, &offCB->cbBase.cbInfo.callback));
903         } else {
904             HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
905             offCB->result = INVALID_PARAMETER;
906         }
907     } else {
908         // parse uri or callback
909         NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
910         if (valuetype == napi_string) {
911             offCB->uri = NapiValueToStringUtf8(env, args[PARAM1]);
912             HILOG_INFO("%{public}s,uri=%{public}s", __func__, offCB->uri.c_str());
913         } else if (valuetype == napi_function) {
914             NAPI_CALL(env, napi_create_reference(env, args[PARAM1], 1, &offCB->cbBase.cbInfo.callback));
915         } else {
916             HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
917             offCB->result = INVALID_PARAMETER;
918         }
919     }
920     GetDataAbilityHelper(env, thisVar, offCB->dataAbilityHelper);
921 
922     ret = UnRegisterSync(env, offCB);
923     return ret;
924 }
925 
UnRegisterSync(napi_env env,DAHelperOnOffCB * offCB)926 napi_value UnRegisterSync(napi_env env, DAHelperOnOffCB *offCB)
927 {
928     HILOG_INFO("%{public}s, syncCallback.", __func__);
929     if (offCB == nullptr) {
930         HILOG_ERROR("%{public}s, offCB == nullptr.", __func__);
931         return nullptr;
932     }
933     napi_value resourceName = nullptr;
934     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
935 
936     if (offCB->result == NO_ERROR) {
937         FindRegisterObs(env, offCB);
938     }
939 
940     HILOG_INFO("NAPI_UnRegister, offCB->NotifyList size is %{public}zu", offCB->NotifyList.size());
941     for (auto &iter : offCB->NotifyList) {
942         if (iter != nullptr && iter->observer != nullptr) {
943             OHOS::Uri uri(iter->uri);
944             auto dataAbilityHelper = iter->dataAbilityHelper;
945             if (dataAbilityHelper != nullptr) {
946                 dataAbilityHelper->UnregisterObserver(uri, iter->observer);
947             }
948             offCB->DestroyList.emplace_back(iter);
949         }
950     }
951     offCB->NotifyList.clear();
952 
953     HILOG_INFO("NAPI_UnRegister, offCB->DestroyList size is %{public}zu", offCB->DestroyList.size());
954     for (auto &iter : offCB->DestroyList) {
955         HILOG_INFO("NAPI_UnRegister ReleaseJSCallback. 1 ---");
956         if (iter->observer != nullptr) {
957             iter->observer->ReleaseJSCallback();
958             delete iter;
959             iter = nullptr;
960             HILOG_INFO("NAPI_UnRegister ReleaseJSCallback. 2 ---");
961         }
962     }
963 
964     offCB->DestroyList.clear();
965     delete offCB;
966     offCB = nullptr;
967     napi_value result = nullptr;
968     NAPI_CALL(env, napi_get_null(env, &result));
969     return result;
970 }
971 
FindRegisterObs(napi_env env,DAHelperOnOffCB * data)972 void FindRegisterObs(napi_env env, DAHelperOnOffCB *data)
973 {
974     HILOG_INFO("NAPI_UnRegister, FindRegisterObs main event thread execute.");
975     if (data == nullptr || data->dataAbilityHelper == nullptr) {
976         HILOG_ERROR("NAPI_UnRegister, param is null.");
977         return;
978     }
979 
980     HILOG_INFO("NAPI_UnRegister, uri=%{public}s.", data->uri.c_str());
981     if (!data->uri.empty()) {
982         // if match uri, unregister all observers corresponding the uri
983         std::string strUri = data->uri;
984         auto iter = g_registerInstances.begin();
985         while (iter != g_registerInstances.end()) {
986             DAHelperOnOffCB *helper = *iter;
987             if (helper == nullptr || helper->uri != strUri) {
988                 iter++;
989                 continue;
990             }
991             data->NotifyList.emplace_back(helper);
992             iter = g_registerInstances.erase(iter);
993             HILOG_INFO("NAPI_UnRegister Instances erase size = %{public}zu", g_registerInstances.size());
994         }
995     } else {
996         HILOG_ERROR("NAPI_UnRegister, error: uri is null.");
997     }
998     HILOG_INFO("NAPI_UnRegister, FindRegisterObs main event thread execute.end %{public}zu", data->NotifyList.size());
999 }
1000 
ReleaseJSCallback()1001 void NAPIDataAbilityObserver::ReleaseJSCallback()
1002 {
1003     std::lock_guard<std::mutex> lock(mutex_);
1004     if (ref_ == nullptr) {
1005         HILOG_ERROR("NAPIDataAbilityObserver::ReleaseJSCallback, ref_ is null.");
1006         return;
1007     }
1008 
1009     if (isCallingback_) {
1010         needRelease_ = true;
1011         HILOG_WARN("%{public}s, ref_ is calling back.", __func__);
1012         return;
1013     }
1014 
1015     SafeReleaseJSCallback();
1016     HILOG_INFO("NAPIDataAbilityObserver::%{public}s, called. end", __func__);
1017 }
1018 
SafeReleaseJSCallback()1019 void NAPIDataAbilityObserver::SafeReleaseJSCallback()
1020 {
1021     uv_loop_s* loop = nullptr;
1022     napi_get_uv_event_loop(env_, &loop);
1023     if (loop == nullptr) {
1024         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
1025         return;
1026     }
1027 
1028     struct DelRefCallbackInfo {
1029         napi_env env_;
1030         napi_ref ref_;
1031     };
1032 
1033     DelRefCallbackInfo* delRefCallbackInfo = new DelRefCallbackInfo {
1034         .env_ = env_,
1035         .ref_ = ref_,
1036     };
1037 
1038     uv_work_t* work = new uv_work_t;
1039     work->data = static_cast<void*>(delRefCallbackInfo);
1040     int ret = uv_queue_work_with_qos(
1041         loop, work, [](uv_work_t* work) {},
1042         [](uv_work_t* work, int status) {
1043             // JS Thread
1044             if (work == nullptr) {
1045                 HILOG_ERROR("uv_queue_work input work is nullptr");
1046                 return;
1047             }
1048             auto delRefCallbackInfo =  reinterpret_cast<DelRefCallbackInfo*>(work->data);
1049             if (delRefCallbackInfo == nullptr) {
1050                 HILOG_ERROR("uv_queue_work delRefCallbackInfo is nullptr");
1051                 delete work;
1052                 work = nullptr;
1053                 return;
1054             }
1055 
1056             napi_delete_reference(delRefCallbackInfo->env_, delRefCallbackInfo->ref_);
1057             delete delRefCallbackInfo;
1058             delRefCallbackInfo = nullptr;
1059             delete work;
1060             work = nullptr;
1061         }, uv_qos_user_initiated);
1062     if (ret != 0) {
1063         if (delRefCallbackInfo != nullptr) {
1064             delete delRefCallbackInfo;
1065             delRefCallbackInfo = nullptr;
1066         }
1067         if (work != nullptr) {
1068             delete work;
1069             work = nullptr;
1070         }
1071     }
1072     ref_ = nullptr;
1073 }
1074 
SetEnv(const napi_env & env)1075 void NAPIDataAbilityObserver::SetEnv(const napi_env &env)
1076 {
1077     env_ = env;
1078     HILOG_INFO("NAPIDataAbilityObserver::%{public}s, called. end", __func__);
1079 }
1080 
SetCallbackRef(const napi_ref & ref)1081 void NAPIDataAbilityObserver::SetCallbackRef(const napi_ref &ref)
1082 {
1083     ref_ = ref;
1084     HILOG_INFO("NAPIDataAbilityObserver::%{public}s, called. end", __func__);
1085 }
1086 
OnChangeJSThreadWorker(uv_work_t * work,int status)1087 static void OnChangeJSThreadWorker(uv_work_t *work, int status)
1088 {
1089     HILOG_INFO("OnChange, uv_queue_work");
1090     if (work == nullptr) {
1091         HILOG_ERROR("OnChange, uv_queue_work input work is nullptr");
1092         return;
1093     }
1094     DAHelperOnOffCB *onCB = (DAHelperOnOffCB *)work->data;
1095     if (onCB == nullptr) {
1096         HILOG_ERROR("OnChange, uv_queue_work onCB is nullptr");
1097         delete work;
1098         work = nullptr;
1099         return;
1100     }
1101 
1102     if (onCB->observer != nullptr) {
1103         onCB->observer->CallJsMethod();
1104     }
1105 
1106     delete onCB;
1107     onCB = nullptr;
1108     delete work;
1109     work = nullptr;
1110     HILOG_INFO("OnChange, uv_queue_work. end");
1111 }
1112 
CallJsMethod()1113 void NAPIDataAbilityObserver::CallJsMethod()
1114 {
1115     {
1116         std::lock_guard<std::mutex> lock(mutex_);
1117         if (ref_ == nullptr || env_ == nullptr) {
1118             HILOG_WARN("%{public}s observer is invalid.", __func__);
1119             return;
1120         }
1121         isCallingback_ = true;
1122     }
1123     napi_value result[ARGS_TWO] = {nullptr};
1124     result[PARAM0] = GetCallbackErrorValue(env_, NO_ERROR);
1125     napi_value callback = nullptr;
1126     napi_value undefined = nullptr;
1127     napi_get_undefined(env_, &undefined);
1128     napi_value callResult = nullptr;
1129     napi_get_reference_value(env_, ref_, &callback);
1130     napi_call_function(env_, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult);
1131 
1132     {
1133         std::lock_guard<std::mutex> lock(mutex_);
1134         if (needRelease_ && ref_ != nullptr) {
1135             HILOG_INFO("%{public}s to delete callback.", __func__);
1136             napi_delete_reference(env_, ref_);
1137             ref_ = nullptr;
1138             needRelease_ = false;
1139         }
1140         isCallingback_ = false;
1141     }
1142 }
1143 
OnChange()1144 void NAPIDataAbilityObserver::OnChange()
1145 {
1146     if (ref_ == nullptr) {
1147         HILOG_ERROR("%{public}s, OnChange ref is nullptr.", __func__);
1148         return;
1149     }
1150     uv_loop_s *loop = nullptr;
1151     napi_get_uv_event_loop(env_, &loop);
1152     if (loop == nullptr) {
1153         HILOG_ERROR("%{public}s, loop is nullptr.", __func__);
1154         return;
1155     }
1156 
1157     uv_work_t *work = new uv_work_t;
1158     DAHelperOnOffCB *onCB = new DAHelperOnOffCB;
1159     onCB->observer = this;
1160     work->data = static_cast<void *>(onCB);
1161     int rev = uv_queue_work(
1162         loop,
1163         work,
1164         [](uv_work_t *work) {},
1165         OnChangeJSThreadWorker);
1166     if (rev != 0) {
1167         if (onCB != nullptr) {
1168             delete onCB;
1169             onCB = nullptr;
1170         }
1171         if (work != nullptr) {
1172             delete work;
1173             work = nullptr;
1174         }
1175     }
1176     HILOG_INFO("%{public}s, called. end", __func__);
1177 }
1178 
NAPI_GetType(napi_env env,napi_callback_info info)1179 napi_value NAPI_GetType(napi_env env, napi_callback_info info)
1180 {
1181     HILOG_INFO("%{public}s,called", __func__);
1182     DAHelperGetTypeCB *gettypeCB = new (std::nothrow) DAHelperGetTypeCB;
1183     if (gettypeCB == nullptr) {
1184         HILOG_ERROR("%{public}s, gettypeCB == nullptr.", __func__);
1185         return WrapVoidToJS(env);
1186     }
1187     gettypeCB->cbBase.cbInfo.env = env;
1188     gettypeCB->cbBase.asyncWork = nullptr;
1189     gettypeCB->cbBase.deferred = nullptr;
1190     gettypeCB->cbBase.ability = nullptr;
1191 
1192     napi_value ret = GetTypeWrap(env, info, gettypeCB);
1193     if (ret == nullptr) {
1194         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
1195         delete gettypeCB;
1196         gettypeCB = nullptr;
1197         ret = WrapVoidToJS(env);
1198     }
1199     HILOG_INFO("%{public}s,end", __func__);
1200     return ret;
1201 }
1202 
GetTypeWrap(napi_env env,napi_callback_info info,DAHelperGetTypeCB * gettypeCB)1203 napi_value GetTypeWrap(napi_env env, napi_callback_info info, DAHelperGetTypeCB *gettypeCB)
1204 {
1205     HILOG_INFO("%{public}s,start", __func__);
1206     size_t argcAsync = ARGS_TWO;
1207     const size_t argcPromise = ARGS_ONE;
1208     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1209     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1210     napi_value ret = nullptr;
1211     napi_value thisVar = nullptr;
1212 
1213     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1214     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1215         HILOG_ERROR("%{public}s, error argument count.", __func__);
1216         return nullptr;
1217     }
1218 
1219     napi_valuetype valuetype = napi_undefined;
1220     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1221     if (valuetype == napi_string) {
1222         gettypeCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1223         HILOG_INFO("%{public}s,uri=%{public}s", __func__, gettypeCB->uri.c_str());
1224     } else {
1225         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
1226     }
1227     GetDataAbilityHelper(env, thisVar, gettypeCB->dataAbilityHelper);
1228 
1229     if (argcAsync > argcPromise) {
1230         ret = GetTypeAsync(env, args, ARGS_ONE, gettypeCB);
1231     } else {
1232         ret = GetTypePromise(env, gettypeCB);
1233     }
1234     HILOG_INFO("%{public}s,end", __func__);
1235     return ret;
1236 }
1237 
GetTypeAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperGetTypeCB * gettypeCB)1238 napi_value GetTypeAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperGetTypeCB *gettypeCB)
1239 {
1240     HILOG_INFO("%{public}s, asyncCallback.", __func__);
1241     if (args == nullptr || gettypeCB == nullptr) {
1242         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1243         return nullptr;
1244     }
1245     napi_value resourceName = nullptr;
1246     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1247 
1248     napi_valuetype valuetype = napi_undefined;
1249     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
1250     if (valuetype == napi_function) {
1251         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &gettypeCB->cbBase.cbInfo.callback));
1252     }
1253 
1254     NAPI_CALL(env,
1255         napi_create_async_work(env,
1256             nullptr,
1257             resourceName,
1258             GetTypeExecuteCB,
1259             GetTypeAsyncCompleteCB,
1260             static_cast<void *>(gettypeCB),
1261             &gettypeCB->cbBase.asyncWork));
1262     NAPI_CALL(env, napi_queue_async_work_with_qos(env, gettypeCB->cbBase.asyncWork, napi_qos_user_initiated));
1263     napi_value result = nullptr;
1264     NAPI_CALL(env, napi_get_null(env, &result));
1265     HILOG_INFO("%{public}s, asyncCallback end", __func__);
1266     return result;
1267 }
1268 
GetTypePromise(napi_env env,DAHelperGetTypeCB * gettypeCB)1269 napi_value GetTypePromise(napi_env env, DAHelperGetTypeCB *gettypeCB)
1270 {
1271     HILOG_INFO("%{public}s, promise.", __func__);
1272     if (gettypeCB == nullptr) {
1273         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1274         return nullptr;
1275     }
1276     napi_value resourceName;
1277     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1278     napi_deferred deferred;
1279     napi_value promise = nullptr;
1280     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1281     gettypeCB->cbBase.deferred = deferred;
1282 
1283     NAPI_CALL(env,
1284         napi_create_async_work(env,
1285             nullptr,
1286             resourceName,
1287             GetTypeExecuteCB,
1288             GetTypePromiseCompleteCB,
1289             static_cast<void *>(gettypeCB),
1290             &gettypeCB->cbBase.asyncWork));
1291     NAPI_CALL(env, napi_queue_async_work_with_qos(env, gettypeCB->cbBase.asyncWork, napi_qos_user_initiated));
1292     HILOG_INFO("%{public}s, promise end.", __func__);
1293     return promise;
1294 }
1295 
GetTypeExecuteCB(napi_env env,void * data)1296 void GetTypeExecuteCB(napi_env env, void *data)
1297 {
1298     HILOG_INFO("NAPI_GetType, worker pool thread execute.");
1299     DAHelperGetTypeCB *gettypeCB = static_cast<DAHelperGetTypeCB *>(data);
1300     auto dataAbilityHelper = gettypeCB->dataAbilityHelper;
1301     if (dataAbilityHelper != nullptr) {
1302         gettypeCB->execResult = INVALID_PARAMETER;
1303         if (!gettypeCB->uri.empty()) {
1304             OHOS::Uri uri(gettypeCB->uri);
1305             gettypeCB->result = dataAbilityHelper->GetType(uri);
1306             gettypeCB->execResult = NO_ERROR;
1307         } else {
1308             HILOG_ERROR("NAPI_GetType, dataAbilityHelper uri is empty.");
1309         }
1310     } else {
1311         HILOG_ERROR("NAPI_GetType, dataAbilityHelper == nullptr.");
1312     }
1313     HILOG_INFO("NAPI_GetType, worker pool thread execute end.");
1314 }
1315 
GetTypeAsyncCompleteCB(napi_env env,napi_status status,void * data)1316 void GetTypeAsyncCompleteCB(napi_env env, napi_status status, void *data)
1317 {
1318     HILOG_INFO("NAPI_GetType, main event thread complete.");
1319     DAHelperGetTypeCB *gettypeCB = static_cast<DAHelperGetTypeCB *>(data);
1320     napi_value callback = nullptr;
1321     napi_value undefined = nullptr;
1322     napi_value result[ARGS_TWO] = {nullptr};
1323     napi_value callResult = nullptr;
1324     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
1325     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, gettypeCB->cbBase.cbInfo.callback, &callback));
1326 
1327     result[PARAM0] = GetCallbackErrorValue(env, gettypeCB->execResult);
1328     napi_create_string_utf8(env, gettypeCB->result.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
1329 
1330     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
1331 
1332     if (gettypeCB->cbBase.cbInfo.callback != nullptr) {
1333         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, gettypeCB->cbBase.cbInfo.callback));
1334     }
1335     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, gettypeCB->cbBase.asyncWork));
1336     delete gettypeCB;
1337     gettypeCB = nullptr;
1338     HILOG_INFO("NAPI_GetType, main event thread complete end.");
1339 }
1340 
GetTypePromiseCompleteCB(napi_env env,napi_status status,void * data)1341 void GetTypePromiseCompleteCB(napi_env env, napi_status status, void *data)
1342 {
1343     HILOG_INFO("NAPI_GetType,  main event thread complete.");
1344     DAHelperGetTypeCB *gettypeCB = static_cast<DAHelperGetTypeCB *>(data);
1345     napi_value result = nullptr;
1346     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, gettypeCB->result.c_str(), NAPI_AUTO_LENGTH, &result));
1347     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, gettypeCB->cbBase.deferred, result));
1348     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, gettypeCB->cbBase.asyncWork));
1349     delete gettypeCB;
1350     gettypeCB = nullptr;
1351     HILOG_INFO("NAPI_GetType,  main event thread complete end.");
1352 }
1353 
NAPI_GetFileTypes(napi_env env,napi_callback_info info)1354 napi_value NAPI_GetFileTypes(napi_env env, napi_callback_info info)
1355 {
1356     HILOG_INFO("%{public}s,called", __func__);
1357     DAHelperGetFileTypesCB *getfiletypesCB = new (std::nothrow) DAHelperGetFileTypesCB;
1358     if (getfiletypesCB == nullptr) {
1359         HILOG_ERROR("%{public}s, getfiletypesCB == nullptr.", __func__);
1360         return WrapVoidToJS(env);
1361     }
1362     getfiletypesCB->cbBase.cbInfo.env = env;
1363     getfiletypesCB->cbBase.asyncWork = nullptr;
1364     getfiletypesCB->cbBase.deferred = nullptr;
1365     getfiletypesCB->cbBase.ability = nullptr;
1366 
1367     napi_value ret = GetFileTypesWrap(env, info, getfiletypesCB);
1368     if (ret == nullptr) {
1369         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
1370         delete getfiletypesCB;
1371         getfiletypesCB = nullptr;
1372         ret = WrapVoidToJS(env);
1373     }
1374     HILOG_INFO("%{public}s,end", __func__);
1375     return ret;
1376 }
1377 
GetFileTypesWrap(napi_env env,napi_callback_info info,DAHelperGetFileTypesCB * getfiletypesCB)1378 napi_value GetFileTypesWrap(napi_env env, napi_callback_info info, DAHelperGetFileTypesCB *getfiletypesCB)
1379 {
1380     HILOG_INFO("%{public}s,called", __func__);
1381     size_t argcAsync = ARGS_THREE;
1382     const size_t argcPromise = ARGS_TWO;
1383     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1384     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1385     napi_value ret = nullptr;
1386     napi_value thisVar = nullptr;
1387 
1388     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1389     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1390         HILOG_ERROR("%{public}s, Wrong arguments count.", __func__);
1391         return nullptr;
1392     }
1393 
1394     napi_valuetype valuetype = napi_undefined;
1395     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1396     if (valuetype == napi_string) {
1397         getfiletypesCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1398         HILOG_INFO("%{public}s,uri=%{public}s", __func__, getfiletypesCB->uri.c_str());
1399     }
1400 
1401     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
1402     if (valuetype == napi_string) {
1403         getfiletypesCB->mimeTypeFilter = NapiValueToStringUtf8(env, args[PARAM1]);
1404         HILOG_INFO("%{public}s,mimeTypeFilter=%{public}s", __func__, getfiletypesCB->mimeTypeFilter.c_str());
1405     }
1406     GetDataAbilityHelper(env, thisVar, getfiletypesCB->dataAbilityHelper);
1407 
1408     if (argcAsync > argcPromise) {
1409         ret = GetFileTypesAsync(env, args, ARGS_TWO, getfiletypesCB);
1410     } else {
1411         ret = GetFileTypesPromise(env, getfiletypesCB);
1412     }
1413     HILOG_INFO("%{public}s,end", __func__);
1414     return ret;
1415 }
GetFileTypesAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperGetFileTypesCB * getfiletypesCB)1416 napi_value GetFileTypesAsync(
1417     napi_env env, napi_value *args, const size_t argCallback, DAHelperGetFileTypesCB *getfiletypesCB)
1418 {
1419     HILOG_INFO("%{public}s, asyncCallback.", __func__);
1420     if (args == nullptr || getfiletypesCB == nullptr) {
1421         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1422         return nullptr;
1423     }
1424     napi_value resourceName = nullptr;
1425     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1426 
1427     napi_valuetype valuetype = napi_undefined;
1428     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
1429     if (valuetype == napi_function) {
1430         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &getfiletypesCB->cbBase.cbInfo.callback));
1431     }
1432 
1433     NAPI_CALL(env,
1434         napi_create_async_work(env,
1435             nullptr,
1436             resourceName,
1437             GetFileTypesExecuteCB,
1438             GetFileTypesAsyncCompleteCB,
1439             static_cast<void *>(getfiletypesCB),
1440             &getfiletypesCB->cbBase.asyncWork));
1441     NAPI_CALL(env, napi_queue_async_work_with_qos(env, getfiletypesCB->cbBase.asyncWork, napi_qos_user_initiated));
1442     napi_value result = nullptr;
1443     NAPI_CALL(env, napi_get_null(env, &result));
1444     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
1445     return result;
1446 }
1447 
GetFileTypesPromise(napi_env env,DAHelperGetFileTypesCB * getfiletypesCB)1448 napi_value GetFileTypesPromise(napi_env env, DAHelperGetFileTypesCB *getfiletypesCB)
1449 {
1450     HILOG_INFO("%{public}s, promise.", __func__);
1451     if (getfiletypesCB == nullptr) {
1452         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1453         return nullptr;
1454     }
1455     napi_value resourceName;
1456     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1457     napi_deferred deferred;
1458     napi_value promise = nullptr;
1459     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1460     getfiletypesCB->cbBase.deferred = deferred;
1461 
1462     NAPI_CALL(env,
1463         napi_create_async_work(env,
1464             nullptr,
1465             resourceName,
1466             GetFileTypesExecuteCB,
1467             GetFileTypesPromiseCompleteCB,
1468             static_cast<void *>(getfiletypesCB),
1469             &getfiletypesCB->cbBase.asyncWork));
1470     NAPI_CALL(env, napi_queue_async_work_with_qos(env, getfiletypesCB->cbBase.asyncWork, napi_qos_user_initiated));
1471     HILOG_INFO("%{public}s, promise end.", __func__);
1472     return promise;
1473 }
1474 
GetFileTypesExecuteCB(napi_env env,void * data)1475 void GetFileTypesExecuteCB(napi_env env, void *data)
1476 {
1477     HILOG_INFO("NAPI_GetFileTypes, worker pool thread execute.");
1478     DAHelperGetFileTypesCB *getfiletypesCB = static_cast<DAHelperGetFileTypesCB *>(data);
1479     auto dataAbilityHelper = getfiletypesCB->dataAbilityHelper;
1480     if (dataAbilityHelper != nullptr) {
1481         getfiletypesCB->execResult = INVALID_PARAMETER;
1482         if (!getfiletypesCB->uri.empty()) {
1483             OHOS::Uri uri(getfiletypesCB->uri);
1484             HILOG_INFO("NAPI_GetFileTypes, uri:%{public}s", uri.ToString().c_str());
1485             HILOG_INFO("NAPI_GetFileTypes, mimeTypeFilter:%{public}s", getfiletypesCB->mimeTypeFilter.c_str());
1486             getfiletypesCB->result = dataAbilityHelper->GetFileTypes(uri, getfiletypesCB->mimeTypeFilter);
1487             getfiletypesCB->execResult = NO_ERROR;
1488         } else {
1489             HILOG_INFO("NAPI_GetFileTypes, dataAbilityHelper uri is empty.");
1490         }
1491     } else {
1492         HILOG_INFO("NAPI_GetFileTypes, dataAbilityHelper == nullptr.");
1493     }
1494     HILOG_INFO("NAPI_GetFileTypes, worker pool thread execute end.");
1495 }
1496 
GetFileTypesAsyncCompleteCB(napi_env env,napi_status status,void * data)1497 void GetFileTypesAsyncCompleteCB(napi_env env, napi_status status, void *data)
1498 {
1499     HILOG_INFO("NAPI_GetFileTypes, main event thread complete.");
1500     DAHelperGetFileTypesCB *getfiletypesCB = static_cast<DAHelperGetFileTypesCB *>(data);
1501     napi_value callback = nullptr;
1502     napi_value undefined = nullptr;
1503     napi_value result[ARGS_TWO] = {nullptr};
1504     napi_value callResult = nullptr;
1505 
1506     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
1507     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, getfiletypesCB->cbBase.cbInfo.callback, &callback));
1508 
1509     result[PARAM0] = GetCallbackErrorValue(env, getfiletypesCB->execResult);
1510     result[PARAM1] = WrapGetFileTypesCB(env, *getfiletypesCB);
1511 
1512     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
1513 
1514     if (getfiletypesCB->cbBase.cbInfo.callback != nullptr) {
1515         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, getfiletypesCB->cbBase.cbInfo.callback));
1516     }
1517     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, getfiletypesCB->cbBase.asyncWork));
1518     delete getfiletypesCB;
1519     getfiletypesCB = nullptr;
1520     HILOG_INFO("NAPI_GetFileTypes, main event thread complete end.");
1521 }
1522 
WrapGetFileTypesCB(napi_env env,const DAHelperGetFileTypesCB & getfiletypesCB)1523 napi_value WrapGetFileTypesCB(napi_env env, const DAHelperGetFileTypesCB &getfiletypesCB)
1524 {
1525     HILOG_INFO("WrapGetFileTypesCB, called.");
1526     HILOG_INFO("NAPI_GetFileTypes, result.size:%{public}zu", getfiletypesCB.result.size());
1527     for (size_t i = 0; i < getfiletypesCB.result.size(); i++) {
1528         HILOG_INFO("NAPI_GetFileTypes, result[%{public}zu]:%{public}s", i, getfiletypesCB.result.at(i).c_str());
1529     }
1530     napi_value proValue = nullptr;
1531 
1532     napi_value jsArrayresult = nullptr;
1533     NAPI_CALL(env, napi_create_array(env, &jsArrayresult));
1534     for (size_t i = 0; i < getfiletypesCB.result.size(); i++) {
1535         proValue = nullptr;
1536         NAPI_CALL(env, napi_create_string_utf8(env, getfiletypesCB.result.at(i).c_str(), NAPI_AUTO_LENGTH, &proValue));
1537         NAPI_CALL(env, napi_set_element(env, jsArrayresult, i, proValue));
1538     }
1539     HILOG_INFO("WrapGetFileTypesCB, end.");
1540     return jsArrayresult;
1541 }
1542 
GetFileTypesPromiseCompleteCB(napi_env env,napi_status status,void * data)1543 void GetFileTypesPromiseCompleteCB(napi_env env, napi_status status, void *data)
1544 {
1545     HILOG_INFO("NAPI_GetFileTypes,  main event thread complete.");
1546     DAHelperGetFileTypesCB *getfiletypesCB = static_cast<DAHelperGetFileTypesCB *>(data);
1547     napi_value result = nullptr;
1548 
1549     result = WrapGetFileTypesCB(env, *getfiletypesCB);
1550     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, getfiletypesCB->cbBase.deferred, result));
1551     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, getfiletypesCB->cbBase.asyncWork));
1552     delete getfiletypesCB;
1553     getfiletypesCB = nullptr;
1554     HILOG_INFO("NAPI_GetFileTypes,  main event thread complete end.");
1555 }
1556 
NAPI_NormalizeUri(napi_env env,napi_callback_info info)1557 napi_value NAPI_NormalizeUri(napi_env env, napi_callback_info info)
1558 {
1559     HILOG_INFO("%{public}s,called", __func__);
1560     DAHelperNormalizeUriCB *normalizeuriCB = new (std::nothrow) DAHelperNormalizeUriCB;
1561     if (normalizeuriCB == nullptr) {
1562         HILOG_ERROR("%{public}s, normalizeuriCB == nullptr.", __func__);
1563         return WrapVoidToJS(env);
1564     }
1565     normalizeuriCB->cbBase.cbInfo.env = env;
1566     normalizeuriCB->cbBase.asyncWork = nullptr;
1567     normalizeuriCB->cbBase.deferred = nullptr;
1568     normalizeuriCB->cbBase.ability = nullptr;
1569 
1570     napi_value ret = NormalizeUriWrap(env, info, normalizeuriCB);
1571     if (ret == nullptr) {
1572         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
1573         delete normalizeuriCB;
1574         normalizeuriCB = nullptr;
1575         ret = WrapVoidToJS(env);
1576     }
1577     HILOG_INFO("%{public}s,end", __func__);
1578     return ret;
1579 }
1580 
NormalizeUriWrap(napi_env env,napi_callback_info info,DAHelperNormalizeUriCB * normalizeuriCB)1581 napi_value NormalizeUriWrap(napi_env env, napi_callback_info info, DAHelperNormalizeUriCB *normalizeuriCB)
1582 {
1583     HILOG_INFO("%{public}s,begin", __func__);
1584     size_t argcAsync = ARGS_TWO;
1585     const size_t argcPromise = ARGS_ONE;
1586     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1587     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1588     napi_value ret = nullptr;
1589     napi_value thisVar = nullptr;
1590 
1591     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1592     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1593         HILOG_ERROR("%{public}s, Error argument count.", __func__);
1594         return nullptr;
1595     }
1596 
1597     napi_valuetype valuetype = napi_undefined;
1598     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1599     if (valuetype == napi_string) {
1600         normalizeuriCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1601         HILOG_INFO("%{public}s,uri=%{public}s", __func__, normalizeuriCB->uri.c_str());
1602     }
1603     GetDataAbilityHelper(env, thisVar, normalizeuriCB->dataAbilityHelper);
1604 
1605     if (argcAsync > argcPromise) {
1606         ret = NormalizeUriAsync(env, args, ARGS_ONE, normalizeuriCB);
1607     } else {
1608         ret = NormalizeUriPromise(env, normalizeuriCB);
1609     }
1610     HILOG_INFO("%{public}s,end", __func__);
1611     return ret;
1612 }
NormalizeUriAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperNormalizeUriCB * normalizeuriCB)1613 napi_value NormalizeUriAsync(
1614     napi_env env, napi_value *args, const size_t argCallback, DAHelperNormalizeUriCB *normalizeuriCB)
1615 {
1616     HILOG_INFO("%{public}s, asyncCallback.", __func__);
1617     if (args == nullptr || normalizeuriCB == nullptr) {
1618         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1619         return nullptr;
1620     }
1621     napi_value resourceName = nullptr;
1622     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1623 
1624     napi_valuetype valuetype = napi_undefined;
1625     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
1626     if (valuetype == napi_function) {
1627         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &normalizeuriCB->cbBase.cbInfo.callback));
1628     }
1629 
1630     NAPI_CALL(env,
1631         napi_create_async_work(env,
1632             nullptr,
1633             resourceName,
1634             NormalizeUriExecuteCB,
1635             NormalizeUriAsyncCompleteCB,
1636             static_cast<void *>(normalizeuriCB),
1637             &normalizeuriCB->cbBase.asyncWork));
1638     NAPI_CALL(env, napi_queue_async_work_with_qos(env, normalizeuriCB->cbBase.asyncWork, napi_qos_user_initiated));
1639     napi_value result = nullptr;
1640     NAPI_CALL(env, napi_get_null(env, &result));
1641     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
1642     return result;
1643 }
1644 
NormalizeUriPromise(napi_env env,DAHelperNormalizeUriCB * normalizeuriCB)1645 napi_value NormalizeUriPromise(napi_env env, DAHelperNormalizeUriCB *normalizeuriCB)
1646 {
1647     HILOG_INFO("%{public}s, promise.", __func__);
1648     if (normalizeuriCB == nullptr) {
1649         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1650         return nullptr;
1651     }
1652     napi_value resourceName;
1653     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1654     napi_deferred deferred;
1655     napi_value promise = nullptr;
1656     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1657     normalizeuriCB->cbBase.deferred = deferred;
1658 
1659     NAPI_CALL(env,
1660         napi_create_async_work(env,
1661             nullptr,
1662             resourceName,
1663             NormalizeUriExecuteCB,
1664             NormalizeUriPromiseCompleteCB,
1665             static_cast<void *>(normalizeuriCB),
1666             &normalizeuriCB->cbBase.asyncWork));
1667     NAPI_CALL(env, napi_queue_async_work_with_qos(env, normalizeuriCB->cbBase.asyncWork, napi_qos_user_initiated));
1668     HILOG_INFO("%{public}s, promise end.", __func__);
1669     return promise;
1670 }
1671 
NormalizeUriExecuteCB(napi_env env,void * data)1672 void NormalizeUriExecuteCB(napi_env env, void *data)
1673 {
1674     HILOG_INFO("NAPI_NormalizeUri, worker pool thread execute.");
1675     DAHelperNormalizeUriCB *normalizeuriCB = static_cast<DAHelperNormalizeUriCB *>(data);
1676     Uri uriValue(normalizeuriCB->uri);
1677     auto dataAbilityHelper = normalizeuriCB->dataAbilityHelper;
1678     if (dataAbilityHelper != nullptr) {
1679         normalizeuriCB->execResult = INVALID_PARAMETER;
1680         if (!normalizeuriCB->uri.empty()) {
1681         OHOS::Uri uri(normalizeuriCB->uri);
1682             uriValue = dataAbilityHelper->NormalizeUri(uri);
1683             normalizeuriCB->result = uriValue.ToString();
1684             normalizeuriCB->execResult = NO_ERROR;
1685         }
1686     } else {
1687         HILOG_INFO("NAPI_NormalizeUri, dataAbilityHelper == nullptr");
1688     }
1689     HILOG_INFO("NAPI_NormalizeUri, worker pool thread execute end.");
1690 }
1691 
NormalizeUriAsyncCompleteCB(napi_env env,napi_status status,void * data)1692 void NormalizeUriAsyncCompleteCB(napi_env env, napi_status status, void *data)
1693 {
1694     HILOG_INFO("NAPI_NormalizeUri, main event thread complete.");
1695     DAHelperNormalizeUriCB *normalizeuriCB = static_cast<DAHelperNormalizeUriCB *>(data);
1696     napi_value callback = nullptr;
1697     napi_value undefined = nullptr;
1698     napi_value result[ARGS_TWO] = {nullptr};
1699     napi_value callResult = nullptr;
1700     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
1701     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, normalizeuriCB->cbBase.cbInfo.callback, &callback));
1702 
1703     result[PARAM0] = GetCallbackErrorValue(env, normalizeuriCB->execResult);
1704     NAPI_CALL_RETURN_VOID(
1705         env, napi_create_string_utf8(env, normalizeuriCB->result.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]));
1706 
1707     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
1708 
1709     if (normalizeuriCB->cbBase.cbInfo.callback != nullptr) {
1710         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, normalizeuriCB->cbBase.cbInfo.callback));
1711     }
1712     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, normalizeuriCB->cbBase.asyncWork));
1713     delete normalizeuriCB;
1714     normalizeuriCB = nullptr;
1715     HILOG_INFO("NAPI_NormalizeUri, main event thread complete end.");
1716 }
1717 
NormalizeUriPromiseCompleteCB(napi_env env,napi_status status,void * data)1718 void NormalizeUriPromiseCompleteCB(napi_env env, napi_status status, void *data)
1719 {
1720     HILOG_INFO("NAPI_NormalizeUri,  main event thread complete.");
1721     DAHelperNormalizeUriCB *normalizeuriCB = static_cast<DAHelperNormalizeUriCB *>(data);
1722     napi_value result = nullptr;
1723     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, normalizeuriCB->result.c_str(), NAPI_AUTO_LENGTH, &result));
1724     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, normalizeuriCB->cbBase.deferred, result));
1725     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, normalizeuriCB->cbBase.asyncWork));
1726     delete normalizeuriCB;
1727     normalizeuriCB = nullptr;
1728     HILOG_INFO("NAPI_NormalizeUri,  main event thread complete end.");
1729 }
1730 
NAPI_DenormalizeUri(napi_env env,napi_callback_info info)1731 napi_value NAPI_DenormalizeUri(napi_env env, napi_callback_info info)
1732 {
1733     HILOG_INFO("%{public}s,called", __func__);
1734     DAHelperDenormalizeUriCB *denormalizeuriCB = new (std::nothrow) DAHelperDenormalizeUriCB;
1735     if (denormalizeuriCB == nullptr) {
1736         HILOG_ERROR("%{public}s, denormalizeuriCB == nullptr.", __func__);
1737         return WrapVoidToJS(env);
1738     }
1739     denormalizeuriCB->cbBase.cbInfo.env = env;
1740     denormalizeuriCB->cbBase.asyncWork = nullptr;
1741     denormalizeuriCB->cbBase.deferred = nullptr;
1742     denormalizeuriCB->cbBase.ability = nullptr;
1743 
1744     napi_value ret = DenormalizeUriWrap(env, info, denormalizeuriCB);
1745     if (ret == nullptr) {
1746         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
1747         delete denormalizeuriCB;
1748         denormalizeuriCB = nullptr;
1749         ret = WrapVoidToJS(env);
1750     }
1751     HILOG_INFO("%{public}s,end", __func__);
1752     return ret;
1753 }
1754 
DenormalizeUriWrap(napi_env env,napi_callback_info info,DAHelperDenormalizeUriCB * denormalizeuriCB)1755 napi_value DenormalizeUriWrap(napi_env env, napi_callback_info info, DAHelperDenormalizeUriCB *denormalizeuriCB)
1756 {
1757     HILOG_INFO("%{public}s,called", __func__);
1758     size_t argcAsync = ARGS_TWO;
1759     const size_t argcPromise = ARGS_ONE;
1760     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1761     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1762     napi_value ret = nullptr;
1763     napi_value thisVar = nullptr;
1764 
1765     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1766     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1767         HILOG_ERROR("%{public}s, Parameter count error", __func__);
1768         return nullptr;
1769     }
1770 
1771     napi_valuetype valuetype = napi_undefined;
1772     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1773     if (valuetype == napi_string) {
1774         denormalizeuriCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1775         HILOG_INFO("%{public}s,uri=%{public}s", __func__, denormalizeuriCB->uri.c_str());
1776     }
1777     GetDataAbilityHelper(env, thisVar, denormalizeuriCB->dataAbilityHelper);
1778 
1779     if (argcAsync > argcPromise) {
1780         ret = DenormalizeUriAsync(env, args, ARGS_ONE, denormalizeuriCB);
1781     } else {
1782         ret = DenormalizeUriPromise(env, denormalizeuriCB);
1783     }
1784     HILOG_INFO("%{public}s,end", __func__);
1785     return ret;
1786 }
DenormalizeUriAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperDenormalizeUriCB * denormalizeuriCB)1787 napi_value DenormalizeUriAsync(
1788     napi_env env, napi_value *args, const size_t argCallback, DAHelperDenormalizeUriCB *denormalizeuriCB)
1789 {
1790     HILOG_INFO("%{public}s, asyncCallback.", __func__);
1791     if (args == nullptr || denormalizeuriCB == nullptr) {
1792         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1793         return nullptr;
1794     }
1795     napi_value resourceName = nullptr;
1796     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1797 
1798     napi_valuetype valuetype = napi_undefined;
1799     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
1800     if (valuetype == napi_function) {
1801         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &denormalizeuriCB->cbBase.cbInfo.callback));
1802     }
1803 
1804     NAPI_CALL(env,
1805         napi_create_async_work(env,
1806             nullptr,
1807             resourceName,
1808             DenormalizeUriExecuteCB,
1809             DenormalizeUriAsyncCompleteCB,
1810             static_cast<void *>(denormalizeuriCB),
1811             &denormalizeuriCB->cbBase.asyncWork));
1812     NAPI_CALL(env, napi_queue_async_work_with_qos(env, denormalizeuriCB->cbBase.asyncWork, napi_qos_user_initiated));
1813     napi_value result = nullptr;
1814     NAPI_CALL(env, napi_get_null(env, &result));
1815     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
1816     return result;
1817 }
1818 
DenormalizeUriPromise(napi_env env,DAHelperDenormalizeUriCB * denormalizeuriCB)1819 napi_value DenormalizeUriPromise(napi_env env, DAHelperDenormalizeUriCB *denormalizeuriCB)
1820 {
1821     HILOG_INFO("%{public}s, promise.", __func__);
1822     if (denormalizeuriCB == nullptr) {
1823         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1824         return nullptr;
1825     }
1826     napi_value resourceName;
1827     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1828     napi_deferred deferred;
1829     napi_value promise = nullptr;
1830     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1831     denormalizeuriCB->cbBase.deferred = deferred;
1832 
1833     NAPI_CALL(env,
1834         napi_create_async_work(env,
1835             nullptr,
1836             resourceName,
1837             DenormalizeUriExecuteCB,
1838             DenormalizeUriPromiseCompleteCB,
1839             static_cast<void *>(denormalizeuriCB),
1840             &denormalizeuriCB->cbBase.asyncWork));
1841     NAPI_CALL(env, napi_queue_async_work_with_qos(env, denormalizeuriCB->cbBase.asyncWork, napi_qos_user_initiated));
1842     HILOG_INFO("%{public}s, promise end.", __func__);
1843     return promise;
1844 }
1845 
DenormalizeUriExecuteCB(napi_env env,void * data)1846 void DenormalizeUriExecuteCB(napi_env env, void *data)
1847 {
1848     HILOG_INFO("NAPI_DenormalizeUri, worker pool thread execute.");
1849     DAHelperDenormalizeUriCB *denormalizeuriCB = static_cast<DAHelperDenormalizeUriCB *>(data);
1850     Uri uriValue(denormalizeuriCB->uri);
1851     auto dataAbilityHelper = denormalizeuriCB->dataAbilityHelper;
1852     if (dataAbilityHelper != nullptr) {
1853         denormalizeuriCB->execResult = INVALID_PARAMETER;
1854         if (!denormalizeuriCB->uri.empty()) {
1855             OHOS::Uri uri(denormalizeuriCB->uri);
1856             uriValue = dataAbilityHelper->DenormalizeUri(uri);
1857             denormalizeuriCB->result = uriValue.ToString();
1858             denormalizeuriCB->execResult = NO_ERROR;
1859         } else {
1860             HILOG_ERROR("NAPI_DenormalizeUri, dataAbilityHelper uri is empty");
1861         }
1862     } else {
1863         HILOG_ERROR("NAPI_DenormalizeUri, dataAbilityHelper == nullptr");
1864     }
1865     HILOG_INFO("NAPI_DenormalizeUri, worker pool thread execute end.");
1866 }
1867 
DenormalizeUriAsyncCompleteCB(napi_env env,napi_status status,void * data)1868 void DenormalizeUriAsyncCompleteCB(napi_env env, napi_status status, void *data)
1869 {
1870     HILOG_INFO("NAPI_DenormalizeUri, main event thread complete.");
1871     DAHelperDenormalizeUriCB *denormalizeuriCB = static_cast<DAHelperDenormalizeUriCB *>(data);
1872     napi_value callback = nullptr;
1873     napi_value undefined = nullptr;
1874     napi_value result[ARGS_TWO] = {nullptr};
1875     napi_value callResult = nullptr;
1876     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
1877     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, denormalizeuriCB->cbBase.cbInfo.callback, &callback));
1878 
1879     result[PARAM0] = GetCallbackErrorValue(env, denormalizeuriCB->execResult);
1880     NAPI_CALL_RETURN_VOID(
1881         env, napi_create_string_utf8(env, denormalizeuriCB->result.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]));
1882 
1883     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
1884 
1885     if (denormalizeuriCB->cbBase.cbInfo.callback != nullptr) {
1886         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, denormalizeuriCB->cbBase.cbInfo.callback));
1887     }
1888     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, denormalizeuriCB->cbBase.asyncWork));
1889     delete denormalizeuriCB;
1890     denormalizeuriCB = nullptr;
1891     HILOG_INFO("NAPI_DenormalizeUri, main event thread complete end.");
1892 }
1893 
DenormalizeUriPromiseCompleteCB(napi_env env,napi_status status,void * data)1894 void DenormalizeUriPromiseCompleteCB(napi_env env, napi_status status, void *data)
1895 {
1896     HILOG_INFO("NAPI_DenormalizeUri,  main event thread complete.");
1897     DAHelperDenormalizeUriCB *denormalizeuriCB = static_cast<DAHelperDenormalizeUriCB *>(data);
1898     napi_value result = nullptr;
1899     NAPI_CALL_RETURN_VOID(
1900         env, napi_create_string_utf8(env, denormalizeuriCB->result.c_str(), NAPI_AUTO_LENGTH, &result));
1901     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, denormalizeuriCB->cbBase.deferred, result));
1902     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, denormalizeuriCB->cbBase.asyncWork));
1903     delete denormalizeuriCB;
1904     denormalizeuriCB = nullptr;
1905     HILOG_INFO("NAPI_DenormalizeUri,  main event thread complete end.");
1906 }
1907 
UnwrapDataAbilityPredicates(NativeRdb::DataAbilityPredicates & predicates,napi_env env,napi_value value)1908 void UnwrapDataAbilityPredicates(NativeRdb::DataAbilityPredicates &predicates, napi_env env, napi_value value)
1909 {
1910     auto tempPredicates = DataAbilityJsKit::DataAbilityPredicatesProxy::GetNativePredicates(env, value);
1911     if (tempPredicates == nullptr) {
1912         HILOG_ERROR("GetNativePredicates retval Marshalling failed.");
1913         return;
1914     }
1915     predicates = *tempPredicates;
1916 }
1917 
1918 /**
1919  * @brief DataAbilityHelper NAPI method : insert.
1920  *
1921  * @param env The environment that the Node-API call is invoked under.
1922  * @param info The callback info passed into the callback function.
1923  *
1924  * @return The return value from NAPI C++ to JS for the module.
1925  */
NAPI_Delete(napi_env env,napi_callback_info info)1926 napi_value NAPI_Delete(napi_env env, napi_callback_info info)
1927 {
1928     HILOG_INFO("%{public}s,called", __func__);
1929     DAHelperDeleteCB *deleteCB = new DAHelperDeleteCB;
1930     deleteCB->cbBase.cbInfo.env = env;
1931     deleteCB->cbBase.asyncWork = nullptr;
1932     deleteCB->cbBase.deferred = nullptr;
1933     deleteCB->cbBase.ability = nullptr;
1934 
1935     napi_value ret = DeleteWrap(env, info, deleteCB);
1936     if (ret == nullptr) {
1937         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
1938         delete deleteCB;
1939         deleteCB = nullptr;
1940         ret = WrapVoidToJS(env);
1941     }
1942     HILOG_INFO("%{public}s,end", __func__);
1943     return ret;
1944 }
1945 
1946 /**
1947  * @brief Insert processing function.
1948  *
1949  * @param env The environment that the Node-API call is invoked under.
1950  * @param insertCB Process data asynchronously.
1951  *
1952  * @return Return JS data successfully, otherwise return nullptr.
1953  */
DeleteWrap(napi_env env,napi_callback_info info,DAHelperDeleteCB * deleteCB)1954 napi_value DeleteWrap(napi_env env, napi_callback_info info, DAHelperDeleteCB *deleteCB)
1955 {
1956     HILOG_INFO("%{public}s,called", __func__);
1957     size_t argcAsync = ARGS_THREE;
1958     const size_t argcPromise = ARGS_TWO;
1959     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1960     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1961     napi_value ret = nullptr;
1962     napi_value thisVar = nullptr;
1963 
1964     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1965     if (argcAsync > argCountWithAsync) {
1966         HILOG_ERROR("%{public}s, Error argument count.", __func__);
1967         return nullptr;
1968     }
1969 
1970     napi_valuetype valuetype = napi_undefined;
1971     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1972     if (valuetype == napi_string) {
1973         deleteCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1974         HILOG_INFO("%{public}s,uri=%{public}s", __func__, deleteCB->uri.c_str());
1975     }
1976 
1977     UnwrapDataAbilityPredicates(deleteCB->predicates, env, args[PARAM1]);
1978     GetDataAbilityHelper(env, thisVar, deleteCB->dataAbilityHelper);
1979 
1980     if (argcAsync > argcPromise) {
1981         ret = DeleteAsync(env, args, ARGS_TWO, deleteCB);
1982     } else {
1983         ret = DeletePromise(env, deleteCB);
1984     }
1985     HILOG_INFO("%{public}s,end", __func__);
1986     return ret;
1987 }
1988 
DeleteAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperDeleteCB * deleteCB)1989 napi_value DeleteAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperDeleteCB *deleteCB)
1990 {
1991     HILOG_INFO("%{public}s, asyncCallback.", __func__);
1992     if (args == nullptr || deleteCB == nullptr) {
1993         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1994         return nullptr;
1995     }
1996     napi_value resourceName = nullptr;
1997     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
1998 
1999     napi_valuetype valuetype = napi_undefined;
2000     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
2001     if (valuetype == napi_function) {
2002         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &deleteCB->cbBase.cbInfo.callback));
2003     }
2004 
2005     NAPI_CALL(env,
2006         napi_create_async_work(env,
2007             nullptr,
2008             resourceName,
2009             DeleteExecuteCB,
2010             DeleteAsyncCompleteCB,
2011             static_cast<void *>(deleteCB),
2012             &deleteCB->cbBase.asyncWork));
2013     NAPI_CALL(env, napi_queue_async_work_with_qos(env, deleteCB->cbBase.asyncWork, napi_qos_user_initiated));
2014     napi_value result = nullptr;
2015     NAPI_CALL(env, napi_get_null(env, &result));
2016     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
2017     return result;
2018 }
2019 
DeletePromise(napi_env env,DAHelperDeleteCB * deleteCB)2020 napi_value DeletePromise(napi_env env, DAHelperDeleteCB *deleteCB)
2021 {
2022     HILOG_INFO("%{public}s, promise.", __func__);
2023     if (deleteCB == nullptr) {
2024         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2025         return nullptr;
2026     }
2027     napi_value resourceName;
2028     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2029     napi_deferred deferred;
2030     napi_value promise = nullptr;
2031     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
2032     deleteCB->cbBase.deferred = deferred;
2033 
2034     NAPI_CALL(env,
2035         napi_create_async_work(env,
2036             nullptr,
2037             resourceName,
2038             DeleteExecuteCB,
2039             DeletePromiseCompleteCB,
2040             static_cast<void *>(deleteCB),
2041             &deleteCB->cbBase.asyncWork));
2042     NAPI_CALL(env, napi_queue_async_work_with_qos(env, deleteCB->cbBase.asyncWork, napi_qos_user_initiated));
2043     HILOG_INFO("%{public}s, promise end.", __func__);
2044     return promise;
2045 }
2046 
DeleteExecuteCB(napi_env env,void * data)2047 void DeleteExecuteCB(napi_env env, void *data)
2048 {
2049     HILOG_INFO("NAPI_Delete, worker pool thread execute.");
2050     DAHelperDeleteCB *deleteCB = static_cast<DAHelperDeleteCB *>(data);
2051     auto dataAbilityHelper = deleteCB->dataAbilityHelper;
2052     if (dataAbilityHelper != nullptr) {
2053         deleteCB->execResult = INVALID_PARAMETER;
2054         if (!deleteCB->uri.empty()) {
2055             OHOS::Uri uri(deleteCB->uri);
2056             deleteCB->result = dataAbilityHelper->Delete(uri, deleteCB->predicates);
2057             deleteCB->execResult = NO_ERROR;
2058         } else {
2059             HILOG_ERROR("NAPI_Delete, dataAbilityHelper uri is empty");
2060         }
2061     } else {
2062         HILOG_ERROR("NAPI_Delete, dataAbilityHelper == nullptr");
2063     }
2064     HILOG_INFO("NAPI_Delete, worker pool thread execute end.");
2065 }
2066 
DeleteAsyncCompleteCB(napi_env env,napi_status status,void * data)2067 void DeleteAsyncCompleteCB(napi_env env, napi_status status, void *data)
2068 {
2069     HILOG_INFO("NAPI_Delete, main event thread complete.");
2070     DAHelperDeleteCB *DeleteCB = static_cast<DAHelperDeleteCB *>(data);
2071     napi_value callback = nullptr;
2072     napi_value undefined = nullptr;
2073     napi_value result[ARGS_TWO] = {nullptr};
2074     napi_value callResult = nullptr;
2075     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
2076     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, DeleteCB->cbBase.cbInfo.callback, &callback));
2077 
2078     result[PARAM0] = GetCallbackErrorValue(env, DeleteCB->execResult);
2079     napi_create_int32(env, DeleteCB->result, &result[PARAM1]);
2080     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
2081 
2082     if (DeleteCB->cbBase.cbInfo.callback != nullptr) {
2083         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, DeleteCB->cbBase.cbInfo.callback));
2084     }
2085     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, DeleteCB->cbBase.asyncWork));
2086     delete DeleteCB;
2087     DeleteCB = nullptr;
2088     HILOG_INFO("NAPI_Delete, main event thread complete end.");
2089 }
2090 
DeletePromiseCompleteCB(napi_env env,napi_status status,void * data)2091 void DeletePromiseCompleteCB(napi_env env, napi_status status, void *data)
2092 {
2093     HILOG_INFO("NAPI_Delete,  main event thread complete.");
2094     DAHelperDeleteCB *DeleteCB = static_cast<DAHelperDeleteCB *>(data);
2095     napi_value result = nullptr;
2096     napi_create_int32(env, DeleteCB->result, &result);
2097     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, DeleteCB->cbBase.deferred, result));
2098     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, DeleteCB->cbBase.asyncWork));
2099     delete DeleteCB;
2100     DeleteCB = nullptr;
2101     HILOG_INFO("NAPI_Delete,  main event thread complete end.");
2102 }
2103 
2104 /**
2105  * @brief DataAbilityHelper NAPI method : insert.
2106  *
2107  * @param env The environment that the Node-API call is invoked under.
2108  * @param info The callback info passed into the callback function.
2109  *
2110  * @return The return value from NAPI C++ to JS for the module.
2111  */
NAPI_Update(napi_env env,napi_callback_info info)2112 napi_value NAPI_Update(napi_env env, napi_callback_info info)
2113 {
2114     HILOG_INFO("%{public}s,called", __func__);
2115     DAHelperUpdateCB *updateCB = new DAHelperUpdateCB;
2116     updateCB->cbBase.cbInfo.env = env;
2117     updateCB->cbBase.asyncWork = nullptr;
2118     updateCB->cbBase.deferred = nullptr;
2119     updateCB->cbBase.ability = nullptr;
2120 
2121     napi_value ret = UpdateWrap(env, info, updateCB);
2122     if (ret == nullptr) {
2123         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
2124         delete updateCB;
2125         updateCB = nullptr;
2126         ret = WrapVoidToJS(env);
2127     }
2128     HILOG_INFO("%{public}s,end", __func__);
2129     return ret;
2130 }
2131 
2132 /**
2133  * @brief Insert processing function.
2134  *
2135  * @param env The environment that the Node-API call is invoked under.
2136  * @param insertCB Process data asynchronously.
2137  *
2138  * @return Return JS data successfully, otherwise return nullptr.
2139  */
UpdateWrap(napi_env env,napi_callback_info info,DAHelperUpdateCB * updateCB)2140 napi_value UpdateWrap(napi_env env, napi_callback_info info, DAHelperUpdateCB *updateCB)
2141 {
2142     HILOG_INFO("%{public}s,called", __func__);
2143     size_t argcAsync = ARGS_FOUR;
2144     const size_t argcPromise = ARGS_THREE;
2145     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
2146     napi_value args[ARGS_MAX_COUNT] = {nullptr};
2147     napi_value ret = nullptr;
2148     napi_value thisVar = nullptr;
2149 
2150     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
2151     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
2152         HILOG_ERROR("%{public}s, Parameter count error.", __func__);
2153         return nullptr;
2154     }
2155 
2156     napi_valuetype valuetype = napi_undefined;
2157     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
2158     if (valuetype == napi_string) {
2159         updateCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
2160         HILOG_INFO("%{public}s,uri=%{public}s", __func__, updateCB->uri.c_str());
2161     }
2162 
2163     updateCB->valueBucket.Clear();
2164     AnalysisValuesBucket(updateCB->valueBucket, env, args[PARAM1]);
2165     UnwrapDataAbilityPredicates(updateCB->predicates, env, args[PARAM2]);
2166     GetDataAbilityHelper(env, thisVar, updateCB->dataAbilityHelper);
2167 
2168     if (argcAsync > argcPromise) {
2169         ret = UpdateAsync(env, args, ARGS_THREE, updateCB);
2170     } else {
2171         ret = UpdatePromise(env, updateCB);
2172     }
2173     HILOG_INFO("%{public}s,end", __func__);
2174     return ret;
2175 }
2176 
UpdateAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperUpdateCB * updateCB)2177 napi_value UpdateAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperUpdateCB *updateCB)
2178 {
2179     HILOG_INFO("%{public}s, asyncCallback.", __func__);
2180     if (args == nullptr || updateCB == nullptr) {
2181         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2182         return nullptr;
2183     }
2184     napi_value resourceName = nullptr;
2185     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2186 
2187     napi_valuetype valuetype = napi_undefined;
2188     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
2189     if (valuetype == napi_function) {
2190         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &updateCB->cbBase.cbInfo.callback));
2191     }
2192 
2193     NAPI_CALL(env,
2194         napi_create_async_work(env,
2195             nullptr,
2196             resourceName,
2197             UpdateExecuteCB,
2198             UpdateAsyncCompleteCB,
2199             static_cast<void *>(updateCB),
2200             &updateCB->cbBase.asyncWork));
2201     NAPI_CALL(env, napi_queue_async_work_with_qos(env, updateCB->cbBase.asyncWork, napi_qos_user_initiated));
2202     napi_value result = nullptr;
2203     NAPI_CALL(env, napi_get_null(env, &result));
2204     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
2205     return result;
2206 }
2207 
UpdatePromise(napi_env env,DAHelperUpdateCB * updateCB)2208 napi_value UpdatePromise(napi_env env, DAHelperUpdateCB *updateCB)
2209 {
2210     HILOG_INFO("%{public}s, promise.", __func__);
2211     if (updateCB == nullptr) {
2212         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2213         return nullptr;
2214     }
2215     napi_value resourceName;
2216     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2217     napi_deferred deferred;
2218     napi_value promise = nullptr;
2219     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
2220     updateCB->cbBase.deferred = deferred;
2221 
2222     NAPI_CALL(env,
2223         napi_create_async_work(env,
2224             nullptr,
2225             resourceName,
2226             UpdateExecuteCB,
2227             UpdatePromiseCompleteCB,
2228             static_cast<void *>(updateCB),
2229             &updateCB->cbBase.asyncWork));
2230     NAPI_CALL(env, napi_queue_async_work_with_qos(env, updateCB->cbBase.asyncWork, napi_qos_user_initiated));
2231     HILOG_INFO("%{public}s, promise end.", __func__);
2232     return promise;
2233 }
2234 
UpdateExecuteCB(napi_env env,void * data)2235 void UpdateExecuteCB(napi_env env, void *data)
2236 {
2237     HILOG_INFO("NAPI_Update, worker pool thread execute.");
2238     DAHelperUpdateCB *updateCB = static_cast<DAHelperUpdateCB *>(data);
2239     auto dataAbilityHelper = updateCB->dataAbilityHelper;
2240     if (dataAbilityHelper != nullptr) {
2241         updateCB->execResult = INVALID_PARAMETER;
2242         if (!updateCB->uri.empty()) {
2243             OHOS::Uri uri(updateCB->uri);
2244             updateCB->result = dataAbilityHelper->Update(uri, updateCB->valueBucket, updateCB->predicates);
2245             updateCB->execResult = NO_ERROR;
2246         } else {
2247             HILOG_ERROR("NAPI_Update, dataAbilityHelper uri is empty");
2248         }
2249     } else {
2250         HILOG_ERROR("NAPI_Update, dataAbilityHelper == nullptr");
2251     }
2252     HILOG_INFO("NAPI_Update, worker pool thread execute end.");
2253 }
2254 
UpdateAsyncCompleteCB(napi_env env,napi_status status,void * data)2255 void UpdateAsyncCompleteCB(napi_env env, napi_status status, void *data)
2256 {
2257     HILOG_INFO("NAPI_Update, main event thread complete.");
2258     DAHelperUpdateCB *updateCB = static_cast<DAHelperUpdateCB *>(data);
2259     napi_value callback = nullptr;
2260     napi_value undefined = nullptr;
2261     napi_value result[ARGS_TWO] = {nullptr};
2262     napi_value callResult = nullptr;
2263     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
2264     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, updateCB->cbBase.cbInfo.callback, &callback));
2265 
2266     result[PARAM0] = GetCallbackErrorValue(env, updateCB->execResult);
2267     napi_create_int32(env, updateCB->result, &result[PARAM1]);
2268     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
2269 
2270     if (updateCB->cbBase.cbInfo.callback != nullptr) {
2271         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, updateCB->cbBase.cbInfo.callback));
2272     }
2273     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, updateCB->cbBase.asyncWork));
2274     delete updateCB;
2275     updateCB = nullptr;
2276     HILOG_INFO("NAPI_Update, main event thread complete end.");
2277 }
2278 
UpdatePromiseCompleteCB(napi_env env,napi_status status,void * data)2279 void UpdatePromiseCompleteCB(napi_env env, napi_status status, void *data)
2280 {
2281     HILOG_INFO("NAPI_Update,  main event thread complete.");
2282     DAHelperUpdateCB *updateCB = static_cast<DAHelperUpdateCB *>(data);
2283     napi_value result = nullptr;
2284     napi_create_int32(env, updateCB->result, &result);
2285     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, updateCB->cbBase.deferred, result));
2286     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, updateCB->cbBase.asyncWork));
2287     delete updateCB;
2288     updateCB = nullptr;
2289     HILOG_INFO("NAPI_Update,  main event thread complete end.");
2290 }
2291 
CallErrorAsyncCompleteCB(napi_env env,napi_status status,void * data)2292 void CallErrorAsyncCompleteCB(napi_env env, napi_status status, void *data)
2293 {
2294     HILOG_INFO("CallErrorAsyncCompleteCB, main event thread complete.");
2295     DAHelperErrorCB *errorCB = static_cast<DAHelperErrorCB *>(data);
2296     if (errorCB != nullptr) {
2297         napi_value callback = nullptr;
2298         napi_value undefined = nullptr;
2299         napi_value result[ARGS_TWO] = {nullptr};
2300         napi_value callResult = nullptr;
2301         NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
2302         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, errorCB->cbBase.cbInfo.callback, &callback));
2303 
2304         napi_create_int32(env, errorCB->execResult, &result[PARAM0]);
2305         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[0], &callResult));
2306 
2307         if (errorCB->cbBase.cbInfo.callback != nullptr) {
2308             NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, errorCB->cbBase.cbInfo.callback));
2309         }
2310         NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, errorCB->cbBase.asyncWork));
2311     }
2312     delete errorCB;
2313     errorCB = nullptr;
2314     HILOG_INFO("CallErrorAsyncCompleteCB, main event thread complete end.");
2315 }
2316 
CallErrorPromiseCompleteCB(napi_env env,napi_status status,void * data)2317 void CallErrorPromiseCompleteCB(napi_env env, napi_status status, void *data)
2318 {
2319     HILOG_INFO("CallErrorPromiseCompleteCB,  main event thread complete.");
2320     DAHelperErrorCB *errorCB = static_cast<DAHelperErrorCB *>(data);
2321     if (errorCB != nullptr) {
2322         napi_value result = nullptr;
2323         napi_create_int32(env, errorCB->execResult, &result);
2324         NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, errorCB->cbBase.deferred, result));
2325         NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, errorCB->cbBase.asyncWork));
2326     }
2327     delete errorCB;
2328     errorCB = nullptr;
2329     HILOG_INFO("CallErrorPromiseCompleteCB,  main event thread complete end.");
2330 }
2331 
CallErrorExecuteCB(napi_env env,void * data)2332 void CallErrorExecuteCB(napi_env env, void *data)
2333 {
2334     HILOG_INFO("CallErrorExecuteCB, worker pool thread execute.");
2335     DAHelperErrorCB *errorCB = static_cast<DAHelperErrorCB *>(data);
2336     if (errorCB != nullptr) {
2337         errorCB->execResult = INVALID_PARAMETER;
2338     } else {
2339         HILOG_ERROR("CallErrorExecuteCB, errorCB is null");
2340     }
2341     HILOG_INFO("CallErrorExecuteCB, worker pool thread execute end.");
2342 }
2343 
CallErrorAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperErrorCB * errorCB)2344 napi_value CallErrorAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperErrorCB *errorCB)
2345 {
2346     HILOG_INFO("%{public}s, asyncCallback.", __func__);
2347     if (args == nullptr || errorCB == nullptr) {
2348         HILOG_ERROR("%{public}s, param or errorCB is null.", __func__);
2349         return nullptr;
2350     }
2351     napi_value resourceName = nullptr;
2352     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2353 
2354     napi_valuetype valuetype = napi_undefined;
2355     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
2356     if (valuetype == napi_function) {
2357         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &errorCB->cbBase.cbInfo.callback));
2358     }
2359 
2360     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, CallErrorExecuteCB, CallErrorAsyncCompleteCB,
2361                        static_cast<void *>(errorCB), &errorCB->cbBase.asyncWork));
2362     NAPI_CALL(env, napi_queue_async_work_with_qos(env, errorCB->cbBase.asyncWork, napi_qos_user_initiated));
2363     napi_value result = nullptr;
2364     NAPI_CALL(env, napi_get_null(env, &result));
2365     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
2366     return result;
2367 }
2368 
CallErrorPromise(napi_env env,DAHelperErrorCB * errorCB)2369 napi_value CallErrorPromise(napi_env env, DAHelperErrorCB *errorCB)
2370 {
2371     HILOG_INFO("%{public}s, promise.", __func__);
2372     if (errorCB == nullptr) {
2373         HILOG_ERROR("%{public}s, param is null.", __func__);
2374         return nullptr;
2375     }
2376     napi_value resourceName;
2377     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2378     napi_deferred deferred;
2379     napi_value promise = nullptr;
2380     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
2381     errorCB->cbBase.deferred = deferred;
2382 
2383     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, CallErrorExecuteCB, CallErrorPromiseCompleteCB,
2384                        static_cast<void *>(errorCB), &errorCB->cbBase.asyncWork));
2385     NAPI_CALL(env, napi_queue_async_work_with_qos(env, errorCB->cbBase.asyncWork, napi_qos_user_initiated));
2386     HILOG_INFO("%{public}s, promise end.", __func__);
2387     return promise;
2388 }
2389 
CallErrorWrap(napi_env env,napi_value thisVar,napi_callback_info info,napi_value * args,bool isPromise)2390 napi_value CallErrorWrap(napi_env env, napi_value thisVar, napi_callback_info info, napi_value *args, bool isPromise)
2391 {
2392     HILOG_INFO("%{public}s, called", __func__);
2393     DAHelperErrorCB *errorCB = new DAHelperErrorCB;
2394     errorCB->cbBase.cbInfo.env = env;
2395     errorCB->cbBase.asyncWork = nullptr;
2396     errorCB->cbBase.deferred = nullptr;
2397     errorCB->cbBase.ability = nullptr;
2398     napi_value ret = nullptr;
2399     if (!isPromise) {
2400         ret = CallErrorAsync(env, args, ARGS_FOUR, errorCB);
2401     } else {
2402         ret = CallErrorPromise(env, errorCB);
2403     }
2404     if (ret == nullptr) {
2405         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
2406         delete errorCB;
2407         errorCB = nullptr;
2408         ret = WrapVoidToJS(env);
2409     }
2410     HILOG_INFO("%{public}s,end", __func__);
2411     return ret;
2412 }
2413 
CallExecuteCB(napi_env env,void * data)2414 void CallExecuteCB(napi_env env, void *data)
2415 {
2416     HILOG_INFO("CallExecuteCB, worker pool thread execute.");
2417     DAHelperCallCB *callCB = static_cast<DAHelperCallCB *>(data);
2418     auto dataAbilityHelper = callCB->dataAbilityHelper;
2419     if (dataAbilityHelper != nullptr) {
2420         callCB->execResult = INVALID_PARAMETER;
2421         if (!callCB->uri.empty()) {
2422             OHOS::Uri uri(callCB->uri);
2423             callCB->result = dataAbilityHelper->Call(uri, callCB->method, callCB->arg, callCB->pacMap);
2424             callCB->execResult = NO_ERROR;
2425         }
2426     } else {
2427         HILOG_ERROR("CallExecuteCB, dataAbilityHelper == nullptr.");
2428     }
2429     HILOG_INFO("CallExecuteCB, worker pool thread execute end.");
2430 }
2431 
ExcludeTag(const std::string & jsonString,const std::string & tagString)2432 static std::string ExcludeTag(const std::string& jsonString, const std::string& tagString)
2433 {
2434     HILOG_DEBUG("enter");
2435     size_t pos = jsonString.find(tagString);
2436     if (pos == std::string::npos) {
2437         return jsonString;
2438     }
2439     std::string valueString = jsonString.substr(pos);
2440     pos = valueString.find(":");
2441     if (pos == std::string::npos) {
2442         return "";
2443     }
2444     size_t valuePos = pos + 1;
2445     while (valuePos < valueString.size()) {
2446         if (valueString.at(valuePos) != ' ' && valueString.at(valuePos) != '\t') {
2447             break;
2448         }
2449         valuePos++;
2450     }
2451     if (valuePos >= valueString.size()) {
2452         return "";
2453     }
2454     HILOG_DEBUG("exit");
2455     valueString = valueString.substr(valuePos);
2456     return valueString.substr(0, valueString.size() - 1);
2457 }
2458 
CallPacMapValue(napi_env env,std::shared_ptr<AppExecFwk::PacMap> result)2459 napi_value CallPacMapValue(napi_env env, std::shared_ptr<AppExecFwk::PacMap> result)
2460 {
2461     napi_value value = nullptr;
2462 
2463     NAPI_CALL(env, napi_create_object(env, &value));
2464     napi_value napiResult = nullptr;
2465     if (result != nullptr) {
2466         std::string resultWithoutTag = ExcludeTag(result->ToString(), "pacmap");
2467         napi_create_string_utf8(env, resultWithoutTag.c_str(), NAPI_AUTO_LENGTH, &napiResult);
2468         NAPI_CALL(env, napi_set_named_property(env, value, "result", napiResult));
2469     } else {
2470         HILOG_ERROR("Return result is nullptr");
2471     }
2472     return value;
2473 }
2474 
CallAsyncCompleteCB(napi_env env,napi_status status,void * data)2475 void CallAsyncCompleteCB(napi_env env, napi_status status, void *data)
2476 {
2477     HILOG_INFO("CallAsyncCompleteCB, main event thread complete.");
2478     DAHelperCallCB *callCB = static_cast<DAHelperCallCB *>(data);
2479     napi_value callback = nullptr;
2480     napi_value undefined = nullptr;
2481     napi_value result[ARGS_TWO] = {nullptr};
2482     napi_value callResult = nullptr;
2483     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
2484     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callCB->cbBase.cbInfo.callback, &callback));
2485 
2486     result[PARAM0] = GetCallbackErrorValue(env, callCB->execResult);
2487     result[PARAM1] = CallPacMapValue(env, callCB->result);
2488     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
2489 
2490     if (callCB->cbBase.cbInfo.callback != nullptr) {
2491         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, callCB->cbBase.cbInfo.callback));
2492     }
2493     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, callCB->cbBase.asyncWork));
2494     delete callCB;
2495     callCB = nullptr;
2496     HILOG_INFO("CallAsyncCompleteCB, main event thread complete end.");
2497 }
2498 
CallPromiseCompleteCB(napi_env env,napi_status status,void * data)2499 void CallPromiseCompleteCB(napi_env env, napi_status status, void *data)
2500 {
2501     HILOG_INFO("CallPromiseCompleteCB, main event thread complete.");
2502     DAHelperCallCB *callCB = static_cast<DAHelperCallCB *>(data);
2503     napi_value result = nullptr;
2504     result = CallPacMapValue(env, callCB->result);
2505     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, callCB->cbBase.deferred, result));
2506     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, callCB->cbBase.asyncWork));
2507     delete callCB;
2508     callCB = nullptr;
2509     HILOG_INFO("CallPromiseCompleteCB,  main event thread complete end.");
2510 }
2511 
CallAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperCallCB * callCB)2512 napi_value CallAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperCallCB *callCB)
2513 {
2514     HILOG_INFO("%{public}s, asyncCallback.", __func__);
2515     if (args == nullptr || callCB == nullptr) {
2516         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2517         return nullptr;
2518     }
2519     napi_value resourceName = nullptr;
2520     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2521 
2522     napi_valuetype valuetype = napi_undefined;
2523     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
2524     if (valuetype == napi_function) {
2525         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &callCB->cbBase.cbInfo.callback));
2526     }
2527 
2528     NAPI_CALL(env,
2529         napi_create_async_work(env,
2530             nullptr,
2531             resourceName,
2532             CallExecuteCB,
2533             CallAsyncCompleteCB,
2534             static_cast<void *>(callCB),
2535             &callCB->cbBase.asyncWork));
2536     NAPI_CALL(env, napi_queue_async_work(env, callCB->cbBase.asyncWork));
2537     napi_value result = nullptr;
2538     NAPI_CALL(env, napi_get_null(env, &result));
2539     HILOG_INFO("%{public}s, asyncCallback end", __func__);
2540     return result;
2541 }
2542 
CallPromise(napi_env env,DAHelperCallCB * callCB)2543 napi_value CallPromise(napi_env env, DAHelperCallCB *callCB)
2544 {
2545     HILOG_INFO("%{public}s, promise.", __func__);
2546     if (callCB == nullptr) {
2547         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2548         return nullptr;
2549     }
2550     napi_value resourceName;
2551     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2552     napi_deferred deferred;
2553     napi_value promise = nullptr;
2554     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
2555     callCB->cbBase.deferred = deferred;
2556 
2557     NAPI_CALL(env,
2558         napi_create_async_work(env,
2559             nullptr,
2560             resourceName,
2561             CallExecuteCB,
2562             CallPromiseCompleteCB,
2563             static_cast<void *>(callCB),
2564             &callCB->cbBase.asyncWork));
2565     NAPI_CALL(env, napi_queue_async_work(env, callCB->cbBase.asyncWork));
2566     HILOG_INFO("%{public}s, promise end", __func__);
2567     return promise;
2568 }
2569 
SetPacMapObject(AppExecFwk::PacMap & pacMap,const napi_env & env,std::string keyStr,napi_value value)2570 void SetPacMapObject(AppExecFwk::PacMap &pacMap, const napi_env &env, std::string keyStr, napi_value value)
2571 {
2572     napi_valuetype valueType = napi_undefined;
2573     napi_typeof(env, value, &valueType);
2574     if (valueType == napi_string) {
2575         std::string valueString = UnwrapStringFromJS(env, value);
2576         pacMap.PutStringValue(keyStr, valueString);
2577     } else if (valueType == napi_number) {
2578         double valueNumber = 0;
2579         napi_get_value_double(env, value, &valueNumber);
2580         pacMap.PutDoubleValue(keyStr, valueNumber);
2581     } else if (valueType == napi_boolean) {
2582         bool valueBool = false;
2583         napi_get_value_bool(env, value, &valueBool);
2584         pacMap.PutBooleanValue(keyStr, valueBool);
2585     } else if (valueType == napi_null) {
2586         pacMap.PutObject(keyStr, nullptr);
2587     } else if (valueType == napi_object) {
2588         pacMap.PutStringValueArray(keyStr, ConvertStringVector(env, value));
2589     } else {
2590         HILOG_ERROR("SetPacMapObject pacMap type error");
2591     }
2592 }
2593 
AnalysisPacMap(AppExecFwk::PacMap & pacMap,const napi_env & env,const napi_value & arg)2594 void AnalysisPacMap(AppExecFwk::PacMap &pacMap, const napi_env &env, const napi_value &arg)
2595 {
2596     napi_value keys = nullptr;
2597     napi_get_property_names(env, arg, &keys);
2598     uint32_t arrLen = 0;
2599     napi_status status = napi_get_array_length(env, keys, &arrLen);
2600     if (status != napi_ok) {
2601         HILOG_ERROR("AnalysisPacMap errr");
2602         return;
2603     }
2604     for (size_t i = 0; i < arrLen; ++i) {
2605         napi_value key = nullptr;
2606         (void)napi_get_element(env, keys, i, &key);
2607         std::string keyStr = UnwrapStringFromJS(env, key);
2608         napi_value value = nullptr;
2609         napi_get_property(env, arg, key, &value);
2610         SetPacMapObject(pacMap, env, keyStr, value);
2611     }
2612 }
2613 
2614 /**
2615  * @brief Call processing function.
2616  *
2617  * @param env The environment that the Node-API call is invoked under.
2618  * @param callCB Process data asynchronously.
2619  *
2620  * @return Return JS data successfully, otherwise return nullptr.
2621  */
CallWrap(napi_env env,napi_callback_info info,DAHelperCallCB * callCB)2622 napi_value CallWrap(napi_env env, napi_callback_info info, DAHelperCallCB *callCB)
2623 {
2624     HILOG_INFO("%{public}s, called", __func__);
2625     size_t argcAsync = ARGS_FIVE;
2626     const size_t argcPromise = ARGS_FOUR;
2627     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
2628     napi_value args[ARGS_MAX_COUNT] = {nullptr};
2629     napi_value ret = nullptr;
2630     napi_value thisVar = nullptr;
2631     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
2632     if (argcAsync != ARGS_FOUR && argcAsync != ARGS_FIVE) {
2633         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
2634         return nullptr;
2635     }
2636     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
2637         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
2638         return nullptr;
2639     }
2640     bool isPromise = (argcAsync <= argcPromise) ? true : false;
2641     napi_valuetype valuetype = napi_undefined;
2642     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
2643     if (valuetype == napi_string) {
2644         callCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
2645     } else {
2646         return CallErrorWrap(env, thisVar, info, args, isPromise);
2647     }
2648     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
2649     if (valuetype == napi_string) {
2650         callCB->method = NapiValueToStringUtf8(env, args[PARAM1]);
2651     } else {
2652         return CallErrorWrap(env, thisVar, info, args, isPromise);
2653     }
2654     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valuetype));
2655     if (valuetype == napi_string) {
2656         callCB->arg = NapiValueToStringUtf8(env, args[PARAM2]);
2657     }
2658     NAPI_CALL(env, napi_typeof(env, args[PARAM3], &valuetype));
2659     if (valuetype == napi_object) {
2660         AnalysisPacMap(callCB->pacMap, env, args[PARAM3]);
2661     }
2662     GetDataAbilityHelper(env, thisVar, callCB->dataAbilityHelper);
2663     if (!isPromise) {
2664         ret = CallAsync(env, args, ARGS_TWO, callCB);
2665     } else {
2666         ret = CallPromise(env, callCB);
2667     }
2668     return ret;
2669 }
2670 
2671 /**
2672  * @brief DataAbilityHelper NAPI method : call.
2673  *
2674  * @param env The environment that the Node-API call is invoked under.
2675  * @param info The callback info passed into the callback function.
2676  *
2677  * @return The return value from NAPI C++ to JS for the module.
2678  */
NAPI_Call(napi_env env,napi_callback_info info)2679 napi_value NAPI_Call(napi_env env, napi_callback_info info)
2680 {
2681     HILOG_INFO("%{public}s, called", __func__);
2682     DAHelperCallCB *callCB = new (std::nothrow) DAHelperCallCB;
2683     if (callCB == nullptr) {
2684         HILOG_ERROR("%{public}s, callCB == nullptr.", __func__);
2685         return WrapVoidToJS(env);
2686     }
2687     callCB->cbBase.cbInfo.env = env;
2688     callCB->cbBase.asyncWork = nullptr;
2689     callCB->cbBase.deferred = nullptr;
2690     callCB->cbBase.ability = nullptr;
2691 
2692     napi_value ret = CallWrap(env, info, callCB);
2693     if (ret == nullptr) {
2694         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
2695         delete callCB;
2696         callCB = nullptr;
2697         ret = WrapVoidToJS(env);
2698     }
2699     HILOG_INFO("%{public}s, called end", __func__);
2700     return ret;
2701 }
2702 
2703 /**
2704  * @brief DataAbilityHelper NAPI method : insert.
2705  *
2706  * @param env The environment that the Node-API call is invoked under.
2707  * @param info The callback info passed into the callback function.
2708  *
2709  * @return The return value from NAPI C++ to JS for the module.
2710  */
NAPI_OpenFile(napi_env env,napi_callback_info info)2711 napi_value NAPI_OpenFile(napi_env env, napi_callback_info info)
2712 {
2713     HILOG_INFO("%{public}s,called", __func__);
2714     DAHelperOpenFileCB *openFileCB = new (std::nothrow) DAHelperOpenFileCB;
2715     if (openFileCB == nullptr) {
2716         HILOG_ERROR("%{public}s, openFileCB == nullptr.", __func__);
2717         return WrapVoidToJS(env);
2718     }
2719     openFileCB->cbBase.cbInfo.env = env;
2720     openFileCB->cbBase.asyncWork = nullptr;
2721     openFileCB->cbBase.deferred = nullptr;
2722     openFileCB->cbBase.ability = nullptr;
2723 
2724     napi_value ret = OpenFileWrap(env, info, openFileCB);
2725     if (ret == nullptr) {
2726         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
2727         delete openFileCB;
2728         openFileCB = nullptr;
2729         ret = WrapVoidToJS(env);
2730     }
2731     HILOG_INFO("%{public}s,end", __func__);
2732     return ret;
2733 }
2734 
2735 /**
2736  * @brief Insert processing function.
2737  *
2738  * @param env The environment that the Node-API call is invoked under.
2739  * @param insertCB Process data asynchronously.
2740  *
2741  * @return Return JS data successfully, otherwise return nullptr.
2742  */
OpenFileWrap(napi_env env,napi_callback_info info,DAHelperOpenFileCB * openFileCB)2743 napi_value OpenFileWrap(napi_env env, napi_callback_info info, DAHelperOpenFileCB *openFileCB)
2744 {
2745     HILOG_INFO("%{public}s,called", __func__);
2746     size_t argcAsync = ARGS_THREE;
2747     const size_t argcPromise = ARGS_TWO;
2748     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
2749     napi_value args[ARGS_MAX_COUNT] = {nullptr};
2750     napi_value ret = nullptr;
2751     napi_value thisVar = nullptr;
2752 
2753     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
2754     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
2755         HILOG_ERROR("%{public}s, argument count error.", __func__);
2756         return nullptr;
2757     }
2758 
2759     napi_valuetype valuetype = napi_undefined;
2760     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
2761     if (valuetype == napi_string) {
2762         openFileCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
2763         HILOG_INFO("%{public}s,uri=%{public}s", __func__, openFileCB->uri.c_str());
2764     }
2765 
2766     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
2767     if (valuetype == napi_string) {
2768         openFileCB->mode = NapiValueToStringUtf8(env, args[PARAM1]);
2769         HILOG_INFO("%{public}s,mode=%{public}s", __func__, openFileCB->mode.c_str());
2770     }
2771     GetDataAbilityHelper(env, thisVar, openFileCB->dataAbilityHelper);
2772 
2773     if (argcAsync > argcPromise) {
2774         ret = OpenFileAsync(env, args, ARGS_TWO, openFileCB);
2775     } else {
2776         ret = OpenFilePromise(env, openFileCB);
2777     }
2778     HILOG_INFO("%{public}s,end", __func__);
2779     return ret;
2780 }
2781 
OpenFileAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperOpenFileCB * openFileCB)2782 napi_value OpenFileAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperOpenFileCB *openFileCB)
2783 {
2784     HILOG_INFO("%{public}s, asyncCallback.", __func__);
2785     if (args == nullptr || openFileCB == nullptr) {
2786         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2787         return nullptr;
2788     }
2789     napi_value resourceName = 0;
2790     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2791 
2792     napi_valuetype valuetype = napi_undefined;
2793     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
2794     if (valuetype == napi_function) {
2795         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &openFileCB->cbBase.cbInfo.callback));
2796     }
2797 
2798     NAPI_CALL(env,
2799         napi_create_async_work(env,
2800             nullptr,
2801             resourceName,
2802             OpenFileExecuteCB,
2803             OpenFileAsyncCompleteCB,
2804             static_cast<void *>(openFileCB),
2805             &openFileCB->cbBase.asyncWork));
2806     NAPI_CALL(env, napi_queue_async_work_with_qos(env, openFileCB->cbBase.asyncWork, napi_qos_user_initiated));
2807     napi_value result = nullptr;
2808     NAPI_CALL(env, napi_get_null(env, &result));
2809     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
2810     return result;
2811 }
2812 
OpenFilePromise(napi_env env,DAHelperOpenFileCB * openFileCB)2813 napi_value OpenFilePromise(napi_env env, DAHelperOpenFileCB *openFileCB)
2814 {
2815     HILOG_INFO("%{public}s, promise.", __func__);
2816     if (openFileCB == nullptr) {
2817         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2818         return nullptr;
2819     }
2820     napi_value resourceName;
2821     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2822     napi_deferred deferred;
2823     napi_value promise = nullptr;
2824     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
2825     openFileCB->cbBase.deferred = deferred;
2826 
2827     NAPI_CALL(env,
2828         napi_create_async_work(env,
2829             nullptr,
2830             resourceName,
2831             OpenFileExecuteCB,
2832             OpenFilePromiseCompleteCB,
2833             static_cast<void *>(openFileCB),
2834             &openFileCB->cbBase.asyncWork));
2835     NAPI_CALL(env, napi_queue_async_work_with_qos(env, openFileCB->cbBase.asyncWork, napi_qos_user_initiated));
2836     HILOG_INFO("%{public}s, promise end.", __func__);
2837     return promise;
2838 }
2839 
OpenFileExecuteCB(napi_env env,void * data)2840 void OpenFileExecuteCB(napi_env env, void *data)
2841 {
2842     HILOG_INFO("NAPI_OpenFile, worker pool thread execute.");
2843     DAHelperOpenFileCB *OpenFileCB = static_cast<DAHelperOpenFileCB *>(data);
2844     auto dataAbilityHelper = OpenFileCB->dataAbilityHelper;
2845     if (dataAbilityHelper != nullptr) {
2846         OpenFileCB->execResult = INVALID_PARAMETER;
2847         if (!OpenFileCB->uri.empty()) {
2848             OHOS::Uri uri(OpenFileCB->uri);
2849             OpenFileCB->result = dataAbilityHelper->OpenFile(uri, OpenFileCB->mode);
2850             OpenFileCB->execResult = NO_ERROR;
2851         } else {
2852             HILOG_ERROR("NAPI_OpenFile, dataAbilityHelper uri is empty");
2853         }
2854     } else {
2855         HILOG_ERROR("NAPI_OpenFile, dataAbilityHelper == nullptr");
2856     }
2857     HILOG_INFO("NAPI_OpenFile, worker pool thread execute end.");
2858 }
2859 
OpenFileAsyncCompleteCB(napi_env env,napi_status status,void * data)2860 void OpenFileAsyncCompleteCB(napi_env env, napi_status status, void *data)
2861 {
2862     HILOG_INFO("NAPI_OpenFile, main event thread complete.");
2863     DAHelperOpenFileCB *OpenFileCB = static_cast<DAHelperOpenFileCB *>(data);
2864     napi_value callback = nullptr;
2865     napi_value undefined = nullptr;
2866     napi_value result[ARGS_TWO] = {nullptr};
2867     napi_value callResult = nullptr;
2868     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
2869     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, OpenFileCB->cbBase.cbInfo.callback, &callback));
2870 
2871     result[PARAM0] = GetCallbackErrorValue(env, OpenFileCB->execResult);
2872     napi_create_int32(env, OpenFileCB->result, &result[PARAM1]);
2873     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
2874 
2875     if (OpenFileCB->cbBase.cbInfo.callback != nullptr) {
2876         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, OpenFileCB->cbBase.cbInfo.callback));
2877     }
2878     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, OpenFileCB->cbBase.asyncWork));
2879     delete OpenFileCB;
2880     OpenFileCB = nullptr;
2881     HILOG_INFO("NAPI_OpenFile, main event thread complete end.");
2882 }
2883 
OpenFilePromiseCompleteCB(napi_env env,napi_status status,void * data)2884 void OpenFilePromiseCompleteCB(napi_env env, napi_status status, void *data)
2885 {
2886     HILOG_INFO("NAPI_OpenFileCB,  main event thread complete.");
2887     DAHelperOpenFileCB *OpenFileCB = static_cast<DAHelperOpenFileCB *>(data);
2888     napi_value result = nullptr;
2889     napi_create_int32(env, OpenFileCB->result, &result);
2890     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, OpenFileCB->cbBase.deferred, result));
2891     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, OpenFileCB->cbBase.asyncWork));
2892     delete OpenFileCB;
2893     OpenFileCB = nullptr;
2894     HILOG_INFO("NAPI_OpenFileCB,  main event thread complete end.");
2895 }
2896 
2897 /**
2898  * @brief DataAbilityHelper NAPI method : insert.
2899  *
2900  * @param env The environment that the Node-API call is invoked under.
2901  * @param info The callback info passed into the callback function.
2902  *
2903  * @return The return value from NAPI C++ to JS for the module.
2904  */
NAPI_BatchInsert(napi_env env,napi_callback_info info)2905 napi_value NAPI_BatchInsert(napi_env env, napi_callback_info info)
2906 {
2907     HILOG_INFO("%{public}s,called", __func__);
2908     DAHelperBatchInsertCB *BatchInsertCB = new (std::nothrow) DAHelperBatchInsertCB;
2909     if (BatchInsertCB == nullptr) {
2910         HILOG_ERROR("%{public}s, BatchInsertCB == nullptr.", __func__);
2911         return WrapVoidToJS(env);
2912     }
2913     BatchInsertCB->cbBase.cbInfo.env = env;
2914     BatchInsertCB->cbBase.asyncWork = nullptr;
2915     BatchInsertCB->cbBase.deferred = nullptr;
2916     BatchInsertCB->cbBase.ability = nullptr;
2917 
2918     napi_value ret = BatchInsertWrap(env, info, BatchInsertCB);
2919     if (ret == nullptr) {
2920         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
2921         delete BatchInsertCB;
2922         BatchInsertCB = nullptr;
2923         ret = WrapVoidToJS(env);
2924     }
2925     HILOG_INFO("%{public}s,end", __func__);
2926     return ret;
2927 }
2928 
NapiValueObject(napi_env env,napi_value param)2929 std::vector<NativeRdb::ValuesBucket> NapiValueObject(napi_env env, napi_value param)
2930 {
2931     HILOG_INFO("%{public}s,called", __func__);
2932     std::vector<NativeRdb::ValuesBucket> result;
2933     UnwrapArrayObjectFromJS(env, param, result);
2934     return result;
2935 }
2936 
UnwrapArrayObjectFromJS(napi_env env,napi_value param,std::vector<NativeRdb::ValuesBucket> & value)2937 bool UnwrapArrayObjectFromJS(napi_env env, napi_value param, std::vector<NativeRdb::ValuesBucket> &value)
2938 {
2939     HILOG_INFO("%{public}s,called", __func__);
2940     uint32_t arraySize = 0;
2941     napi_value jsValue = nullptr;
2942     std::string strValue = "";
2943 
2944     if (!IsArrayForNapiValue(env, param, arraySize)) {
2945         HILOG_INFO("%{public}s, IsArrayForNapiValue is false", __func__);
2946         return false;
2947     }
2948 
2949     value.clear();
2950     for (uint32_t i = 0; i < arraySize; i++) {
2951         jsValue = nullptr;
2952         if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
2953             HILOG_INFO("%{public}s, napi_get_element is false", __func__);
2954             return false;
2955         }
2956 
2957         NativeRdb::ValuesBucket valueBucket;
2958         valueBucket.Clear();
2959         AnalysisValuesBucket(valueBucket, env, jsValue);
2960 
2961         value.push_back(valueBucket);
2962     }
2963     HILOG_INFO("%{public}s,end", __func__);
2964     return true;
2965 }
2966 
2967 /**
2968  * @brief Insert processing function.
2969  *
2970  * @param env The environment that the Node-API call is invoked under.
2971  * @param insertCB Process data asynchronously.
2972  *
2973  * @return Return JS data successfully, otherwise return nullptr.
2974  */
BatchInsertWrap(napi_env env,napi_callback_info info,DAHelperBatchInsertCB * batchInsertCB)2975 napi_value BatchInsertWrap(napi_env env, napi_callback_info info, DAHelperBatchInsertCB *batchInsertCB)
2976 {
2977     HILOG_INFO("%{public}s,called", __func__);
2978     size_t argcAsync = ARGS_THREE;
2979     const size_t argcPromise = ARGS_TWO;
2980     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
2981     napi_value args[ARGS_MAX_COUNT] = {nullptr};
2982     napi_value ret = nullptr;
2983     napi_value thisVar = nullptr;
2984 
2985     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
2986     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
2987         HILOG_ERROR("%{public}s, Wrong argument count", __func__);
2988         return nullptr;
2989     }
2990 
2991     napi_valuetype valuetype = napi_undefined;
2992     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
2993     if (valuetype == napi_string) {
2994         batchInsertCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
2995         HILOG_INFO("%{public}s,uri=%{public}s", __func__, batchInsertCB->uri.c_str());
2996     }
2997 
2998     batchInsertCB->values = NapiValueObject(env, args[PARAM1]);
2999     GetDataAbilityHelper(env, thisVar, batchInsertCB->dataAbilityHelper);
3000 
3001     if (argcAsync > argcPromise) {
3002         ret = BatchInsertAsync(env, args, ARGS_TWO, batchInsertCB);
3003     } else {
3004         ret = BatchInsertPromise(env, batchInsertCB);
3005     }
3006     HILOG_INFO("%{public}s,end", __func__);
3007     return ret;
3008 }
3009 
BatchInsertAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperBatchInsertCB * batchInsertCB)3010 napi_value BatchInsertAsync(
3011     napi_env env, napi_value *args, const size_t argCallback, DAHelperBatchInsertCB *batchInsertCB)
3012 {
3013     HILOG_INFO("%{public}s, asyncCallback.", __func__);
3014     if (args == nullptr || batchInsertCB == nullptr) {
3015         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
3016         return nullptr;
3017     }
3018     napi_value resourceName = nullptr;
3019     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3020 
3021     napi_valuetype valuetype = napi_undefined;
3022     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
3023     if (valuetype == napi_function) {
3024         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &batchInsertCB->cbBase.cbInfo.callback));
3025     }
3026 
3027     NAPI_CALL(env,
3028         napi_create_async_work(env,
3029             nullptr,
3030             resourceName,
3031             BatchInsertExecuteCB,
3032             BatchInsertAsyncCompleteCB,
3033             static_cast<void *>(batchInsertCB),
3034             &batchInsertCB->cbBase.asyncWork));
3035     NAPI_CALL(env, napi_queue_async_work(env, batchInsertCB->cbBase.asyncWork));
3036     napi_value result = nullptr;
3037     NAPI_CALL(env, napi_get_null(env, &result));
3038     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
3039     return result;
3040 }
3041 
BatchInsertPromise(napi_env env,DAHelperBatchInsertCB * batchInsertCB)3042 napi_value BatchInsertPromise(napi_env env, DAHelperBatchInsertCB *batchInsertCB)
3043 {
3044     HILOG_INFO("%{public}s, promise.", __func__);
3045     if (batchInsertCB == nullptr) {
3046         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
3047         return nullptr;
3048     }
3049     napi_value resourceName;
3050     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3051     napi_deferred deferred;
3052     napi_value promise = nullptr;
3053     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
3054     batchInsertCB->cbBase.deferred = deferred;
3055 
3056     NAPI_CALL(env,
3057         napi_create_async_work(env,
3058             nullptr,
3059             resourceName,
3060             BatchInsertExecuteCB,
3061             BatchInsertPromiseCompleteCB,
3062             static_cast<void *>(batchInsertCB),
3063             &batchInsertCB->cbBase.asyncWork));
3064     NAPI_CALL(env, napi_queue_async_work(env, batchInsertCB->cbBase.asyncWork));
3065     HILOG_INFO("%{public}s, promise end.", __func__);
3066     return promise;
3067 }
3068 
BatchInsertExecuteCB(napi_env env,void * data)3069 void BatchInsertExecuteCB(napi_env env, void *data)
3070 {
3071     HILOG_INFO("NAPI_BatchInsert, worker pool thread execute.");
3072     DAHelperBatchInsertCB *batchInsertCB = static_cast<DAHelperBatchInsertCB *>(data);
3073     auto dataAbilityHelper = batchInsertCB->dataAbilityHelper;
3074     if (dataAbilityHelper != nullptr) {
3075         batchInsertCB->execResult = INVALID_PARAMETER;
3076         if (!batchInsertCB->uri.empty()) {
3077             OHOS::Uri uri(batchInsertCB->uri);
3078             batchInsertCB->result = dataAbilityHelper->BatchInsert(uri, batchInsertCB->values);
3079             batchInsertCB->execResult = NO_ERROR;
3080         } else {
3081             HILOG_ERROR("NAPI_BatchInsert, dataAbilityHelper uri is empyt");
3082         }
3083     } else {
3084         HILOG_ERROR("NAPI_BatchInsert, dataAbilityHelper == nullptr");
3085     }
3086     HILOG_INFO("NAPI_BatchInsert, worker pool thread execute end.");
3087 }
3088 
BatchInsertAsyncCompleteCB(napi_env env,napi_status status,void * data)3089 void BatchInsertAsyncCompleteCB(napi_env env, napi_status status, void *data)
3090 {
3091     HILOG_INFO("NAPI_BatchInsert, main event thread complete.");
3092     DAHelperBatchInsertCB *BatchInsertCB = static_cast<DAHelperBatchInsertCB *>(data);
3093     napi_value callback = nullptr;
3094     napi_value undefined = nullptr;
3095     napi_value result[ARGS_TWO] = {nullptr};
3096     napi_value callResult = nullptr;
3097     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
3098     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, BatchInsertCB->cbBase.cbInfo.callback, &callback));
3099 
3100     result[PARAM0] = GetCallbackErrorValue(env, BatchInsertCB->execResult);
3101     napi_create_int32(env, BatchInsertCB->result, &result[PARAM1]);
3102     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
3103 
3104     if (BatchInsertCB->cbBase.cbInfo.callback != nullptr) {
3105         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, BatchInsertCB->cbBase.cbInfo.callback));
3106     }
3107     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, BatchInsertCB->cbBase.asyncWork));
3108     delete BatchInsertCB;
3109     BatchInsertCB = nullptr;
3110     HILOG_INFO("NAPI_BatchInsert, main event thread complete end.");
3111 }
3112 
BatchInsertPromiseCompleteCB(napi_env env,napi_status status,void * data)3113 void BatchInsertPromiseCompleteCB(napi_env env, napi_status status, void *data)
3114 {
3115     HILOG_INFO("NAPI_BatchInsertCB,  main event thread complete.");
3116     DAHelperBatchInsertCB *BatchInsertCB = static_cast<DAHelperBatchInsertCB *>(data);
3117     napi_value result = nullptr;
3118     napi_create_int32(env, BatchInsertCB->result, &result);
3119     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, BatchInsertCB->cbBase.deferred, result));
3120     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, BatchInsertCB->cbBase.asyncWork));
3121     delete BatchInsertCB;
3122     BatchInsertCB = nullptr;
3123     HILOG_INFO("NAPI_BatchInsertCB,  main event thread complete end.");
3124 }
3125 
3126 /**
3127  * @brief DataAbilityHelper NAPI method : insert.
3128  *
3129  * @param env The environment that the Node-API call is invoked under.
3130  * @param info The callback info passed into the callback function.
3131  *
3132  * @return The return value from NAPI C++ to JS for the module.
3133  */
NAPI_Query(napi_env env,napi_callback_info info)3134 napi_value NAPI_Query(napi_env env, napi_callback_info info)
3135 {
3136     HILOG_INFO("NAPI_Query called");
3137     DAHelperQueryCB *queryCB = new DAHelperQueryCB;
3138     queryCB->cbBase.cbInfo.env = env;
3139     queryCB->cbBase.asyncWork = nullptr;
3140     queryCB->cbBase.deferred = nullptr;
3141     queryCB->cbBase.ability = nullptr;
3142 
3143     napi_value ret = QueryWrap(env, info, queryCB);
3144     if (ret == nullptr) {
3145         HILOG_ERROR("ret == nullptr");
3146         delete queryCB;
3147         queryCB = nullptr;
3148         ret = WrapVoidToJS(env);
3149     }
3150     HILOG_INFO("NAPI_Query end");
3151     return ret;
3152 }
3153 
3154 /**
3155  * @brief Insert processing function.
3156  *
3157  * @param env The environment that the Node-API call is invoked under.
3158  * @param insertCB Process data asynchronously.
3159  *
3160  * @return Return JS data successfully, otherwise return nullptr.
3161  */
QueryWrap(napi_env env,napi_callback_info info,DAHelperQueryCB * queryCB)3162 napi_value QueryWrap(napi_env env, napi_callback_info info, DAHelperQueryCB *queryCB)
3163 {
3164     size_t argcAsync = ARGS_FOUR;
3165     const size_t argcPromise = ARGS_THREE;
3166     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
3167     napi_value args[ARGS_MAX_COUNT] = {nullptr};
3168     napi_value ret = nullptr;
3169     napi_value thisVar = nullptr;
3170 
3171     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
3172     if (argcAsync > argCountWithAsync) {
3173         HILOG_ERROR("Wrong argument count.");
3174         return nullptr;
3175     }
3176 
3177     napi_valuetype valuetype = napi_undefined;
3178     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
3179     if (valuetype == napi_string) {
3180         queryCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
3181         HILOG_DEBUG("uri=%{public}s", queryCB->uri.c_str());
3182     }
3183 
3184     std::vector<std::string> result;
3185     bool arrayStringbool = NapiValueToArrayStringUtf8(env, args[PARAM1], result);
3186     if (!arrayStringbool) {
3187         HILOG_ERROR("The return value of arraystringbool is false");
3188     }
3189     queryCB->columns = result;
3190 
3191     UnwrapDataAbilityPredicates(queryCB->predicates, env, args[PARAM2]);
3192     GetDataAbilityHelper(env, thisVar, queryCB->dataAbilityHelper);
3193 
3194     if (argcAsync > argcPromise) {
3195         ret = QuerySync(env, args, ARGS_THREE, queryCB);
3196     } else {
3197         ret = QueryPromise(env, queryCB);
3198     }
3199     return ret;
3200 }
3201 
QuerySync(napi_env env,napi_value * args,const size_t argCallback,DAHelperQueryCB * queryCB)3202 napi_value QuerySync(napi_env env, napi_value *args, const size_t argCallback, DAHelperQueryCB *queryCB)
3203 {
3204     HILOG_DEBUG("asyncCallback.");
3205     if (args == nullptr || queryCB == nullptr) {
3206         HILOG_ERROR("param == nullptr.");
3207         return nullptr;
3208     }
3209 
3210     napi_valuetype valuetype = napi_undefined;
3211     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
3212     if (valuetype == napi_function) {
3213         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &queryCB->cbBase.cbInfo.callback));
3214     }
3215 
3216     auto dataAbilityHelper = queryCB->dataAbilityHelper;
3217     if (dataAbilityHelper != nullptr) {
3218         queryCB->execResult = INVALID_PARAMETER;
3219         if (!queryCB->uri.empty()) {
3220             OHOS::Uri uri(queryCB->uri);
3221             auto resultset = dataAbilityHelper->Query(uri, queryCB->columns, queryCB->predicates);
3222             if (resultset != nullptr) {
3223                 queryCB->result = resultset;
3224                 queryCB->execResult = NO_ERROR;
3225             }
3226         }
3227     }
3228 
3229     napi_value callback = nullptr;
3230     NAPI_CALL(env, napi_get_reference_value(env, queryCB->cbBase.cbInfo.callback, &callback));
3231     napi_value result[ARGS_TWO] = {nullptr};
3232     result[PARAM0] = GetCallbackErrorValue(env, queryCB->execResult);
3233     result[PARAM1] = WrapResultSet(env, queryCB->result);
3234     napi_value undefined = nullptr;
3235     NAPI_CALL(env, napi_get_undefined(env, &undefined));
3236     napi_value callResult = nullptr;
3237     NAPI_CALL(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
3238 
3239     if (queryCB->cbBase.cbInfo.callback != nullptr) {
3240         NAPI_CALL(env, napi_delete_reference(env, queryCB->cbBase.cbInfo.callback));
3241     }
3242     delete queryCB;
3243     queryCB = nullptr;
3244 
3245     napi_value ret = nullptr;
3246     NAPI_CALL(env, napi_get_null(env, &ret));
3247     return ret;
3248 }
3249 
QueryPromise(napi_env env,DAHelperQueryCB * queryCB)3250 napi_value QueryPromise(napi_env env, DAHelperQueryCB *queryCB)
3251 {
3252     HILOG_DEBUG("promise.");
3253     if (queryCB == nullptr) {
3254         HILOG_ERROR("param == nullptr.");
3255         return nullptr;
3256     }
3257 
3258     auto dataAbilityHelper = queryCB->dataAbilityHelper;
3259     if (dataAbilityHelper != nullptr) {
3260         if (!queryCB->uri.empty()) {
3261             OHOS::Uri uri(queryCB->uri);
3262             auto resultset = dataAbilityHelper->Query(uri, queryCB->columns, queryCB->predicates);
3263             if (resultset != nullptr) {
3264                 queryCB->result = resultset;
3265             }
3266         }
3267     }
3268 
3269     napi_deferred deferred;
3270     napi_value promise = nullptr;
3271     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
3272     napi_value result = WrapResultSet(env, queryCB->result);
3273     NAPI_CALL(env, napi_resolve_deferred(env, deferred, result));
3274     delete queryCB;
3275     queryCB = nullptr;
3276 
3277     return promise;
3278 }
3279 
WrapResultSet(napi_env env,const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)3280 napi_value WrapResultSet(napi_env env, const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
3281 {
3282     HILOG_DEBUG("called");
3283     if (resultSet == nullptr) {
3284         HILOG_ERROR("input parameter resultSet is nullptr");
3285         return WrapVoidToJS(env);
3286     }
3287 
3288     return RdbJsKit::ResultSetProxy::NewInstance(env, resultSet);
3289 }
3290 
NAPI_ExecuteBatch(napi_env env,napi_callback_info info)3291 napi_value NAPI_ExecuteBatch(napi_env env, napi_callback_info info)
3292 {
3293     HILOG_INFO("%{public}s,start", __func__);
3294     DAHelperExecuteBatchCB *executeBatchCB = new (std::nothrow) DAHelperExecuteBatchCB;
3295     if (executeBatchCB == nullptr) {
3296         HILOG_ERROR("%{public}s, executeBatchCB == nullptr.", __func__);
3297         return WrapVoidToJS(env);
3298     }
3299     executeBatchCB->cbBase.cbInfo.env = env;
3300     executeBatchCB->cbBase.asyncWork = nullptr;
3301     executeBatchCB->cbBase.deferred = nullptr;
3302     executeBatchCB->cbBase.ability = nullptr;
3303 
3304     napi_value ret = ExecuteBatchWrap(env, info, executeBatchCB);
3305     if (ret == nullptr) {
3306         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
3307         delete executeBatchCB;
3308         executeBatchCB = nullptr;
3309         ret = WrapVoidToJS(env);
3310     }
3311     HILOG_INFO("%{public}s,end", __func__);
3312     return ret;
3313 }
3314 
UnwrapArrayOperationFromJS(napi_env env,napi_callback_info info,napi_value param,std::vector<std::shared_ptr<DataAbilityOperation>> & result)3315 bool UnwrapArrayOperationFromJS(
3316     napi_env env, napi_callback_info info, napi_value param, std::vector<std::shared_ptr<DataAbilityOperation>> &result)
3317 {
3318     HILOG_INFO("%{public}s,called", __func__);
3319     uint32_t arraySize = 0;
3320     napi_value jsValue = nullptr;
3321     std::string strValue = "";
3322 
3323     if (!IsArrayForNapiValue(env, param, arraySize)) {
3324         HILOG_ERROR("%{public}s, Wrong argument type ", __func__);
3325         return false;
3326     }
3327     HILOG_INFO("%{public}s, param size:%{public}d ", __func__, arraySize);
3328     result.clear();
3329     for (uint32_t i = 0; i < arraySize; i++) {
3330         jsValue = nullptr;
3331         if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
3332             HILOG_ERROR("%{public}s, get element failed, index:%{public}d ", __func__, i);
3333             return false;
3334         }
3335         std::shared_ptr<DataAbilityOperation> operation = nullptr;
3336         UnwrapDataAbilityOperation(operation, env, jsValue);
3337         HILOG_INFO("%{public}s, UnwrapDataAbilityOperation, index:%{public}d ", __func__, i);
3338         result.push_back(operation);
3339     }
3340     return true;
3341 }
3342 
ExecuteBatchWrap(napi_env env,napi_callback_info info,DAHelperExecuteBatchCB * executeBatchCB)3343 napi_value ExecuteBatchWrap(napi_env env, napi_callback_info info, DAHelperExecuteBatchCB *executeBatchCB)
3344 {
3345     HILOG_INFO("%{public}s,start", __func__);
3346     size_t argcAsync = ARGS_THREE;
3347     const size_t argcPromise = ARGS_TWO;
3348     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
3349     napi_value args[ARGS_MAX_COUNT] = {nullptr};
3350     napi_value ret = nullptr;
3351     napi_value thisVar = nullptr;
3352 
3353     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
3354     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
3355         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
3356         return nullptr;
3357     }
3358 
3359     napi_valuetype valuetype = napi_undefined;
3360     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
3361     if (valuetype == napi_string) {
3362         executeBatchCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
3363         HILOG_INFO("%{public}s,uri=%{public}s", __func__, executeBatchCB->uri.c_str());
3364     } else {
3365         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
3366     }
3367 
3368     std::vector<std::shared_ptr<DataAbilityOperation>> operations;
3369     UnwrapArrayOperationFromJS(env, info, args[PARAM1], operations);
3370     HILOG_INFO("%{public}s,operations size=%{public}zu", __func__, operations.size());
3371     executeBatchCB->operations = operations;
3372     GetDataAbilityHelper(env, thisVar, executeBatchCB->dataAbilityHelper);
3373 
3374     if (argcAsync > argcPromise) {
3375         ret = ExecuteBatchAsync(env, args, argcAsync, argcPromise, executeBatchCB);
3376     } else {
3377         ret = ExecuteBatchPromise(env, executeBatchCB);
3378     }
3379     HILOG_INFO("%{public}s,end", __func__);
3380     return ret;
3381 }
3382 
ExecuteBatchAsync(napi_env env,napi_value * args,size_t argcAsync,const size_t argcPromise,DAHelperExecuteBatchCB * executeBatchCB)3383 napi_value ExecuteBatchAsync(
3384     napi_env env, napi_value *args, size_t argcAsync, const size_t argcPromise, DAHelperExecuteBatchCB *executeBatchCB)
3385 {
3386     HILOG_INFO("%{public}s, asyncCallback start.", __func__);
3387     if (args == nullptr || executeBatchCB == nullptr) {
3388         HILOG_ERROR("%{public}s, param is nullptr.", __func__);
3389         return nullptr;
3390     }
3391     napi_value resourceName = nullptr;
3392     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3393 
3394     napi_valuetype valuetype = napi_undefined;
3395     NAPI_CALL(env, napi_typeof(env, args[argcPromise], &valuetype));
3396     if (valuetype == napi_function) {
3397         NAPI_CALL(env, napi_create_reference(env, args[argcPromise], 1, &executeBatchCB->cbBase.cbInfo.callback));
3398     }
3399 
3400     NAPI_CALL(env,
3401         napi_create_async_work(env,
3402             nullptr,
3403             resourceName,
3404             ExecuteBatchExecuteCB,
3405             ExecuteBatchAsyncCompleteCB,
3406             static_cast<void *>(executeBatchCB),
3407             &executeBatchCB->cbBase.asyncWork));
3408     NAPI_CALL(env, napi_queue_async_work(env, executeBatchCB->cbBase.asyncWork));
3409     napi_value result = nullptr;
3410     NAPI_CALL(env, napi_get_null(env, &result));
3411     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
3412     return result;
3413 }
3414 
ExecuteBatchPromise(napi_env env,DAHelperExecuteBatchCB * executeBatchCB)3415 napi_value ExecuteBatchPromise(napi_env env, DAHelperExecuteBatchCB *executeBatchCB)
3416 {
3417     HILOG_INFO("%{public}s, promise start.", __func__);
3418     if (executeBatchCB == nullptr) {
3419         HILOG_ERROR("%{public}s, param is nullptr.", __func__);
3420         return nullptr;
3421     }
3422     napi_value resourceName;
3423     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3424     napi_deferred deferred;
3425     napi_value promise = nullptr;
3426     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
3427     executeBatchCB->cbBase.deferred = deferred;
3428 
3429     NAPI_CALL(env,
3430         napi_create_async_work(env,
3431             nullptr,
3432             resourceName,
3433             ExecuteBatchExecuteCB,
3434             ExecuteBatchPromiseCompleteCB,
3435             static_cast<void *>(executeBatchCB),
3436             &executeBatchCB->cbBase.asyncWork));
3437     NAPI_CALL(env, napi_queue_async_work(env, executeBatchCB->cbBase.asyncWork));
3438     HILOG_INFO("%{public}s, promise end.", __func__);
3439     return promise;
3440 }
3441 
ExecuteBatchExecuteCB(napi_env env,void * data)3442 void ExecuteBatchExecuteCB(napi_env env, void *data)
3443 {
3444     HILOG_INFO("%{public}s,NAPI_ExecuteBatch, worker pool thread execute start.", __func__);
3445     DAHelperExecuteBatchCB *executeBatchCB = static_cast<DAHelperExecuteBatchCB *>(data);
3446     auto dataAbilityHelper = executeBatchCB->dataAbilityHelper;
3447     if (dataAbilityHelper != nullptr) {
3448         OHOS::Uri uri(executeBatchCB->uri);
3449         executeBatchCB->result = dataAbilityHelper->ExecuteBatch(uri, executeBatchCB->operations);
3450         HILOG_INFO("%{public}s, dataAbilityHelper is not nullptr. %{public}zu",
3451             __func__, executeBatchCB->result.size());
3452     }
3453     HILOG_INFO("%{public}s,NAPI_ExecuteBatch, worker pool thread execute end.", __func__);
3454 }
3455 
ExecuteBatchAsyncCompleteCB(napi_env env,napi_status status,void * data)3456 void ExecuteBatchAsyncCompleteCB(napi_env env, napi_status status, void *data)
3457 {
3458     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete start.", __func__);
3459     DAHelperExecuteBatchCB *executeBatchCB = static_cast<DAHelperExecuteBatchCB *>(data);
3460     napi_value callback = nullptr;
3461     napi_value undefined = nullptr;
3462     napi_value result[ARGS_TWO] = {nullptr};
3463     napi_value callResult = nullptr;
3464     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
3465     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, executeBatchCB->cbBase.cbInfo.callback, &callback));
3466 
3467     result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
3468     napi_create_array(env, &result[PARAM1]);
3469     GetDataAbilityResultForResult(env, executeBatchCB->result, result[PARAM1]);
3470     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
3471 
3472     if (executeBatchCB->cbBase.cbInfo.callback != nullptr) {
3473         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, executeBatchCB->cbBase.cbInfo.callback));
3474     }
3475     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, executeBatchCB->cbBase.asyncWork));
3476     delete executeBatchCB;
3477     executeBatchCB = nullptr;
3478     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete end.", __func__);
3479 }
3480 
ExecuteBatchPromiseCompleteCB(napi_env env,napi_status status,void * data)3481 void ExecuteBatchPromiseCompleteCB(napi_env env, napi_status status, void *data)
3482 {
3483     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete start.", __func__);
3484     DAHelperExecuteBatchCB *executeBatchCB = static_cast<DAHelperExecuteBatchCB *>(data);
3485     napi_value result = nullptr;
3486     napi_create_array(env, &result);
3487     GetDataAbilityResultForResult(env, executeBatchCB->result, result);
3488     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, executeBatchCB->cbBase.deferred, result));
3489     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, executeBatchCB->cbBase.asyncWork));
3490     delete executeBatchCB;
3491     executeBatchCB = nullptr;
3492     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete end.", __func__);
3493 }
3494 
GetDataAbilityResultForResult(napi_env env,const std::vector<std::shared_ptr<DataAbilityResult>> & dataAbilityResult,napi_value result)3495 void GetDataAbilityResultForResult(
3496     napi_env env, const std::vector<std::shared_ptr<DataAbilityResult>> &dataAbilityResult, napi_value result)
3497 {
3498     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, getDataAbilityResultForResult start. %{public}zu",
3499         __func__, dataAbilityResult.size());
3500     int32_t index = 0;
3501     std::vector<std::shared_ptr<DataAbilityResult>> entities = dataAbilityResult;
3502     for (const auto &item : entities) {
3503         napi_value objDataAbilityResult;
3504         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &objDataAbilityResult));
3505 
3506         napi_value uri;
3507         NAPI_CALL_RETURN_VOID(
3508             env, napi_create_string_utf8(env, item->GetUri().ToString().c_str(), NAPI_AUTO_LENGTH, &uri));
3509         HILOG_INFO("%{public}s, NAPI_ExecuteBatch, uri = [%{public}s]", __func__, item->GetUri().ToString().c_str());
3510         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objDataAbilityResult, "uri", uri));
3511 
3512         napi_value count;
3513         NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, item->GetCount(), &count));
3514         HILOG_INFO("%{public}s, NAPI_ExecuteBatch, count = [%{public}d]", __func__, item->GetCount());
3515         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objDataAbilityResult, "count", count));
3516 
3517         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, objDataAbilityResult));
3518         index++;
3519     }
3520     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, getDataAbilityResultForResult end.", __func__);
3521 }
3522 
GetDataAbilityHelper(napi_env env,napi_value thisVar,std::shared_ptr<DataAbilityHelper> & dataAbilityHelper)3523 void GetDataAbilityHelper(napi_env env, napi_value thisVar, std::shared_ptr<DataAbilityHelper>& dataAbilityHelper)
3524 {
3525     NAPIDataAbilityHelperWrapper* wrapper = nullptr;
3526     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&wrapper));
3527     if (wrapper != nullptr) {
3528         dataAbilityHelper = wrapper->GetDataAbilityHelper();
3529     }
3530 }
3531 
EraseMemberProperties(DAHelperOnOffCB * onCB)3532 void EraseMemberProperties(DAHelperOnOffCB* onCB)
3533 {
3534     if (onCB->observer) {
3535         HILOG_DEBUG("EraseMemberProperties, call ReleaseJSCallback");
3536         onCB->observer->ReleaseJSCallback();
3537     }
3538     auto dataAbilityHelper = onCB->dataAbilityHelper;
3539     if (dataAbilityHelper != nullptr) {
3540         HILOG_DEBUG("EraseMemberProperties, call Release");
3541         dataAbilityHelper->Release();
3542     }
3543 }
3544 
NeedErase(std::vector<DAHelperOnOffCB * >::iterator & iter,const std::shared_ptr<DataAbilityHelper> && dataAbilityHelper)3545 bool NeedErase(std::vector<DAHelperOnOffCB*>::iterator& iter,
3546     const std::shared_ptr<DataAbilityHelper>&& dataAbilityHelper)
3547 {
3548     if ((*iter) == nullptr) {
3549         return false;
3550     }
3551     if ((*iter)->dataAbilityHelper == dataAbilityHelper) {
3552         EraseMemberProperties(*iter);
3553         delete (*iter);
3554         (*iter) = nullptr;
3555         iter = g_registerInstances.erase(iter);
3556     } else {
3557         ++iter;
3558     }
3559     return true;
3560 }
3561 
DeleteDAHelperOnOffCB(DAHelperOnOffCB * onCB)3562 void DeleteDAHelperOnOffCB(DAHelperOnOffCB *onCB)
3563 {
3564     if (!onCB) {
3565         HILOG_INFO("DeleteDAHelperOnOffCB, onCB is nullptr, no need delete");
3566         return;
3567     }
3568     EraseMemberProperties(onCB);
3569 
3570     auto end = remove(g_registerInstances.begin(), g_registerInstances.end(), onCB);
3571     if (end != g_registerInstances.end()) {
3572         (void)g_registerInstances.erase(end);
3573     }
3574     delete onCB;
3575     onCB = nullptr;
3576 }
3577 }  // namespace AppExecFwk
3578 }  // namespace OHOS
3579