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