• 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_INFO("%{public}s,called", __func__);
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 argument 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 argument 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,called", __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 argument 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,called", __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, Wrong 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 argument 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,called", __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, Wrong 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, Wrong argument count.", __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, Wrong 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, Wrong argument count.", __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     size_t pos = jsonString.find(tagString);
2435     if (pos == std::string::npos) {
2436         return jsonString;
2437     }
2438     std::string valueString = jsonString.substr(pos);
2439     pos = valueString.find(":");
2440     if (pos == std::string::npos) {
2441         return "";
2442     }
2443     size_t valuePos = pos + 1;
2444     while (valuePos < valueString.size()) {
2445         if (valueString.at(valuePos) != ' ' && valueString.at(valuePos) != '\t') {
2446             break;
2447         }
2448         valuePos++;
2449     }
2450     if (valuePos >= valueString.size()) {
2451         return "";
2452     }
2453     valueString = valueString.substr(valuePos);
2454     return valueString.substr(0, valueString.size() - 1);
2455 }
2456 
CallPacMapValue(napi_env env,std::shared_ptr<AppExecFwk::PacMap> result)2457 napi_value CallPacMapValue(napi_env env, std::shared_ptr<AppExecFwk::PacMap> result)
2458 {
2459     napi_value value = nullptr;
2460 
2461     NAPI_CALL(env, napi_create_object(env, &value));
2462     napi_value napiResult = nullptr;
2463     if (result != nullptr) {
2464         std::string resultWithoutTag = ExcludeTag(result->ToString(), "pacmap");
2465         napi_create_string_utf8(env, resultWithoutTag.c_str(), NAPI_AUTO_LENGTH, &napiResult);
2466         NAPI_CALL(env, napi_set_named_property(env, value, "result", napiResult));
2467     } else {
2468         HILOG_ERROR("Return result is nullptr");
2469     }
2470     return value;
2471 }
2472 
CallAsyncCompleteCB(napi_env env,napi_status status,void * data)2473 void CallAsyncCompleteCB(napi_env env, napi_status status, void *data)
2474 {
2475     HILOG_INFO("CallAsyncCompleteCB, main event thread complete.");
2476     DAHelperCallCB *callCB = static_cast<DAHelperCallCB *>(data);
2477     napi_value callback = nullptr;
2478     napi_value undefined = nullptr;
2479     napi_value result[ARGS_TWO] = {nullptr};
2480     napi_value callResult = nullptr;
2481     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
2482     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callCB->cbBase.cbInfo.callback, &callback));
2483 
2484     result[PARAM0] = GetCallbackErrorValue(env, callCB->execResult);
2485     result[PARAM1] = CallPacMapValue(env, callCB->result);
2486     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
2487 
2488     if (callCB->cbBase.cbInfo.callback != nullptr) {
2489         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, callCB->cbBase.cbInfo.callback));
2490     }
2491     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, callCB->cbBase.asyncWork));
2492     delete callCB;
2493     callCB = nullptr;
2494     HILOG_INFO("CallAsyncCompleteCB, main event thread complete end.");
2495 }
2496 
CallPromiseCompleteCB(napi_env env,napi_status status,void * data)2497 void CallPromiseCompleteCB(napi_env env, napi_status status, void *data)
2498 {
2499     HILOG_INFO("CallPromiseCompleteCB, main event thread complete.");
2500     DAHelperCallCB *callCB = static_cast<DAHelperCallCB *>(data);
2501     napi_value result = nullptr;
2502     result = CallPacMapValue(env, callCB->result);
2503     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, callCB->cbBase.deferred, result));
2504     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, callCB->cbBase.asyncWork));
2505     delete callCB;
2506     callCB = nullptr;
2507     HILOG_INFO("CallPromiseCompleteCB,  main event thread complete end.");
2508 }
2509 
CallAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperCallCB * callCB)2510 napi_value CallAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperCallCB *callCB)
2511 {
2512     HILOG_INFO("%{public}s, asyncCallback.", __func__);
2513     if (args == nullptr || callCB == nullptr) {
2514         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2515         return nullptr;
2516     }
2517     napi_value resourceName = nullptr;
2518     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2519 
2520     napi_valuetype valuetype = napi_undefined;
2521     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
2522     if (valuetype == napi_function) {
2523         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &callCB->cbBase.cbInfo.callback));
2524     }
2525 
2526     NAPI_CALL(env,
2527         napi_create_async_work(env,
2528             nullptr,
2529             resourceName,
2530             CallExecuteCB,
2531             CallAsyncCompleteCB,
2532             static_cast<void *>(callCB),
2533             &callCB->cbBase.asyncWork));
2534     NAPI_CALL(env, napi_queue_async_work(env, callCB->cbBase.asyncWork));
2535     napi_value result = nullptr;
2536     NAPI_CALL(env, napi_get_null(env, &result));
2537     HILOG_INFO("%{public}s, asyncCallback end", __func__);
2538     return result;
2539 }
2540 
CallPromise(napi_env env,DAHelperCallCB * callCB)2541 napi_value CallPromise(napi_env env, DAHelperCallCB *callCB)
2542 {
2543     HILOG_INFO("%{public}s, promise.", __func__);
2544     if (callCB == nullptr) {
2545         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2546         return nullptr;
2547     }
2548     napi_value resourceName;
2549     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2550     napi_deferred deferred;
2551     napi_value promise = nullptr;
2552     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
2553     callCB->cbBase.deferred = deferred;
2554 
2555     NAPI_CALL(env,
2556         napi_create_async_work(env,
2557             nullptr,
2558             resourceName,
2559             CallExecuteCB,
2560             CallPromiseCompleteCB,
2561             static_cast<void *>(callCB),
2562             &callCB->cbBase.asyncWork));
2563     NAPI_CALL(env, napi_queue_async_work(env, callCB->cbBase.asyncWork));
2564     HILOG_INFO("%{public}s, promise end", __func__);
2565     return promise;
2566 }
2567 
SetPacMapObject(AppExecFwk::PacMap & pacMap,const napi_env & env,std::string keyStr,napi_value value)2568 void SetPacMapObject(AppExecFwk::PacMap &pacMap, const napi_env &env, std::string keyStr, napi_value value)
2569 {
2570     napi_valuetype valueType = napi_undefined;
2571     napi_typeof(env, value, &valueType);
2572     if (valueType == napi_string) {
2573         std::string valueString = UnwrapStringFromJS(env, value);
2574         pacMap.PutStringValue(keyStr, valueString);
2575     } else if (valueType == napi_number) {
2576         double valueNumber = 0;
2577         napi_get_value_double(env, value, &valueNumber);
2578         pacMap.PutDoubleValue(keyStr, valueNumber);
2579     } else if (valueType == napi_boolean) {
2580         bool valueBool = false;
2581         napi_get_value_bool(env, value, &valueBool);
2582         pacMap.PutBooleanValue(keyStr, valueBool);
2583     } else if (valueType == napi_null) {
2584         pacMap.PutObject(keyStr, nullptr);
2585     } else if (valueType == napi_object) {
2586         pacMap.PutStringValueArray(keyStr, ConvertStringVector(env, value));
2587     } else {
2588         HILOG_ERROR("SetPacMapObject pacMap type error");
2589     }
2590 }
2591 
AnalysisPacMap(AppExecFwk::PacMap & pacMap,const napi_env & env,const napi_value & arg)2592 void AnalysisPacMap(AppExecFwk::PacMap &pacMap, const napi_env &env, const napi_value &arg)
2593 {
2594     napi_value keys = nullptr;
2595     napi_get_property_names(env, arg, &keys);
2596     uint32_t arrLen = 0;
2597     napi_status status = napi_get_array_length(env, keys, &arrLen);
2598     if (status != napi_ok) {
2599         HILOG_ERROR("AnalysisPacMap errr");
2600         return;
2601     }
2602     for (size_t i = 0; i < arrLen; ++i) {
2603         napi_value key = nullptr;
2604         (void)napi_get_element(env, keys, i, &key);
2605         std::string keyStr = UnwrapStringFromJS(env, key);
2606         napi_value value = nullptr;
2607         napi_get_property(env, arg, key, &value);
2608         SetPacMapObject(pacMap, env, keyStr, value);
2609     }
2610 }
2611 
2612 /**
2613  * @brief Call processing function.
2614  *
2615  * @param env The environment that the Node-API call is invoked under.
2616  * @param callCB Process data asynchronously.
2617  *
2618  * @return Return JS data successfully, otherwise return nullptr.
2619  */
CallWrap(napi_env env,napi_callback_info info,DAHelperCallCB * callCB)2620 napi_value CallWrap(napi_env env, napi_callback_info info, DAHelperCallCB *callCB)
2621 {
2622     HILOG_INFO("%{public}s, called", __func__);
2623     size_t argcAsync = ARGS_FIVE;
2624     const size_t argcPromise = ARGS_FOUR;
2625     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
2626     napi_value args[ARGS_MAX_COUNT] = {nullptr};
2627     napi_value ret = nullptr;
2628     napi_value thisVar = nullptr;
2629     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
2630     if (argcAsync != ARGS_FOUR && argcAsync != ARGS_FIVE) {
2631         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
2632         return nullptr;
2633     }
2634     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
2635         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
2636         return nullptr;
2637     }
2638     bool isPromise = (argcAsync <= argcPromise) ? true : false;
2639     napi_valuetype valuetype = napi_undefined;
2640     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
2641     if (valuetype == napi_string) {
2642         callCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
2643     } else {
2644         return CallErrorWrap(env, thisVar, info, args, isPromise);
2645     }
2646     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
2647     if (valuetype == napi_string) {
2648         callCB->method = NapiValueToStringUtf8(env, args[PARAM1]);
2649     } else {
2650         return CallErrorWrap(env, thisVar, info, args, isPromise);
2651     }
2652     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valuetype));
2653     if (valuetype == napi_string) {
2654         callCB->arg = NapiValueToStringUtf8(env, args[PARAM2]);
2655     }
2656     NAPI_CALL(env, napi_typeof(env, args[PARAM3], &valuetype));
2657     if (valuetype == napi_object) {
2658         AnalysisPacMap(callCB->pacMap, env, args[PARAM3]);
2659     }
2660     GetDataAbilityHelper(env, thisVar, callCB->dataAbilityHelper);
2661     if (!isPromise) {
2662         ret = CallAsync(env, args, ARGS_TWO, callCB);
2663     } else {
2664         ret = CallPromise(env, callCB);
2665     }
2666     return ret;
2667 }
2668 
2669 /**
2670  * @brief DataAbilityHelper NAPI method : call.
2671  *
2672  * @param env The environment that the Node-API call is invoked under.
2673  * @param info The callback info passed into the callback function.
2674  *
2675  * @return The return value from NAPI C++ to JS for the module.
2676  */
NAPI_Call(napi_env env,napi_callback_info info)2677 napi_value NAPI_Call(napi_env env, napi_callback_info info)
2678 {
2679     HILOG_INFO("%{public}s, called", __func__);
2680     DAHelperCallCB *callCB = new (std::nothrow) DAHelperCallCB;
2681     if (callCB == nullptr) {
2682         HILOG_ERROR("%{public}s, callCB == nullptr.", __func__);
2683         return WrapVoidToJS(env);
2684     }
2685     callCB->cbBase.cbInfo.env = env;
2686     callCB->cbBase.asyncWork = nullptr;
2687     callCB->cbBase.deferred = nullptr;
2688     callCB->cbBase.ability = nullptr;
2689 
2690     napi_value ret = CallWrap(env, info, callCB);
2691     if (ret == nullptr) {
2692         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
2693         delete callCB;
2694         callCB = nullptr;
2695         ret = WrapVoidToJS(env);
2696     }
2697     HILOG_INFO("%{public}s, called end", __func__);
2698     return ret;
2699 }
2700 
2701 /**
2702  * @brief DataAbilityHelper NAPI method : insert.
2703  *
2704  * @param env The environment that the Node-API call is invoked under.
2705  * @param info The callback info passed into the callback function.
2706  *
2707  * @return The return value from NAPI C++ to JS for the module.
2708  */
NAPI_OpenFile(napi_env env,napi_callback_info info)2709 napi_value NAPI_OpenFile(napi_env env, napi_callback_info info)
2710 {
2711     HILOG_INFO("%{public}s,called", __func__);
2712     DAHelperOpenFileCB *openFileCB = new (std::nothrow) DAHelperOpenFileCB;
2713     if (openFileCB == nullptr) {
2714         HILOG_ERROR("%{public}s, openFileCB == nullptr.", __func__);
2715         return WrapVoidToJS(env);
2716     }
2717     openFileCB->cbBase.cbInfo.env = env;
2718     openFileCB->cbBase.asyncWork = nullptr;
2719     openFileCB->cbBase.deferred = nullptr;
2720     openFileCB->cbBase.ability = nullptr;
2721 
2722     napi_value ret = OpenFileWrap(env, info, openFileCB);
2723     if (ret == nullptr) {
2724         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
2725         delete openFileCB;
2726         openFileCB = nullptr;
2727         ret = WrapVoidToJS(env);
2728     }
2729     HILOG_INFO("%{public}s,end", __func__);
2730     return ret;
2731 }
2732 
2733 /**
2734  * @brief Insert processing function.
2735  *
2736  * @param env The environment that the Node-API call is invoked under.
2737  * @param insertCB Process data asynchronously.
2738  *
2739  * @return Return JS data successfully, otherwise return nullptr.
2740  */
OpenFileWrap(napi_env env,napi_callback_info info,DAHelperOpenFileCB * openFileCB)2741 napi_value OpenFileWrap(napi_env env, napi_callback_info info, DAHelperOpenFileCB *openFileCB)
2742 {
2743     HILOG_INFO("%{public}s,called", __func__);
2744     size_t argcAsync = ARGS_THREE;
2745     const size_t argcPromise = ARGS_TWO;
2746     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
2747     napi_value args[ARGS_MAX_COUNT] = {nullptr};
2748     napi_value ret = nullptr;
2749     napi_value thisVar = nullptr;
2750 
2751     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
2752     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
2753         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
2754         return nullptr;
2755     }
2756 
2757     napi_valuetype valuetype = napi_undefined;
2758     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
2759     if (valuetype == napi_string) {
2760         openFileCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
2761         HILOG_INFO("%{public}s,uri=%{public}s", __func__, openFileCB->uri.c_str());
2762     }
2763 
2764     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
2765     if (valuetype == napi_string) {
2766         openFileCB->mode = NapiValueToStringUtf8(env, args[PARAM1]);
2767         HILOG_INFO("%{public}s,mode=%{public}s", __func__, openFileCB->mode.c_str());
2768     }
2769     GetDataAbilityHelper(env, thisVar, openFileCB->dataAbilityHelper);
2770 
2771     if (argcAsync > argcPromise) {
2772         ret = OpenFileAsync(env, args, ARGS_TWO, openFileCB);
2773     } else {
2774         ret = OpenFilePromise(env, openFileCB);
2775     }
2776     HILOG_INFO("%{public}s,end", __func__);
2777     return ret;
2778 }
2779 
OpenFileAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperOpenFileCB * openFileCB)2780 napi_value OpenFileAsync(napi_env env, napi_value *args, const size_t argCallback, DAHelperOpenFileCB *openFileCB)
2781 {
2782     HILOG_INFO("%{public}s, asyncCallback.", __func__);
2783     if (args == nullptr || openFileCB == nullptr) {
2784         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2785         return nullptr;
2786     }
2787     napi_value resourceName = 0;
2788     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2789 
2790     napi_valuetype valuetype = napi_undefined;
2791     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
2792     if (valuetype == napi_function) {
2793         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &openFileCB->cbBase.cbInfo.callback));
2794     }
2795 
2796     NAPI_CALL(env,
2797         napi_create_async_work(env,
2798             nullptr,
2799             resourceName,
2800             OpenFileExecuteCB,
2801             OpenFileAsyncCompleteCB,
2802             static_cast<void *>(openFileCB),
2803             &openFileCB->cbBase.asyncWork));
2804     NAPI_CALL(env, napi_queue_async_work_with_qos(env, openFileCB->cbBase.asyncWork, napi_qos_user_initiated));
2805     napi_value result = nullptr;
2806     NAPI_CALL(env, napi_get_null(env, &result));
2807     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
2808     return result;
2809 }
2810 
OpenFilePromise(napi_env env,DAHelperOpenFileCB * openFileCB)2811 napi_value OpenFilePromise(napi_env env, DAHelperOpenFileCB *openFileCB)
2812 {
2813     HILOG_INFO("%{public}s, promise.", __func__);
2814     if (openFileCB == nullptr) {
2815         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
2816         return nullptr;
2817     }
2818     napi_value resourceName;
2819     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
2820     napi_deferred deferred;
2821     napi_value promise = nullptr;
2822     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
2823     openFileCB->cbBase.deferred = deferred;
2824 
2825     NAPI_CALL(env,
2826         napi_create_async_work(env,
2827             nullptr,
2828             resourceName,
2829             OpenFileExecuteCB,
2830             OpenFilePromiseCompleteCB,
2831             static_cast<void *>(openFileCB),
2832             &openFileCB->cbBase.asyncWork));
2833     NAPI_CALL(env, napi_queue_async_work_with_qos(env, openFileCB->cbBase.asyncWork, napi_qos_user_initiated));
2834     HILOG_INFO("%{public}s, promise end.", __func__);
2835     return promise;
2836 }
2837 
OpenFileExecuteCB(napi_env env,void * data)2838 void OpenFileExecuteCB(napi_env env, void *data)
2839 {
2840     HILOG_INFO("NAPI_OpenFile, worker pool thread execute.");
2841     DAHelperOpenFileCB *OpenFileCB = static_cast<DAHelperOpenFileCB *>(data);
2842     auto dataAbilityHelper = OpenFileCB->dataAbilityHelper;
2843     if (dataAbilityHelper != nullptr) {
2844         OpenFileCB->execResult = INVALID_PARAMETER;
2845         if (!OpenFileCB->uri.empty()) {
2846             OHOS::Uri uri(OpenFileCB->uri);
2847             OpenFileCB->result = dataAbilityHelper->OpenFile(uri, OpenFileCB->mode);
2848             OpenFileCB->execResult = NO_ERROR;
2849         } else {
2850             HILOG_ERROR("NAPI_OpenFile, dataAbilityHelper uri is empty");
2851         }
2852     } else {
2853         HILOG_ERROR("NAPI_OpenFile, dataAbilityHelper == nullptr");
2854     }
2855     HILOG_INFO("NAPI_OpenFile, worker pool thread execute end.");
2856 }
2857 
OpenFileAsyncCompleteCB(napi_env env,napi_status status,void * data)2858 void OpenFileAsyncCompleteCB(napi_env env, napi_status status, void *data)
2859 {
2860     HILOG_INFO("NAPI_OpenFile, main event thread complete.");
2861     DAHelperOpenFileCB *OpenFileCB = static_cast<DAHelperOpenFileCB *>(data);
2862     napi_value callback = nullptr;
2863     napi_value undefined = nullptr;
2864     napi_value result[ARGS_TWO] = {nullptr};
2865     napi_value callResult = nullptr;
2866     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
2867     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, OpenFileCB->cbBase.cbInfo.callback, &callback));
2868 
2869     result[PARAM0] = GetCallbackErrorValue(env, OpenFileCB->execResult);
2870     napi_create_int32(env, OpenFileCB->result, &result[PARAM1]);
2871     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
2872 
2873     if (OpenFileCB->cbBase.cbInfo.callback != nullptr) {
2874         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, OpenFileCB->cbBase.cbInfo.callback));
2875     }
2876     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, OpenFileCB->cbBase.asyncWork));
2877     delete OpenFileCB;
2878     OpenFileCB = nullptr;
2879     HILOG_INFO("NAPI_OpenFile, main event thread complete end.");
2880 }
2881 
OpenFilePromiseCompleteCB(napi_env env,napi_status status,void * data)2882 void OpenFilePromiseCompleteCB(napi_env env, napi_status status, void *data)
2883 {
2884     HILOG_INFO("NAPI_OpenFileCB,  main event thread complete.");
2885     DAHelperOpenFileCB *OpenFileCB = static_cast<DAHelperOpenFileCB *>(data);
2886     napi_value result = nullptr;
2887     napi_create_int32(env, OpenFileCB->result, &result);
2888     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, OpenFileCB->cbBase.deferred, result));
2889     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, OpenFileCB->cbBase.asyncWork));
2890     delete OpenFileCB;
2891     OpenFileCB = nullptr;
2892     HILOG_INFO("NAPI_OpenFileCB,  main event thread complete end.");
2893 }
2894 
2895 /**
2896  * @brief DataAbilityHelper NAPI method : insert.
2897  *
2898  * @param env The environment that the Node-API call is invoked under.
2899  * @param info The callback info passed into the callback function.
2900  *
2901  * @return The return value from NAPI C++ to JS for the module.
2902  */
NAPI_BatchInsert(napi_env env,napi_callback_info info)2903 napi_value NAPI_BatchInsert(napi_env env, napi_callback_info info)
2904 {
2905     HILOG_INFO("%{public}s,called", __func__);
2906     DAHelperBatchInsertCB *BatchInsertCB = new (std::nothrow) DAHelperBatchInsertCB;
2907     if (BatchInsertCB == nullptr) {
2908         HILOG_ERROR("%{public}s, BatchInsertCB == nullptr.", __func__);
2909         return WrapVoidToJS(env);
2910     }
2911     BatchInsertCB->cbBase.cbInfo.env = env;
2912     BatchInsertCB->cbBase.asyncWork = nullptr;
2913     BatchInsertCB->cbBase.deferred = nullptr;
2914     BatchInsertCB->cbBase.ability = nullptr;
2915 
2916     napi_value ret = BatchInsertWrap(env, info, BatchInsertCB);
2917     if (ret == nullptr) {
2918         HILOG_ERROR("%{public}s,ret == nullptr", __func__);
2919         delete BatchInsertCB;
2920         BatchInsertCB = nullptr;
2921         ret = WrapVoidToJS(env);
2922     }
2923     HILOG_INFO("%{public}s,end", __func__);
2924     return ret;
2925 }
2926 
NapiValueObject(napi_env env,napi_value param)2927 std::vector<NativeRdb::ValuesBucket> NapiValueObject(napi_env env, napi_value param)
2928 {
2929     HILOG_INFO("%{public}s,called", __func__);
2930     std::vector<NativeRdb::ValuesBucket> result;
2931     UnwrapArrayObjectFromJS(env, param, result);
2932     return result;
2933 }
2934 
UnwrapArrayObjectFromJS(napi_env env,napi_value param,std::vector<NativeRdb::ValuesBucket> & value)2935 bool UnwrapArrayObjectFromJS(napi_env env, napi_value param, std::vector<NativeRdb::ValuesBucket> &value)
2936 {
2937     HILOG_INFO("%{public}s,called", __func__);
2938     uint32_t arraySize = 0;
2939     napi_value jsValue = nullptr;
2940     std::string strValue = "";
2941 
2942     if (!IsArrayForNapiValue(env, param, arraySize)) {
2943         HILOG_INFO("%{public}s, IsArrayForNapiValue is false", __func__);
2944         return false;
2945     }
2946 
2947     value.clear();
2948     for (uint32_t i = 0; i < arraySize; i++) {
2949         jsValue = nullptr;
2950         if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
2951             HILOG_INFO("%{public}s, napi_get_element is false", __func__);
2952             return false;
2953         }
2954 
2955         NativeRdb::ValuesBucket valueBucket;
2956         valueBucket.Clear();
2957         AnalysisValuesBucket(valueBucket, env, jsValue);
2958 
2959         value.push_back(valueBucket);
2960     }
2961     HILOG_INFO("%{public}s,end", __func__);
2962     return true;
2963 }
2964 
2965 /**
2966  * @brief Insert processing function.
2967  *
2968  * @param env The environment that the Node-API call is invoked under.
2969  * @param insertCB Process data asynchronously.
2970  *
2971  * @return Return JS data successfully, otherwise return nullptr.
2972  */
BatchInsertWrap(napi_env env,napi_callback_info info,DAHelperBatchInsertCB * batchInsertCB)2973 napi_value BatchInsertWrap(napi_env env, napi_callback_info info, DAHelperBatchInsertCB *batchInsertCB)
2974 {
2975     HILOG_INFO("%{public}s,called", __func__);
2976     size_t argcAsync = ARGS_THREE;
2977     const size_t argcPromise = ARGS_TWO;
2978     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
2979     napi_value args[ARGS_MAX_COUNT] = {nullptr};
2980     napi_value ret = nullptr;
2981     napi_value thisVar = nullptr;
2982 
2983     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
2984     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
2985         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
2986         return nullptr;
2987     }
2988 
2989     napi_valuetype valuetype = napi_undefined;
2990     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
2991     if (valuetype == napi_string) {
2992         batchInsertCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
2993         HILOG_INFO("%{public}s,uri=%{public}s", __func__, batchInsertCB->uri.c_str());
2994     }
2995 
2996     batchInsertCB->values = NapiValueObject(env, args[PARAM1]);
2997     GetDataAbilityHelper(env, thisVar, batchInsertCB->dataAbilityHelper);
2998 
2999     if (argcAsync > argcPromise) {
3000         ret = BatchInsertAsync(env, args, ARGS_TWO, batchInsertCB);
3001     } else {
3002         ret = BatchInsertPromise(env, batchInsertCB);
3003     }
3004     HILOG_INFO("%{public}s,end", __func__);
3005     return ret;
3006 }
3007 
BatchInsertAsync(napi_env env,napi_value * args,const size_t argCallback,DAHelperBatchInsertCB * batchInsertCB)3008 napi_value BatchInsertAsync(
3009     napi_env env, napi_value *args, const size_t argCallback, DAHelperBatchInsertCB *batchInsertCB)
3010 {
3011     HILOG_INFO("%{public}s, asyncCallback.", __func__);
3012     if (args == nullptr || batchInsertCB == nullptr) {
3013         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
3014         return nullptr;
3015     }
3016     napi_value resourceName = nullptr;
3017     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3018 
3019     napi_valuetype valuetype = napi_undefined;
3020     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
3021     if (valuetype == napi_function) {
3022         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &batchInsertCB->cbBase.cbInfo.callback));
3023     }
3024 
3025     NAPI_CALL(env,
3026         napi_create_async_work(env,
3027             nullptr,
3028             resourceName,
3029             BatchInsertExecuteCB,
3030             BatchInsertAsyncCompleteCB,
3031             static_cast<void *>(batchInsertCB),
3032             &batchInsertCB->cbBase.asyncWork));
3033     NAPI_CALL(env, napi_queue_async_work(env, batchInsertCB->cbBase.asyncWork));
3034     napi_value result = nullptr;
3035     NAPI_CALL(env, napi_get_null(env, &result));
3036     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
3037     return result;
3038 }
3039 
BatchInsertPromise(napi_env env,DAHelperBatchInsertCB * batchInsertCB)3040 napi_value BatchInsertPromise(napi_env env, DAHelperBatchInsertCB *batchInsertCB)
3041 {
3042     HILOG_INFO("%{public}s, promise.", __func__);
3043     if (batchInsertCB == nullptr) {
3044         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
3045         return nullptr;
3046     }
3047     napi_value resourceName;
3048     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3049     napi_deferred deferred;
3050     napi_value promise = nullptr;
3051     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
3052     batchInsertCB->cbBase.deferred = deferred;
3053 
3054     NAPI_CALL(env,
3055         napi_create_async_work(env,
3056             nullptr,
3057             resourceName,
3058             BatchInsertExecuteCB,
3059             BatchInsertPromiseCompleteCB,
3060             static_cast<void *>(batchInsertCB),
3061             &batchInsertCB->cbBase.asyncWork));
3062     NAPI_CALL(env, napi_queue_async_work(env, batchInsertCB->cbBase.asyncWork));
3063     HILOG_INFO("%{public}s, promise end.", __func__);
3064     return promise;
3065 }
3066 
BatchInsertExecuteCB(napi_env env,void * data)3067 void BatchInsertExecuteCB(napi_env env, void *data)
3068 {
3069     HILOG_INFO("NAPI_BatchInsert, worker pool thread execute.");
3070     DAHelperBatchInsertCB *batchInsertCB = static_cast<DAHelperBatchInsertCB *>(data);
3071     auto dataAbilityHelper = batchInsertCB->dataAbilityHelper;
3072     if (dataAbilityHelper != nullptr) {
3073         batchInsertCB->execResult = INVALID_PARAMETER;
3074         if (!batchInsertCB->uri.empty()) {
3075             OHOS::Uri uri(batchInsertCB->uri);
3076             batchInsertCB->result = dataAbilityHelper->BatchInsert(uri, batchInsertCB->values);
3077             batchInsertCB->execResult = NO_ERROR;
3078         } else {
3079             HILOG_ERROR("NAPI_BatchInsert, dataAbilityHelper uri is empyt");
3080         }
3081     } else {
3082         HILOG_ERROR("NAPI_BatchInsert, dataAbilityHelper == nullptr");
3083     }
3084     HILOG_INFO("NAPI_BatchInsert, worker pool thread execute end.");
3085 }
3086 
BatchInsertAsyncCompleteCB(napi_env env,napi_status status,void * data)3087 void BatchInsertAsyncCompleteCB(napi_env env, napi_status status, void *data)
3088 {
3089     HILOG_INFO("NAPI_BatchInsert, main event thread complete.");
3090     DAHelperBatchInsertCB *BatchInsertCB = static_cast<DAHelperBatchInsertCB *>(data);
3091     napi_value callback = nullptr;
3092     napi_value undefined = nullptr;
3093     napi_value result[ARGS_TWO] = {nullptr};
3094     napi_value callResult = nullptr;
3095     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
3096     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, BatchInsertCB->cbBase.cbInfo.callback, &callback));
3097 
3098     result[PARAM0] = GetCallbackErrorValue(env, BatchInsertCB->execResult);
3099     napi_create_int32(env, BatchInsertCB->result, &result[PARAM1]);
3100     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
3101 
3102     if (BatchInsertCB->cbBase.cbInfo.callback != nullptr) {
3103         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, BatchInsertCB->cbBase.cbInfo.callback));
3104     }
3105     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, BatchInsertCB->cbBase.asyncWork));
3106     delete BatchInsertCB;
3107     BatchInsertCB = nullptr;
3108     HILOG_INFO("NAPI_BatchInsert, main event thread complete end.");
3109 }
3110 
BatchInsertPromiseCompleteCB(napi_env env,napi_status status,void * data)3111 void BatchInsertPromiseCompleteCB(napi_env env, napi_status status, void *data)
3112 {
3113     HILOG_INFO("NAPI_BatchInsertCB,  main event thread complete.");
3114     DAHelperBatchInsertCB *BatchInsertCB = static_cast<DAHelperBatchInsertCB *>(data);
3115     napi_value result = nullptr;
3116     napi_create_int32(env, BatchInsertCB->result, &result);
3117     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, BatchInsertCB->cbBase.deferred, result));
3118     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, BatchInsertCB->cbBase.asyncWork));
3119     delete BatchInsertCB;
3120     BatchInsertCB = nullptr;
3121     HILOG_INFO("NAPI_BatchInsertCB,  main event thread complete end.");
3122 }
3123 
3124 /**
3125  * @brief DataAbilityHelper NAPI method : insert.
3126  *
3127  * @param env The environment that the Node-API call is invoked under.
3128  * @param info The callback info passed into the callback function.
3129  *
3130  * @return The return value from NAPI C++ to JS for the module.
3131  */
NAPI_Query(napi_env env,napi_callback_info info)3132 napi_value NAPI_Query(napi_env env, napi_callback_info info)
3133 {
3134     HILOG_INFO("NAPI_Query called");
3135     DAHelperQueryCB *queryCB = new DAHelperQueryCB;
3136     queryCB->cbBase.cbInfo.env = env;
3137     queryCB->cbBase.asyncWork = nullptr;
3138     queryCB->cbBase.deferred = nullptr;
3139     queryCB->cbBase.ability = nullptr;
3140 
3141     napi_value ret = QueryWrap(env, info, queryCB);
3142     if (ret == nullptr) {
3143         HILOG_ERROR("ret == nullptr");
3144         delete queryCB;
3145         queryCB = nullptr;
3146         ret = WrapVoidToJS(env);
3147     }
3148     HILOG_INFO("NAPI_Query end");
3149     return ret;
3150 }
3151 
3152 /**
3153  * @brief Insert processing function.
3154  *
3155  * @param env The environment that the Node-API call is invoked under.
3156  * @param insertCB Process data asynchronously.
3157  *
3158  * @return Return JS data successfully, otherwise return nullptr.
3159  */
QueryWrap(napi_env env,napi_callback_info info,DAHelperQueryCB * queryCB)3160 napi_value QueryWrap(napi_env env, napi_callback_info info, DAHelperQueryCB *queryCB)
3161 {
3162     size_t argcAsync = ARGS_FOUR;
3163     const size_t argcPromise = ARGS_THREE;
3164     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
3165     napi_value args[ARGS_MAX_COUNT] = {nullptr};
3166     napi_value ret = nullptr;
3167     napi_value thisVar = nullptr;
3168 
3169     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
3170     if (argcAsync > argCountWithAsync) {
3171         HILOG_ERROR("Wrong argument count.");
3172         return nullptr;
3173     }
3174 
3175     napi_valuetype valuetype = napi_undefined;
3176     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
3177     if (valuetype == napi_string) {
3178         queryCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
3179         HILOG_DEBUG("uri=%{public}s", queryCB->uri.c_str());
3180     }
3181 
3182     std::vector<std::string> result;
3183     bool arrayStringbool = NapiValueToArrayStringUtf8(env, args[PARAM1], result);
3184     if (!arrayStringbool) {
3185         HILOG_ERROR("The return value of arraystringbool is false");
3186     }
3187     queryCB->columns = result;
3188 
3189     UnwrapDataAbilityPredicates(queryCB->predicates, env, args[PARAM2]);
3190     GetDataAbilityHelper(env, thisVar, queryCB->dataAbilityHelper);
3191 
3192     if (argcAsync > argcPromise) {
3193         ret = QuerySync(env, args, ARGS_THREE, queryCB);
3194     } else {
3195         ret = QueryPromise(env, queryCB);
3196     }
3197     return ret;
3198 }
3199 
QuerySync(napi_env env,napi_value * args,const size_t argCallback,DAHelperQueryCB * queryCB)3200 napi_value QuerySync(napi_env env, napi_value *args, const size_t argCallback, DAHelperQueryCB *queryCB)
3201 {
3202     HILOG_DEBUG("asyncCallback.");
3203     if (args == nullptr || queryCB == nullptr) {
3204         HILOG_ERROR("param == nullptr.");
3205         return nullptr;
3206     }
3207 
3208     napi_valuetype valuetype = napi_undefined;
3209     NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype));
3210     if (valuetype == napi_function) {
3211         NAPI_CALL(env, napi_create_reference(env, args[argCallback], 1, &queryCB->cbBase.cbInfo.callback));
3212     }
3213 
3214     auto dataAbilityHelper = queryCB->dataAbilityHelper;
3215     if (dataAbilityHelper != nullptr) {
3216         queryCB->execResult = INVALID_PARAMETER;
3217         if (!queryCB->uri.empty()) {
3218             OHOS::Uri uri(queryCB->uri);
3219             auto resultset = dataAbilityHelper->Query(uri, queryCB->columns, queryCB->predicates);
3220             if (resultset != nullptr) {
3221                 queryCB->result = resultset;
3222                 queryCB->execResult = NO_ERROR;
3223             }
3224         }
3225     }
3226 
3227     napi_value callback = nullptr;
3228     NAPI_CALL(env, napi_get_reference_value(env, queryCB->cbBase.cbInfo.callback, &callback));
3229     napi_value result[ARGS_TWO] = {nullptr};
3230     result[PARAM0] = GetCallbackErrorValue(env, queryCB->execResult);
3231     result[PARAM1] = WrapResultSet(env, queryCB->result);
3232     napi_value undefined = nullptr;
3233     NAPI_CALL(env, napi_get_undefined(env, &undefined));
3234     napi_value callResult = nullptr;
3235     NAPI_CALL(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
3236 
3237     if (queryCB->cbBase.cbInfo.callback != nullptr) {
3238         NAPI_CALL(env, napi_delete_reference(env, queryCB->cbBase.cbInfo.callback));
3239     }
3240     delete queryCB;
3241     queryCB = nullptr;
3242 
3243     napi_value ret = nullptr;
3244     NAPI_CALL(env, napi_get_null(env, &ret));
3245     return ret;
3246 }
3247 
QueryPromise(napi_env env,DAHelperQueryCB * queryCB)3248 napi_value QueryPromise(napi_env env, DAHelperQueryCB *queryCB)
3249 {
3250     HILOG_DEBUG("promise.");
3251     if (queryCB == nullptr) {
3252         HILOG_ERROR("param == nullptr.");
3253         return nullptr;
3254     }
3255 
3256     auto dataAbilityHelper = queryCB->dataAbilityHelper;
3257     if (dataAbilityHelper != nullptr) {
3258         if (!queryCB->uri.empty()) {
3259             OHOS::Uri uri(queryCB->uri);
3260             auto resultset = dataAbilityHelper->Query(uri, queryCB->columns, queryCB->predicates);
3261             if (resultset != nullptr) {
3262                 queryCB->result = resultset;
3263             }
3264         }
3265     }
3266 
3267     napi_deferred deferred;
3268     napi_value promise = nullptr;
3269     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
3270     napi_value result = WrapResultSet(env, queryCB->result);
3271     NAPI_CALL(env, napi_resolve_deferred(env, deferred, result));
3272     delete queryCB;
3273     queryCB = nullptr;
3274 
3275     return promise;
3276 }
3277 
WrapResultSet(napi_env env,const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)3278 napi_value WrapResultSet(napi_env env, const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
3279 {
3280     HILOG_DEBUG("called");
3281     if (resultSet == nullptr) {
3282         HILOG_ERROR("input parameter resultSet is nullptr");
3283         return WrapVoidToJS(env);
3284     }
3285 
3286     return RdbJsKit::ResultSetProxy::NewInstance(env, resultSet);
3287 }
3288 
NAPI_ExecuteBatch(napi_env env,napi_callback_info info)3289 napi_value NAPI_ExecuteBatch(napi_env env, napi_callback_info info)
3290 {
3291     HILOG_INFO("%{public}s,start", __func__);
3292     DAHelperExecuteBatchCB *executeBatchCB = new (std::nothrow) DAHelperExecuteBatchCB;
3293     if (executeBatchCB == nullptr) {
3294         HILOG_ERROR("%{public}s, executeBatchCB == nullptr.", __func__);
3295         return WrapVoidToJS(env);
3296     }
3297     executeBatchCB->cbBase.cbInfo.env = env;
3298     executeBatchCB->cbBase.asyncWork = nullptr;
3299     executeBatchCB->cbBase.deferred = nullptr;
3300     executeBatchCB->cbBase.ability = nullptr;
3301 
3302     napi_value ret = ExecuteBatchWrap(env, info, executeBatchCB);
3303     if (ret == nullptr) {
3304         HILOG_ERROR("%{public}s, ret == nullptr.", __func__);
3305         delete executeBatchCB;
3306         executeBatchCB = nullptr;
3307         ret = WrapVoidToJS(env);
3308     }
3309     HILOG_INFO("%{public}s,end", __func__);
3310     return ret;
3311 }
3312 
UnwrapArrayOperationFromJS(napi_env env,napi_callback_info info,napi_value param,std::vector<std::shared_ptr<DataAbilityOperation>> & result)3313 bool UnwrapArrayOperationFromJS(
3314     napi_env env, napi_callback_info info, napi_value param, std::vector<std::shared_ptr<DataAbilityOperation>> &result)
3315 {
3316     HILOG_INFO("%{public}s,called", __func__);
3317     uint32_t arraySize = 0;
3318     napi_value jsValue = nullptr;
3319     std::string strValue = "";
3320 
3321     if (!IsArrayForNapiValue(env, param, arraySize)) {
3322         HILOG_ERROR("%{public}s, Wrong argument type ", __func__);
3323         return false;
3324     }
3325     HILOG_INFO("%{public}s, param size:%{public}d ", __func__, arraySize);
3326     result.clear();
3327     for (uint32_t i = 0; i < arraySize; i++) {
3328         jsValue = nullptr;
3329         if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
3330             HILOG_ERROR("%{public}s, get element failed, index:%{public}d ", __func__, i);
3331             return false;
3332         }
3333         std::shared_ptr<DataAbilityOperation> operation = nullptr;
3334         UnwrapDataAbilityOperation(operation, env, jsValue);
3335         HILOG_INFO("%{public}s, UnwrapDataAbilityOperation, index:%{public}d ", __func__, i);
3336         result.push_back(operation);
3337     }
3338     return true;
3339 }
3340 
ExecuteBatchWrap(napi_env env,napi_callback_info info,DAHelperExecuteBatchCB * executeBatchCB)3341 napi_value ExecuteBatchWrap(napi_env env, napi_callback_info info, DAHelperExecuteBatchCB *executeBatchCB)
3342 {
3343     HILOG_INFO("%{public}s,start", __func__);
3344     size_t argcAsync = ARGS_THREE;
3345     const size_t argcPromise = ARGS_TWO;
3346     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
3347     napi_value args[ARGS_MAX_COUNT] = {nullptr};
3348     napi_value ret = nullptr;
3349     napi_value thisVar = nullptr;
3350 
3351     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
3352     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
3353         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
3354         return nullptr;
3355     }
3356 
3357     napi_valuetype valuetype = napi_undefined;
3358     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
3359     if (valuetype == napi_string) {
3360         executeBatchCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
3361         HILOG_INFO("%{public}s,uri=%{public}s", __func__, executeBatchCB->uri.c_str());
3362     } else {
3363         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
3364     }
3365 
3366     std::vector<std::shared_ptr<DataAbilityOperation>> operations;
3367     UnwrapArrayOperationFromJS(env, info, args[PARAM1], operations);
3368     HILOG_INFO("%{public}s,operations size=%{public}zu", __func__, operations.size());
3369     executeBatchCB->operations = operations;
3370     GetDataAbilityHelper(env, thisVar, executeBatchCB->dataAbilityHelper);
3371 
3372     if (argcAsync > argcPromise) {
3373         ret = ExecuteBatchAsync(env, args, argcAsync, argcPromise, executeBatchCB);
3374     } else {
3375         ret = ExecuteBatchPromise(env, executeBatchCB);
3376     }
3377     HILOG_INFO("%{public}s,end", __func__);
3378     return ret;
3379 }
3380 
ExecuteBatchAsync(napi_env env,napi_value * args,size_t argcAsync,const size_t argcPromise,DAHelperExecuteBatchCB * executeBatchCB)3381 napi_value ExecuteBatchAsync(
3382     napi_env env, napi_value *args, size_t argcAsync, const size_t argcPromise, DAHelperExecuteBatchCB *executeBatchCB)
3383 {
3384     HILOG_INFO("%{public}s, asyncCallback start.", __func__);
3385     if (args == nullptr || executeBatchCB == nullptr) {
3386         HILOG_ERROR("%{public}s, param is nullptr.", __func__);
3387         return nullptr;
3388     }
3389     napi_value resourceName = nullptr;
3390     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3391 
3392     napi_valuetype valuetype = napi_undefined;
3393     NAPI_CALL(env, napi_typeof(env, args[argcPromise], &valuetype));
3394     if (valuetype == napi_function) {
3395         NAPI_CALL(env, napi_create_reference(env, args[argcPromise], 1, &executeBatchCB->cbBase.cbInfo.callback));
3396     }
3397 
3398     NAPI_CALL(env,
3399         napi_create_async_work(env,
3400             nullptr,
3401             resourceName,
3402             ExecuteBatchExecuteCB,
3403             ExecuteBatchAsyncCompleteCB,
3404             static_cast<void *>(executeBatchCB),
3405             &executeBatchCB->cbBase.asyncWork));
3406     NAPI_CALL(env, napi_queue_async_work(env, executeBatchCB->cbBase.asyncWork));
3407     napi_value result = nullptr;
3408     NAPI_CALL(env, napi_get_null(env, &result));
3409     HILOG_INFO("%{public}s, asyncCallback end.", __func__);
3410     return result;
3411 }
3412 
ExecuteBatchPromise(napi_env env,DAHelperExecuteBatchCB * executeBatchCB)3413 napi_value ExecuteBatchPromise(napi_env env, DAHelperExecuteBatchCB *executeBatchCB)
3414 {
3415     HILOG_INFO("%{public}s, promise start.", __func__);
3416     if (executeBatchCB == nullptr) {
3417         HILOG_ERROR("%{public}s, param is nullptr.", __func__);
3418         return nullptr;
3419     }
3420     napi_value resourceName;
3421     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3422     napi_deferred deferred;
3423     napi_value promise = nullptr;
3424     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
3425     executeBatchCB->cbBase.deferred = deferred;
3426 
3427     NAPI_CALL(env,
3428         napi_create_async_work(env,
3429             nullptr,
3430             resourceName,
3431             ExecuteBatchExecuteCB,
3432             ExecuteBatchPromiseCompleteCB,
3433             static_cast<void *>(executeBatchCB),
3434             &executeBatchCB->cbBase.asyncWork));
3435     NAPI_CALL(env, napi_queue_async_work(env, executeBatchCB->cbBase.asyncWork));
3436     HILOG_INFO("%{public}s, promise end.", __func__);
3437     return promise;
3438 }
3439 
ExecuteBatchExecuteCB(napi_env env,void * data)3440 void ExecuteBatchExecuteCB(napi_env env, void *data)
3441 {
3442     HILOG_INFO("%{public}s,NAPI_ExecuteBatch, worker pool thread execute start.", __func__);
3443     DAHelperExecuteBatchCB *executeBatchCB = static_cast<DAHelperExecuteBatchCB *>(data);
3444     auto dataAbilityHelper = executeBatchCB->dataAbilityHelper;
3445     if (dataAbilityHelper != nullptr) {
3446         OHOS::Uri uri(executeBatchCB->uri);
3447         executeBatchCB->result = dataAbilityHelper->ExecuteBatch(uri, executeBatchCB->operations);
3448         HILOG_INFO("%{public}s, dataAbilityHelper is not nullptr. %{public}zu",
3449             __func__, executeBatchCB->result.size());
3450     }
3451     HILOG_INFO("%{public}s,NAPI_ExecuteBatch, worker pool thread execute end.", __func__);
3452 }
3453 
ExecuteBatchAsyncCompleteCB(napi_env env,napi_status status,void * data)3454 void ExecuteBatchAsyncCompleteCB(napi_env env, napi_status status, void *data)
3455 {
3456     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete start.", __func__);
3457     DAHelperExecuteBatchCB *executeBatchCB = static_cast<DAHelperExecuteBatchCB *>(data);
3458     napi_value callback = nullptr;
3459     napi_value undefined = nullptr;
3460     napi_value result[ARGS_TWO] = {nullptr};
3461     napi_value callResult = nullptr;
3462     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
3463     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, executeBatchCB->cbBase.cbInfo.callback, &callback));
3464 
3465     result[PARAM0] = GetCallbackErrorValue(env, NO_ERROR);
3466     napi_create_array(env, &result[PARAM1]);
3467     GetDataAbilityResultForResult(env, executeBatchCB->result, result[PARAM1]);
3468     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &result[PARAM0], &callResult));
3469 
3470     if (executeBatchCB->cbBase.cbInfo.callback != nullptr) {
3471         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, executeBatchCB->cbBase.cbInfo.callback));
3472     }
3473     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, executeBatchCB->cbBase.asyncWork));
3474     delete executeBatchCB;
3475     executeBatchCB = nullptr;
3476     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete end.", __func__);
3477 }
3478 
ExecuteBatchPromiseCompleteCB(napi_env env,napi_status status,void * data)3479 void ExecuteBatchPromiseCompleteCB(napi_env env, napi_status status, void *data)
3480 {
3481     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete start.", __func__);
3482     DAHelperExecuteBatchCB *executeBatchCB = static_cast<DAHelperExecuteBatchCB *>(data);
3483     napi_value result = nullptr;
3484     napi_create_array(env, &result);
3485     GetDataAbilityResultForResult(env, executeBatchCB->result, result);
3486     NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, executeBatchCB->cbBase.deferred, result));
3487     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, executeBatchCB->cbBase.asyncWork));
3488     delete executeBatchCB;
3489     executeBatchCB = nullptr;
3490     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, main event thread complete end.", __func__);
3491 }
3492 
GetDataAbilityResultForResult(napi_env env,const std::vector<std::shared_ptr<DataAbilityResult>> & dataAbilityResult,napi_value result)3493 void GetDataAbilityResultForResult(
3494     napi_env env, const std::vector<std::shared_ptr<DataAbilityResult>> &dataAbilityResult, napi_value result)
3495 {
3496     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, getDataAbilityResultForResult start. %{public}zu",
3497         __func__, dataAbilityResult.size());
3498     int32_t index = 0;
3499     std::vector<std::shared_ptr<DataAbilityResult>> entities = dataAbilityResult;
3500     for (const auto &item : entities) {
3501         napi_value objDataAbilityResult;
3502         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &objDataAbilityResult));
3503 
3504         napi_value uri;
3505         NAPI_CALL_RETURN_VOID(
3506             env, napi_create_string_utf8(env, item->GetUri().ToString().c_str(), NAPI_AUTO_LENGTH, &uri));
3507         HILOG_INFO("%{public}s, NAPI_ExecuteBatch, uri = [%{public}s]", __func__, item->GetUri().ToString().c_str());
3508         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objDataAbilityResult, "uri", uri));
3509 
3510         napi_value count;
3511         NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, item->GetCount(), &count));
3512         HILOG_INFO("%{public}s, NAPI_ExecuteBatch, count = [%{public}d]", __func__, item->GetCount());
3513         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objDataAbilityResult, "count", count));
3514 
3515         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, objDataAbilityResult));
3516         index++;
3517     }
3518     HILOG_INFO("%{public}s, NAPI_ExecuteBatch, getDataAbilityResultForResult end.", __func__);
3519 }
3520 
GetDataAbilityHelper(napi_env env,napi_value thisVar,std::shared_ptr<DataAbilityHelper> & dataAbilityHelper)3521 void GetDataAbilityHelper(napi_env env, napi_value thisVar, std::shared_ptr<DataAbilityHelper>& dataAbilityHelper)
3522 {
3523     NAPIDataAbilityHelperWrapper* wrapper = nullptr;
3524     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&wrapper));
3525     if (wrapper != nullptr) {
3526         dataAbilityHelper = wrapper->GetDataAbilityHelper();
3527     }
3528 }
3529 
EraseMemberProperties(DAHelperOnOffCB * onCB)3530 void EraseMemberProperties(DAHelperOnOffCB* onCB)
3531 {
3532     if (onCB->observer) {
3533         HILOG_DEBUG("EraseMemberProperties, call ReleaseJSCallback");
3534         onCB->observer->ReleaseJSCallback();
3535     }
3536     auto dataAbilityHelper = onCB->dataAbilityHelper;
3537     if (dataAbilityHelper != nullptr) {
3538         HILOG_DEBUG("EraseMemberProperties, call Release");
3539         dataAbilityHelper->Release();
3540     }
3541 }
3542 
NeedErase(std::vector<DAHelperOnOffCB * >::iterator & iter,const std::shared_ptr<DataAbilityHelper> && dataAbilityHelper)3543 bool NeedErase(std::vector<DAHelperOnOffCB*>::iterator& iter,
3544     const std::shared_ptr<DataAbilityHelper>&& dataAbilityHelper)
3545 {
3546     if ((*iter) == nullptr) {
3547         return false;
3548     }
3549     if ((*iter)->dataAbilityHelper == dataAbilityHelper) {
3550         EraseMemberProperties(*iter);
3551         delete (*iter);
3552         (*iter) = nullptr;
3553         iter = g_registerInstances.erase(iter);
3554     } else {
3555         ++iter;
3556     }
3557     return true;
3558 }
3559 
DeleteDAHelperOnOffCB(DAHelperOnOffCB * onCB)3560 void DeleteDAHelperOnOffCB(DAHelperOnOffCB *onCB)
3561 {
3562     if (!onCB) {
3563         HILOG_INFO("DeleteDAHelperOnOffCB, onCB is nullptr, no need delete");
3564         return;
3565     }
3566     EraseMemberProperties(onCB);
3567 
3568     auto end = remove(g_registerInstances.begin(), g_registerInstances.end(), onCB);
3569     if (end != g_registerInstances.end()) {
3570         (void)g_registerInstances.erase(end);
3571     }
3572     delete onCB;
3573     onCB = nullptr;
3574 }
3575 }  // namespace AppExecFwk
3576 }  // namespace OHOS
3577