1 /*
2  * Copyright (c) 2021-2024 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 <vector>
19 #include <string>
20 
21 #include "data_ability_helper.h"
22 #include "napi_common_ability.h"
23 #include "data_ability_operation.h"
24 #include "data_ability_result.h"
25 #include "hilog_tag_wrapper.h"
26 #include "napi_base_context.h"
27 #include "napi_data_ability_helper_utils.h"
28 #include "napi_data_ability_observer.h"
29 #include "napi_data_ability_operation.h"
30 #include "napi_data_ability_predicates.h"
31 #include "napi_rdb_predicates.h"
32 #include "napi_result_set.h"
33 
34 #ifndef SUPPORT_GRAPHICS
35 #define DBL_MIN ((double)2.22507385850720138309e-308L)
36 #define DBL_MAX ((double)2.22507385850720138309e-308L)
37 #endif
38 
39 using namespace OHOS::AAFwk;
40 using namespace OHOS::AppExecFwk;
41 
42 namespace OHOS {
43 namespace AppExecFwk {
44 std::list<std::shared_ptr<DataAbilityHelper>> g_dataAbilityHelperList;
45 std::vector<DAHelperOnOffCB *> g_registerInstances;
46 
47 /**
48  * @brief DataAbilityHelper NAPI module registration.
49  *
50  * @param env The environment that the Node-API call is invoked under.
51  * @param exports An empty object via the exports parameter as a convenience.
52  *
53  * @return The return value from Init is treated as the exports object for the module.
54  */
DataAbilityHelperInit(napi_env env,napi_value exports)55 napi_value DataAbilityHelperInit(napi_env env, napi_value exports)
56 {
57     TAG_LOGD(AAFwkTag::FA, "called");
58     napi_property_descriptor properties[] = {
59         DECLARE_NAPI_FUNCTION("insert", NAPI_Insert),
60         DECLARE_NAPI_FUNCTION("notifyChange", NAPI_NotifyChange),
61         DECLARE_NAPI_FUNCTION("on", NAPI_Register),
62         DECLARE_NAPI_FUNCTION("off", NAPI_UnRegister),
63         DECLARE_NAPI_FUNCTION("delete", NAPI_Delete),
64         DECLARE_NAPI_FUNCTION("query", NAPI_Query),
65         DECLARE_NAPI_FUNCTION("update", NAPI_Update),
66         DECLARE_NAPI_FUNCTION("batchInsert", NAPI_BatchInsert),
67         DECLARE_NAPI_FUNCTION("openFile", NAPI_OpenFile),
68         DECLARE_NAPI_FUNCTION("getType", NAPI_GetType),
69         DECLARE_NAPI_FUNCTION("getFileTypes", NAPI_GetFileTypes),
70         DECLARE_NAPI_FUNCTION("normalizeUri", NAPI_NormalizeUri),
71         DECLARE_NAPI_FUNCTION("denormalizeUri", NAPI_DenormalizeUri),
72         DECLARE_NAPI_FUNCTION("executeBatch", NAPI_ExecuteBatch),
73         DECLARE_NAPI_FUNCTION("call", NAPI_Call),
74     };
75 
76     napi_value constructor;
77     NAPI_CALL(env,
78         napi_define_class(env,
79             "dataAbilityHelper",
80             NAPI_AUTO_LENGTH,
81             DataAbilityHelperConstructor,
82             nullptr,
83             sizeof(properties) / sizeof(*properties),
84             properties,
85             &constructor));
86     NAPI_CALL(env, SaveGlobalDataAbilityHelper(env, constructor));
87     return exports;
88 }
89 
DataAbilityHelperConstructor(napi_env env,napi_callback_info info)90 napi_value DataAbilityHelperConstructor(napi_env env, napi_callback_info info)
91 {
92     size_t argc = ARGS_TWO;
93     napi_value argv[ARGS_TWO] = {nullptr};
94     napi_value thisVar = nullptr;
95     auto& dataAbilityHelperStatus = GetDataAbilityHelperStatus();
96     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
97     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments");
98 
99     std::shared_ptr<DataAbilityHelper> dataAbilityHelper = nullptr;
100     bool stageMode = false;
101     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, argv[0], stageMode);
102     if (status != napi_ok) {
103         auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
104         if (ability == nullptr) {
105             TAG_LOGE(AAFwkTag::FA, "null ability");
106             return nullptr;
107         }
108         std::string strUri = NapiValueToStringUtf8(env, argv[0]);
109         TAG_LOGI(AAFwkTag::FA, "strUri=%{public}s", strUri.c_str());
110         dataAbilityHelper = DataAbilityHelper::Creator(ability->GetContext(), std::make_shared<Uri>(strUri));
111     } else {
112         if (stageMode) {
113             auto context = OHOS::AbilityRuntime::GetStageModeContext(env, argv[0]);
114             if (context == nullptr) {
115                 TAG_LOGE(AAFwkTag::FA, "Failed to get native context instance");
116                 return nullptr;
117             }
118             std::string strUri = NapiValueToStringUtf8(env, argv[PARAM1]);
119             TAG_LOGI(AAFwkTag::FA, "Stage Model: strUri = %{public}s", strUri.c_str());
120             dataAbilityHelper = DataAbilityHelper::Creator(context, std::make_shared<Uri>(strUri));
121         } else {
122             auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
123             if (ability == nullptr) {
124                 TAG_LOGE(AAFwkTag::FA, "Failed to get native context instance");
125                 return nullptr;
126             }
127             std::string strUri = NapiValueToStringUtf8(env, argv[PARAM1]);
128             TAG_LOGI(AAFwkTag::FA, "FA Model: strUri = %{public}s", strUri.c_str());
129             dataAbilityHelper = DataAbilityHelper::Creator(ability->GetContext(), std::make_shared<Uri>(strUri));
130         }
131     }
132 
133     if (dataAbilityHelper == nullptr) {
134         TAG_LOGE(AAFwkTag::FA, "dataAbilityHelper is nullptr");
135         dataAbilityHelperStatus = false;
136         return nullptr;
137     }
138     dataAbilityHelper->SetCallFromJs();
139     g_dataAbilityHelperList.emplace_back(dataAbilityHelper);
140     auto wrapper = new NAPIDataAbilityHelperWrapper(dataAbilityHelper);
141 
142     status = napi_wrap(
143         env,
144         thisVar,
145         wrapper,
146         [](napi_env env, void *data, void *hint) {
147             auto objectInfo = static_cast<NAPIDataAbilityHelperWrapper *>(data);
148             if (objectInfo == nullptr) {
149                 TAG_LOGW(AAFwkTag::FA, "null objectInfo");
150                 return;
151             }
152             TAG_LOGD(AAFwkTag::FA, "DAHelper finalize_cb dataAbilityHelperList.size = %{public}zu, "
153                 "regInstances_.size = %{public}zu",
154                 g_dataAbilityHelperList.size(), g_registerInstances.size());
155             for (auto iter = g_registerInstances.begin(); iter != g_registerInstances.end();) {
156                 if (!NeedErase(iter, objectInfo->GetDataAbilityHelper())) {
157                     iter = g_registerInstances.erase(iter);
158                 }
159             }
160             g_dataAbilityHelperList.remove_if(
161                 [objectInfo](const std::shared_ptr<DataAbilityHelper> &dataAbilityHelper) {
162                     return objectInfo->GetDataAbilityHelper() == dataAbilityHelper;
163                 });
164             TAG_LOGD(AAFwkTag::FA, "dataAbilityHelperList.size = %{public}zu, regInstances_.size = %{public}zu",
165                 g_dataAbilityHelperList.size(), g_registerInstances.size());
166             delete objectInfo;
167             objectInfo = nullptr;
168         },
169         nullptr,
170         nullptr);
171     if (status != napi_ok && wrapper != nullptr) {
172         TAG_LOGE(AAFwkTag::FA, "napi_wrap Failed: %{public}d", status);
173         delete wrapper;
174         return nullptr;
175     }
176 
177     dataAbilityHelperStatus = true;
178     return thisVar;
179 }
180 
181 /**
182  * @brief DataAbilityHelper NAPI method : insert.
183  *
184  * @param env The environment that the Node-API call is invoked under.
185  * @param info The callback info passed into the callback function.
186  *
187  * @return The return value from NAPI C++ to JS for the module.
188  */
NAPI_Insert(napi_env env,napi_callback_info info)189 napi_value NAPI_Insert(napi_env env, napi_callback_info info)
190 {
191     TAG_LOGI(AAFwkTag::FA, "called");
192     DAHelperInsertCB *insertCB = new (std::nothrow) DAHelperInsertCB;
193     if (insertCB == nullptr) {
194         TAG_LOGE(AAFwkTag::FA, "null insertCB");
195         return WrapVoidToJS(env);
196     }
197     insertCB->cbBase.cbInfo.env = env;
198     insertCB->cbBase.asyncWork = nullptr;
199     insertCB->cbBase.deferred = nullptr;
200     insertCB->cbBase.ability = nullptr;
201 
202     napi_value ret = InsertWrap(env, info, insertCB);
203     if (ret == nullptr) {
204         TAG_LOGE(AAFwkTag::FA, "null ret");
205         delete insertCB;
206         insertCB = nullptr;
207         ret = WrapVoidToJS(env);
208     }
209     TAG_LOGI(AAFwkTag::FA, "end");
210     return ret;
211 }
212 
213 /**
214  * @brief Insert processing function.
215  *
216  * @param env The environment that the Node-API call is invoked under.
217  * @param insertCB Process data asynchronously.
218  *
219  * @return Return JS data successfully, otherwise return nullptr.
220  */
InsertWrap(napi_env env,napi_callback_info info,DAHelperInsertCB * insertCB)221 napi_value InsertWrap(napi_env env, napi_callback_info info, DAHelperInsertCB *insertCB)
222 {
223     TAG_LOGI(AAFwkTag::FA, "called");
224     size_t argcAsync = ARGS_THREE;
225     const size_t argcPromise = ARGS_TWO;
226     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
227     napi_value args[ARGS_MAX_COUNT] = {nullptr};
228     napi_value ret = nullptr;
229     napi_value thisVar = nullptr;
230 
231     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
232     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
233         TAG_LOGE(AAFwkTag::FA, "invalid argc");
234         return nullptr;
235     }
236 
237     napi_valuetype valuetype = napi_undefined;
238     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
239     if (valuetype == napi_string) {
240         insertCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
241         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", insertCB->uri.c_str());
242     } else {
243         TAG_LOGE(AAFwkTag::FA, "wrong argument type");
244     }
245 
246     insertCB->valueBucket.Clear();
247     AnalysisValuesBucket(insertCB->valueBucket, env, args[PARAM1]);
248     GetDataAbilityHelper(env, thisVar, insertCB->dataAbilityHelper);
249 
250     if (argcAsync > argcPromise) {
251         ret = InsertAsync(env, args, ARGS_TWO, insertCB);
252     } else {
253         ret = InsertPromise(env, insertCB);
254     }
255     TAG_LOGI(AAFwkTag::FA, "end");
256     return ret;
257 }
258 
AnalysisValuesBucket(NativeRdb::ValuesBucket & valuesBucket,const napi_env & env,const napi_value & arg)259 void AnalysisValuesBucket(NativeRdb::ValuesBucket &valuesBucket, const napi_env &env, const napi_value &arg)
260 {
261     napi_value keys = nullptr;
262     napi_get_property_names(env, arg, &keys);
263     uint32_t arrLen = 0;
264     napi_status status = napi_get_array_length(env, keys, &arrLen);
265     if (status != napi_ok) {
266         TAG_LOGE(AAFwkTag::FA, "ValuesBucket error");
267         return;
268     }
269     TAG_LOGI(AAFwkTag::FA, "ValuesBucket num:%{public}d ", arrLen);
270     for (size_t i = 0; i < arrLen; ++i) {
271         napi_value key = nullptr;
272         (void)napi_get_element(env, keys, i, &key);
273         std::string keyStr = UnwrapStringFromJS(env, key);
274         napi_value value = nullptr;
275         napi_get_property(env, arg, key, &value);
276 
277         SetValuesBucketObject(valuesBucket, env, keyStr, value);
278     }
279 }
280 
SetValuesBucketObject(NativeRdb::ValuesBucket & valuesBucket,const napi_env & env,std::string keyStr,napi_value value)281 void SetValuesBucketObject(
282     NativeRdb::ValuesBucket &valuesBucket, const napi_env &env, std::string keyStr, napi_value value)
283 {
284     napi_valuetype valueType = napi_undefined;
285     napi_typeof(env, value, &valueType);
286     if (valueType == napi_string) {
287         std::string valueString = UnwrapStringFromJS(env, value);
288         TAG_LOGI(AAFwkTag::FA, "ValueObject type:%{public}d, key:%{public}s, value:%{private}s",
289             valueType,
290             keyStr.c_str(),
291             valueString.c_str());
292         valuesBucket.PutString(keyStr, valueString);
293     } else if (valueType == napi_number) {
294         double valueNumber = 0;
295         napi_get_value_double(env, value, &valueNumber);
296         valuesBucket.PutDouble(keyStr, valueNumber);
297         TAG_LOGI(AAFwkTag::FA, "ValueObject type:%{public}d, key:%{public}s, value:%{private}lf", valueType,
298             keyStr.c_str(), valueNumber);
299     } else if (valueType == napi_boolean) {
300         bool valueBool = false;
301         napi_get_value_bool(env, value, &valueBool);
302         TAG_LOGI(AAFwkTag::FA, "ValueObject type:%{public}d, key:%{public}s, value:%{private}d", valueType,
303             keyStr.c_str(), valueBool);
304         valuesBucket.PutBool(keyStr, valueBool);
305     } else if (valueType == napi_null) {
306         valuesBucket.PutNull(keyStr);
307         TAG_LOGI(AAFwkTag::FA, "ValueObject type:%{public}d, key:%{public}s, value:null", valueType, keyStr.c_str());
308     } else if (valueType == napi_object) {
309         TAG_LOGI(
310             AAFwkTag::FA, "ValueObject type:%{public}d, key:%{public}s, value:Uint8Array", valueType, keyStr.c_str());
311         valuesBucket.PutBlob(keyStr, ConvertU8Vector(env, value));
312     } else {
313         TAG_LOGE(AAFwkTag::FA, "valuesBucket error");
314     }
315 }
316 /**
317  * @brief Parse the ValuesBucket parameters.
318  *
319  * @param param Indicates the want parameters saved the parse result.
320  * @param env The environment that the Node-API call is invoked under.
321  * @param args Indicates the arguments passed into the callback.
322  *
323  * @return The return value from NAPI C++ to JS for the module.
324  */
UnwrapValuesBucket(std::string & value,napi_env env,napi_value args)325 napi_value UnwrapValuesBucket(std::string &value, napi_env env, napi_value args)
326 {
327     TAG_LOGI(AAFwkTag::FA, "called");
328     napi_valuetype valueType = napi_undefined;
329     napi_typeof(env, args, &valueType);
330     if (valueType != napi_object) {
331         TAG_LOGE(AAFwkTag::FA, "valueType != napi_object");
332         return nullptr;
333     }
334 
335     std::string strValue = "";
336     if (UnwrapStringByPropertyName(env, args, "value", strValue)) {
337         TAG_LOGI(AAFwkTag::FA, "strValue=%{private}s", strValue.c_str());
338         value = strValue;
339     } else {
340         TAG_LOGE(AAFwkTag::FA, "invalid value");
341         return nullptr;
342     }
343 
344     napi_value result;
345     NAPI_CALL(env, napi_create_int32(env, 1, &result));
346     TAG_LOGI(AAFwkTag::FA, "end");
347     return result;
348 }
349 
350 /**
351  * @brief DataAbilityHelper NAPI method : notifyChange.
352  *
353  * @param env The environment that the Node-API call is invoked under.
354  * @param info The callback info passed into the callback function.
355  *
356  * @return The return value from NAPI C++ to JS for the module.
357  */
NAPI_NotifyChange(napi_env env,napi_callback_info info)358 napi_value NAPI_NotifyChange(napi_env env, napi_callback_info info)
359 {
360     TAG_LOGI(AAFwkTag::FA, "called");
361     DAHelperNotifyChangeCB *notifyChangeCB = new DAHelperNotifyChangeCB;
362     notifyChangeCB->cbBase.cbInfo.env = env;
363     notifyChangeCB->cbBase.asyncWork = nullptr;
364     notifyChangeCB->cbBase.deferred = nullptr;
365     notifyChangeCB->cbBase.ability = nullptr;
366 
367     napi_value ret = NotifyChangeWrap(env, info, notifyChangeCB);
368     if (ret == nullptr) {
369         TAG_LOGE(AAFwkTag::FA, "null ret");
370         delete notifyChangeCB;
371         notifyChangeCB = nullptr;
372         ret = WrapVoidToJS(env);
373     }
374     TAG_LOGI(AAFwkTag::FA, "end");
375     return ret;
376 }
377 
378 /**
379  * @brief NotifyChange processing function.
380  *
381  * @param env The environment that the Node-API call is invoked under.
382  * @param notifyChangeCB Process data asynchronously.
383  *
384  * @return Return JS data successfully, otherwise return nullptr.
385  */
NotifyChangeWrap(napi_env env,napi_callback_info info,DAHelperNotifyChangeCB * notifyChangeCB)386 napi_value NotifyChangeWrap(napi_env env, napi_callback_info info, DAHelperNotifyChangeCB *notifyChangeCB)
387 {
388     TAG_LOGI(AAFwkTag::FA, "called");
389     size_t argcAsync = ARGS_TWO;
390     const size_t argcPromise = ARGS_ONE;
391     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
392     napi_value args[ARGS_MAX_COUNT] = {nullptr};
393     napi_value ret = nullptr;
394     napi_value thisVar = nullptr;
395 
396     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
397     if (argcAsync > argCountWithAsync) {
398         TAG_LOGE(AAFwkTag::FA, "invalid argc");
399         return nullptr;
400     }
401 
402     napi_valuetype valuetype = napi_undefined;
403     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
404     if (valuetype == napi_string) {
405         notifyChangeCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
406         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", notifyChangeCB->uri.c_str());
407     }
408     GetDataAbilityHelper(env, thisVar, notifyChangeCB->dataAbilityHelper);
409 
410     if (argcAsync > argcPromise) {
411         ret = NotifyChangeAsync(env, args, argcAsync, argcPromise, notifyChangeCB);
412     } else {
413         ret = NotifyChangePromise(env, notifyChangeCB);
414     }
415     return ret;
416 }
417 
418 /**
419  * @brief DataAbilityHelper NAPI method : on.
420  *
421  * @param env The environment that the Node-API call is invoked under.
422  * @param info The callback info passed into the callback function.
423  *
424  * @return The return value from NAPI C++ to JS for the module.
425  */
NAPI_Register(napi_env env,napi_callback_info info)426 napi_value NAPI_Register(napi_env env, napi_callback_info info)
427 {
428     TAG_LOGI(AAFwkTag::FA, "called");
429     DAHelperOnOffCB *onCB = new DAHelperOnOffCB;
430     onCB->cbBase.cbInfo.env = env;
431     onCB->cbBase.asyncWork = nullptr;
432     onCB->cbBase.deferred = nullptr;
433     onCB->cbBase.ability = nullptr;
434 
435     napi_value ret = RegisterWrap(env, info, onCB);
436     if (ret == nullptr) {
437         TAG_LOGE(AAFwkTag::FA, "null ret");
438         delete onCB;
439         onCB = nullptr;
440         ret = WrapVoidToJS(env);
441     }
442     TAG_LOGI(AAFwkTag::FA, "end");
443     return ret;
444 }
445 
446 /**
447  * @brief On processing function.
448  *
449  * @param env The environment that the Node-API call is invoked under.
450  * @param onCB Process data asynchronously.
451  *
452  * @return Return JS data successfully, otherwise return nullptr.
453  */
RegisterWrap(napi_env env,napi_callback_info info,DAHelperOnOffCB * onCB)454 napi_value RegisterWrap(napi_env env, napi_callback_info info, DAHelperOnOffCB *onCB)
455 {
456     TAG_LOGI(AAFwkTag::FA, "called");
457     size_t argcAsync = ARGS_THREE;
458     const size_t argcPromise = ARGS_TWO;
459     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
460     napi_value args[ARGS_MAX_COUNT] = {nullptr};
461     napi_value ret = nullptr;
462     napi_value thisVar = nullptr;
463 
464     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
465     if (argcAsync > argCountWithAsync) {
466         TAG_LOGE(AAFwkTag::FA, "invalid argc");
467         return nullptr;
468     }
469 
470     onCB->result = NO_ERROR;
471     napi_valuetype valuetype = napi_undefined;
472     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
473     if (valuetype == napi_string) {
474         std::string type = NapiValueToStringUtf8(env, args[PARAM0]);
475         if (type == "dataChange") {
476             TAG_LOGI(AAFwkTag::FA, "type:%{public}s", type.c_str());
477         } else {
478             TAG_LOGE(AAFwkTag::FA, "error type: %{public}s", type.c_str());
479             onCB->result = INVALID_PARAMETER;
480         }
481     } else {
482         TAG_LOGE(AAFwkTag::FA, "wrong type");
483         onCB->result = INVALID_PARAMETER;
484     }
485 
486     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
487     if (valuetype == napi_string) {
488         onCB->uri = NapiValueToStringUtf8(env, args[PARAM1]);
489         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", onCB->uri.c_str());
490     } else {
491         TAG_LOGE(AAFwkTag::FA, "wrong type");
492         onCB->result = INVALID_PARAMETER;
493     }
494     GetDataAbilityHelper(env, thisVar, onCB->dataAbilityHelper);
495 
496     ret = RegisterAsync(env, args, argcAsync, argcPromise, onCB);
497     return ret;
498 }
499 
RegisterAsync(napi_env env,napi_value * args,size_t argcAsync,const size_t argcPromise,DAHelperOnOffCB * onCB)500 napi_value RegisterAsync(
501     napi_env env, napi_value *args, size_t argcAsync, const size_t argcPromise, DAHelperOnOffCB *onCB)
502 {
503     TAG_LOGI(AAFwkTag::FA, "called");
504     if (args == nullptr || onCB == nullptr) {
505         TAG_LOGE(AAFwkTag::FA, "null param");
506         return nullptr;
507     }
508     napi_value resourceName = nullptr;
509     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
510 
511     napi_valuetype valuetype = napi_undefined;
512     NAPI_CALL(env, napi_typeof(env, args[argcPromise], &valuetype));
513     if (valuetype == napi_function) {
514         TAG_LOGI(AAFwkTag::FA, "valuetype is napi_function");
515         NAPI_CALL(env, napi_create_reference(env, args[argcPromise], 1, &onCB->cbBase.cbInfo.callback));
516     } else {
517         TAG_LOGI(AAFwkTag::FA, "not valuetype isn't napi_function");
518         onCB->result = INVALID_PARAMETER;
519     }
520 
521     sptr<NAPIDataAbilityObserver> observer(new NAPIDataAbilityObserver());
522     observer->SetEnv(env);
523     observer->SetCallbackRef(onCB->cbBase.cbInfo.callback);
524     onCB->observer = observer;
525 
526     if (onCB->result == NO_ERROR) {
527         g_registerInstances.emplace_back(onCB);
528     }
529 
530     NAPI_CALL(env,
531         napi_create_async_work(
532             env,
533             nullptr,
534             resourceName,
535             RegisterExecuteCB,
536             RegisterCompleteCB,
537             static_cast<void *>(onCB),
538             &onCB->cbBase.asyncWork));
539     NAPI_CALL(env, napi_queue_async_work(env, onCB->cbBase.asyncWork));
540     napi_value result = nullptr;
541     NAPI_CALL(env, napi_get_null(env, &result));
542     return result;
543 }
544 
RegisterExecuteCB(napi_env env,void * data)545 void RegisterExecuteCB(napi_env env, void *data)
546 {
547     TAG_LOGI(AAFwkTag::FA, "called");
548     DAHelperOnOffCB *onCB = static_cast<DAHelperOnOffCB *>(data);
549     auto onCBIter = std::find(g_registerInstances.begin(), g_registerInstances.end(), onCB);
550     if (onCBIter == g_registerInstances.end()) {
551         // onCB is invalid or onCB has been delete
552         TAG_LOGE(AAFwkTag::FA, "invalid onCB");
553         return;
554     }
555 
556     auto dataAbilityHelper = onCB->dataAbilityHelper;
557     if (dataAbilityHelper != nullptr) {
558         if (onCB->result != INVALID_PARAMETER && !onCB->uri.empty() && onCB->cbBase.cbInfo.callback != nullptr) {
559             OHOS::Uri uri(onCB->uri);
560             dataAbilityHelper->RegisterObserver(uri, onCB->observer);
561         } else {
562             TAG_LOGE(AAFwkTag::FA, "empty uri or null callback");
563         }
564     }
565 }
566 
RegisterCompleteCB(napi_env env,napi_status status,void * data)567 void RegisterCompleteCB(napi_env env, napi_status status, void *data)
568 {
569     TAG_LOGI(AAFwkTag::FA, "complete");
570     DAHelperOnOffCB *onCB = static_cast<DAHelperOnOffCB *>(data);
571     if (onCB == nullptr) {
572         TAG_LOGE(AAFwkTag::FA, "null onCB");
573         return;
574     }
575 
576     auto onCBIter = std::find(g_registerInstances.begin(), g_registerInstances.end(), onCB);
577     if (onCBIter == g_registerInstances.end()) {
578         // onCB is invalid or onCB has been delete
579         TAG_LOGE(AAFwkTag::FA, "invalid onCB");
580         return;
581     }
582 
583     if (onCB->result == NO_ERROR) {
584         return;
585     }
586     TAG_LOGI(AAFwkTag::FA, "input params onCB will be release");
587     DeleteDAHelperOnOffCB(onCB);
588 }
589 
590 /**
591  * @brief DataAbilityHelper NAPI method : Off.
592  *
593  * @param env The environment that the Node-API call is invoked under.
594  * @param info The callback info passed into the callback function.
595  *
596  * @return The return value from NAPI C++ to JS for the module.
597  */
NAPI_UnRegister(napi_env env,napi_callback_info info)598 napi_value NAPI_UnRegister(napi_env env, napi_callback_info info)
599 {
600     TAG_LOGI(AAFwkTag::FA, "called");
601     DAHelperOnOffCB *offCB = new DAHelperOnOffCB;
602     offCB->cbBase.cbInfo.env = env;
603     offCB->cbBase.asyncWork = nullptr;
604     offCB->cbBase.deferred = nullptr;
605     offCB->cbBase.ability = nullptr;
606 
607     napi_value ret = UnRegisterWrap(env, info, offCB);
608     if (ret == nullptr) {
609         TAG_LOGE(AAFwkTag::FA, "null ret");
610         delete offCB;
611         offCB = nullptr;
612         ret = WrapVoidToJS(env);
613     }
614     TAG_LOGI(AAFwkTag::FA, "end");
615     return ret;
616 }
617 
618 /**
619  * @brief Off processing function.
620  *
621  * @param env The environment that the Node-API call is invoked under.
622  * @param offCB Process data asynchronously.
623  *
624  * @return Return JS data successfully, otherwise return nullptr.
625  */
UnRegisterWrap(napi_env env,napi_callback_info info,DAHelperOnOffCB * offCB)626 napi_value UnRegisterWrap(napi_env env, napi_callback_info info, DAHelperOnOffCB *offCB)
627 {
628     TAG_LOGI(AAFwkTag::FA, "called");
629     size_t argcAsync = ARGS_THREE;
630     const size_t argCountWithAsync = ARGS_TWO + ARGS_ASYNC_COUNT;
631     napi_value args[ARGS_MAX_COUNT] = {nullptr};
632     napi_value ret = nullptr;
633     napi_value thisVar = nullptr;
634 
635     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
636     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
637         TAG_LOGE(AAFwkTag::FA, "invalid argc");
638         return nullptr;
639     }
640 
641     offCB->result = NO_ERROR;
642     napi_valuetype valuetype = napi_undefined;
643     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
644     if (valuetype == napi_string) {
645         std::string type = NapiValueToStringUtf8(env, args[PARAM0]);
646         if (type == "dataChange") {
647             TAG_LOGI(AAFwkTag::FA, "Wrong type=%{public}s", type.c_str());
648         } else {
649             TAG_LOGE(AAFwkTag::FA, "Wrong argument type %{public}s", type.c_str());
650             offCB->result = INVALID_PARAMETER;
651         }
652     } else {
653         TAG_LOGE(AAFwkTag::FA, "wrong argument type");
654         offCB->result = INVALID_PARAMETER;
655     }
656 
657     offCB->uri = "";
658     if (argcAsync > ARGS_TWO) {
659         // parse uri and callback
660         NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
661         if (valuetype == napi_string) {
662             offCB->uri = NapiValueToStringUtf8(env, args[PARAM1]);
663             TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", offCB->uri.c_str());
664         } else {
665             TAG_LOGE(AAFwkTag::FA, "Wrong argument type");
666             offCB->result = INVALID_PARAMETER;
667         }
668         NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valuetype));
669         if (valuetype == napi_function) {
670             NAPI_CALL(env, napi_create_reference(env, args[PARAM2], 1, &offCB->cbBase.cbInfo.callback));
671         } else {
672             TAG_LOGE(AAFwkTag::FA, "Wrong argument type");
673             offCB->result = INVALID_PARAMETER;
674         }
675     } else {
676         // parse uri or callback
677         NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
678         if (valuetype == napi_string) {
679             offCB->uri = NapiValueToStringUtf8(env, args[PARAM1]);
680             TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", offCB->uri.c_str());
681         } else if (valuetype == napi_function) {
682             NAPI_CALL(env, napi_create_reference(env, args[PARAM1], 1, &offCB->cbBase.cbInfo.callback));
683         } else {
684             TAG_LOGE(AAFwkTag::FA, "Wrong argument type");
685             offCB->result = INVALID_PARAMETER;
686         }
687     }
688     GetDataAbilityHelper(env, thisVar, offCB->dataAbilityHelper);
689 
690     ret = UnRegisterSync(env, offCB);
691     return ret;
692 }
693 
UnRegisterSync(napi_env env,DAHelperOnOffCB * offCB)694 napi_value UnRegisterSync(napi_env env, DAHelperOnOffCB *offCB)
695 {
696     TAG_LOGI(AAFwkTag::FA, "syncCallback");
697     if (offCB == nullptr) {
698         TAG_LOGE(AAFwkTag::FA, "null offCB");
699         return nullptr;
700     }
701     napi_value resourceName = nullptr;
702     NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
703 
704     if (offCB->result == NO_ERROR) {
705         FindRegisterObs(env, offCB);
706     }
707 
708     TAG_LOGI(AAFwkTag::FA, "notifyList size: %{public}zu", offCB->NotifyList.size());
709     for (auto &iter : offCB->NotifyList) {
710         if (iter != nullptr && iter->observer != nullptr) {
711             OHOS::Uri uri(iter->uri);
712             auto dataAbilityHelper = iter->dataAbilityHelper;
713             if (dataAbilityHelper != nullptr) {
714                 dataAbilityHelper->UnregisterObserver(uri, iter->observer);
715             }
716             offCB->DestroyList.emplace_back(iter);
717         }
718     }
719     offCB->NotifyList.clear();
720 
721     TAG_LOGI(AAFwkTag::FA, "offCB->DestroyList size is %{public}zu", offCB->DestroyList.size());
722     for (auto &iter : offCB->DestroyList) {
723         if (iter->observer != nullptr) {
724             iter->observer->ReleaseJSCallback();
725             delete iter;
726             iter = nullptr;
727             TAG_LOGI(AAFwkTag::FA, "ReleaseJSCallback");
728         }
729     }
730 
731     offCB->DestroyList.clear();
732     delete offCB;
733     offCB = nullptr;
734     napi_value result = nullptr;
735     NAPI_CALL(env, napi_get_null(env, &result));
736     return result;
737 }
738 
FindRegisterObs(napi_env env,DAHelperOnOffCB * data)739 void FindRegisterObs(napi_env env, DAHelperOnOffCB *data)
740 {
741     TAG_LOGI(AAFwkTag::FA, "execute");
742     if (data == nullptr || data->dataAbilityHelper == nullptr) {
743         TAG_LOGE(AAFwkTag::FA, "null param");
744         return;
745     }
746 
747     TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", data->uri.c_str());
748     if (!data->uri.empty()) {
749         // if match uri, unregister all observers corresponding the uri
750         std::string strUri = data->uri;
751         auto iter = g_registerInstances.begin();
752         while (iter != g_registerInstances.end()) {
753             DAHelperOnOffCB *helper = *iter;
754             if (helper == nullptr || helper->uri != strUri) {
755                 iter++;
756                 continue;
757             }
758             data->NotifyList.emplace_back(helper);
759             iter = g_registerInstances.erase(iter);
760             TAG_LOGI(AAFwkTag::FA, "Instances erase size = %{public}zu", g_registerInstances.size());
761         }
762     } else {
763         TAG_LOGE(AAFwkTag::FA, "null uri");
764     }
765     TAG_LOGI(AAFwkTag::FA, "execute end %{public}zu",
766         data->NotifyList.size());
767 }
NAPI_GetType(napi_env env,napi_callback_info info)768 napi_value NAPI_GetType(napi_env env, napi_callback_info info)
769 {
770     TAG_LOGI(AAFwkTag::FA, "called");
771     DAHelperGetTypeCB *gettypeCB = new (std::nothrow) DAHelperGetTypeCB;
772     if (gettypeCB == nullptr) {
773         TAG_LOGE(AAFwkTag::FA, "null gettypeCB");
774         return WrapVoidToJS(env);
775     }
776     gettypeCB->cbBase.cbInfo.env = env;
777     gettypeCB->cbBase.asyncWork = nullptr;
778     gettypeCB->cbBase.deferred = nullptr;
779     gettypeCB->cbBase.ability = nullptr;
780 
781     napi_value ret = GetTypeWrap(env, info, gettypeCB);
782     if (ret == nullptr) {
783         TAG_LOGE(AAFwkTag::FA, "null ret");
784         delete gettypeCB;
785         gettypeCB = nullptr;
786         ret = WrapVoidToJS(env);
787     }
788     return ret;
789 }
790 
GetTypeWrap(napi_env env,napi_callback_info info,DAHelperGetTypeCB * gettypeCB)791 napi_value GetTypeWrap(napi_env env, napi_callback_info info, DAHelperGetTypeCB *gettypeCB)
792 {
793     TAG_LOGI(AAFwkTag::FA, "start");
794     size_t argcAsync = ARGS_TWO;
795     const size_t argcPromise = ARGS_ONE;
796     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
797     napi_value args[ARGS_MAX_COUNT] = {nullptr};
798     napi_value ret = nullptr;
799     napi_value thisVar = nullptr;
800 
801     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
802     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
803         TAG_LOGE(AAFwkTag::FA, "invalid argc");
804         return nullptr;
805     }
806 
807     napi_valuetype valuetype = napi_undefined;
808     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
809     if (valuetype == napi_string) {
810         gettypeCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
811         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", gettypeCB->uri.c_str());
812     } else {
813         TAG_LOGE(AAFwkTag::FA, "not string");
814     }
815     GetDataAbilityHelper(env, thisVar, gettypeCB->dataAbilityHelper);
816 
817     if (argcAsync > argcPromise) {
818         ret = GetTypeAsync(env, args, ARGS_ONE, gettypeCB);
819     } else {
820         ret = GetTypePromise(env, gettypeCB);
821     }
822     return ret;
823 }
824 
NAPI_GetFileTypes(napi_env env,napi_callback_info info)825 napi_value NAPI_GetFileTypes(napi_env env, napi_callback_info info)
826 {
827     TAG_LOGI(AAFwkTag::FA, "called");
828     DAHelperGetFileTypesCB *getfiletypesCB = new (std::nothrow) DAHelperGetFileTypesCB;
829     if (getfiletypesCB == nullptr) {
830         TAG_LOGE(AAFwkTag::FA, "null getfiletypesCB");
831         return WrapVoidToJS(env);
832     }
833     getfiletypesCB->cbBase.cbInfo.env = env;
834     getfiletypesCB->cbBase.asyncWork = nullptr;
835     getfiletypesCB->cbBase.deferred = nullptr;
836     getfiletypesCB->cbBase.ability = nullptr;
837 
838     napi_value ret = GetFileTypesWrap(env, info, getfiletypesCB);
839     if (ret == nullptr) {
840         TAG_LOGE(AAFwkTag::FA, "null ret");
841         delete getfiletypesCB;
842         getfiletypesCB = nullptr;
843         ret = WrapVoidToJS(env);
844     }
845     return ret;
846 }
847 
GetFileTypesWrap(napi_env env,napi_callback_info info,DAHelperGetFileTypesCB * getfiletypesCB)848 napi_value GetFileTypesWrap(napi_env env, napi_callback_info info, DAHelperGetFileTypesCB *getfiletypesCB)
849 {
850     TAG_LOGI(AAFwkTag::FA, "called");
851     size_t argcAsync = ARGS_THREE;
852     const size_t argcPromise = ARGS_TWO;
853     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
854     napi_value args[ARGS_MAX_COUNT] = {nullptr};
855     napi_value ret = nullptr;
856     napi_value thisVar = nullptr;
857 
858     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
859     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
860         TAG_LOGE(AAFwkTag::FA, "invalid argc");
861         return nullptr;
862     }
863 
864     napi_valuetype valuetype = napi_undefined;
865     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
866     if (valuetype == napi_string) {
867         getfiletypesCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
868         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", getfiletypesCB->uri.c_str());
869     }
870 
871     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
872     if (valuetype == napi_string) {
873         getfiletypesCB->mimeTypeFilter = NapiValueToStringUtf8(env, args[PARAM1]);
874         TAG_LOGI(
875             AAFwkTag::FA, "mimeTypeFilter=%{public}s", getfiletypesCB->mimeTypeFilter.c_str());
876     }
877     GetDataAbilityHelper(env, thisVar, getfiletypesCB->dataAbilityHelper);
878 
879     if (argcAsync > argcPromise) {
880         ret = GetFileTypesAsync(env, args, ARGS_TWO, getfiletypesCB);
881     } else {
882         ret = GetFileTypesPromise(env, getfiletypesCB);
883     }
884 
885     return ret;
886 }
887 
NAPI_NormalizeUri(napi_env env,napi_callback_info info)888 napi_value NAPI_NormalizeUri(napi_env env, napi_callback_info info)
889 {
890     TAG_LOGI(AAFwkTag::FA, "called");
891     DAHelperNormalizeUriCB *normalizeuriCB = new (std::nothrow) DAHelperNormalizeUriCB;
892     if (normalizeuriCB == nullptr) {
893         TAG_LOGE(AAFwkTag::FA, "null normalizeuriCB");
894         return WrapVoidToJS(env);
895     }
896     normalizeuriCB->cbBase.cbInfo.env = env;
897     normalizeuriCB->cbBase.asyncWork = nullptr;
898     normalizeuriCB->cbBase.deferred = nullptr;
899     normalizeuriCB->cbBase.ability = nullptr;
900 
901     napi_value ret = NormalizeUriWrap(env, info, normalizeuriCB);
902     if (ret == nullptr) {
903         TAG_LOGE(AAFwkTag::FA, "null ret");
904         delete normalizeuriCB;
905         normalizeuriCB = nullptr;
906         ret = WrapVoidToJS(env);
907     }
908 
909     return ret;
910 }
911 
NormalizeUriWrap(napi_env env,napi_callback_info info,DAHelperNormalizeUriCB * normalizeuriCB)912 napi_value NormalizeUriWrap(napi_env env, napi_callback_info info, DAHelperNormalizeUriCB *normalizeuriCB)
913 {
914     TAG_LOGI(AAFwkTag::FA, "begin");
915     size_t argcAsync = ARGS_TWO;
916     const size_t argcPromise = ARGS_ONE;
917     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
918     napi_value args[ARGS_MAX_COUNT] = {nullptr};
919     napi_value ret = nullptr;
920     napi_value thisVar = nullptr;
921 
922     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
923     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
924         TAG_LOGE(AAFwkTag::FA, "invalid argc");
925         return nullptr;
926     }
927 
928     napi_valuetype valuetype = napi_undefined;
929     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
930     if (valuetype == napi_string) {
931         normalizeuriCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
932         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", normalizeuriCB->uri.c_str());
933     }
934     GetDataAbilityHelper(env, thisVar, normalizeuriCB->dataAbilityHelper);
935 
936     if (argcAsync > argcPromise) {
937         ret = NormalizeUriAsync(env, args, ARGS_ONE, normalizeuriCB);
938     } else {
939         ret = NormalizeUriPromise(env, normalizeuriCB);
940     }
941 
942     return ret;
943 }
944 
NAPI_DenormalizeUri(napi_env env,napi_callback_info info)945 napi_value NAPI_DenormalizeUri(napi_env env, napi_callback_info info)
946 {
947     TAG_LOGI(AAFwkTag::FA, "called");
948     DAHelperDenormalizeUriCB *denormalizeuriCB = new (std::nothrow) DAHelperDenormalizeUriCB;
949     if (denormalizeuriCB == nullptr) {
950         TAG_LOGE(AAFwkTag::FA, "null denormalizeuriCB");
951         return WrapVoidToJS(env);
952     }
953     denormalizeuriCB->cbBase.cbInfo.env = env;
954     denormalizeuriCB->cbBase.asyncWork = nullptr;
955     denormalizeuriCB->cbBase.deferred = nullptr;
956     denormalizeuriCB->cbBase.ability = nullptr;
957 
958     napi_value ret = DenormalizeUriWrap(env, info, denormalizeuriCB);
959     if (ret == nullptr) {
960         TAG_LOGE(AAFwkTag::FA, "null ret");
961         delete denormalizeuriCB;
962         denormalizeuriCB = nullptr;
963         ret = WrapVoidToJS(env);
964     }
965 
966     return ret;
967 }
968 
DenormalizeUriWrap(napi_env env,napi_callback_info info,DAHelperDenormalizeUriCB * denormalizeuriCB)969 napi_value DenormalizeUriWrap(napi_env env, napi_callback_info info, DAHelperDenormalizeUriCB *denormalizeuriCB)
970 {
971     TAG_LOGI(AAFwkTag::FA, "called");
972     size_t argcAsync = ARGS_TWO;
973     const size_t argcPromise = ARGS_ONE;
974     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
975     napi_value args[ARGS_MAX_COUNT] = {nullptr};
976     napi_value ret = nullptr;
977     napi_value thisVar = nullptr;
978 
979     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
980     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
981         TAG_LOGE(AAFwkTag::FA, "invalid argc");
982         return nullptr;
983     }
984 
985     napi_valuetype valuetype = napi_undefined;
986     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
987     if (valuetype == napi_string) {
988         denormalizeuriCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
989         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", denormalizeuriCB->uri.c_str());
990     }
991     GetDataAbilityHelper(env, thisVar, denormalizeuriCB->dataAbilityHelper);
992 
993     if (argcAsync > argcPromise) {
994         ret = DenormalizeUriAsync(env, args, ARGS_ONE, denormalizeuriCB);
995     } else {
996         ret = DenormalizeUriPromise(env, denormalizeuriCB);
997     }
998 
999     return ret;
1000 }
1001 
UnwrapDataAbilityPredicates(NativeRdb::DataAbilityPredicates & predicates,napi_env env,napi_value value)1002 void UnwrapDataAbilityPredicates(NativeRdb::DataAbilityPredicates &predicates, napi_env env, napi_value value)
1003 {
1004     auto tempPredicates = DataAbilityJsKit::DataAbilityPredicatesProxy::GetNativePredicates(env, value);
1005     if (tempPredicates == nullptr) {
1006         TAG_LOGE(AAFwkTag::FA, "null tempPredicates");
1007         return;
1008     }
1009     predicates = *tempPredicates;
1010 }
1011 
1012 /**
1013  * @brief DataAbilityHelper NAPI method : insert.
1014  *
1015  * @param env The environment that the Node-API call is invoked under.
1016  * @param info The callback info passed into the callback function.
1017  *
1018  * @return The return value from NAPI C++ to JS for the module.
1019  */
NAPI_Delete(napi_env env,napi_callback_info info)1020 napi_value NAPI_Delete(napi_env env, napi_callback_info info)
1021 {
1022     TAG_LOGI(AAFwkTag::FA, "called");
1023     DAHelperDeleteCB *deleteCB = new DAHelperDeleteCB;
1024     deleteCB->cbBase.cbInfo.env = env;
1025     deleteCB->cbBase.asyncWork = nullptr;
1026     deleteCB->cbBase.deferred = nullptr;
1027     deleteCB->cbBase.ability = nullptr;
1028 
1029     napi_value ret = DeleteWrap(env, info, deleteCB);
1030     if (ret == nullptr) {
1031         TAG_LOGE(AAFwkTag::FA, "null ret");
1032         delete deleteCB;
1033         deleteCB = nullptr;
1034         ret = WrapVoidToJS(env);
1035     }
1036 
1037     return ret;
1038 }
1039 
1040 /**
1041  * @brief Insert processing function.
1042  *
1043  * @param env The environment that the Node-API call is invoked under.
1044  * @param insertCB Process data asynchronously.
1045  *
1046  * @return Return JS data successfully, otherwise return nullptr.
1047  */
DeleteWrap(napi_env env,napi_callback_info info,DAHelperDeleteCB * deleteCB)1048 napi_value DeleteWrap(napi_env env, napi_callback_info info, DAHelperDeleteCB *deleteCB)
1049 {
1050     TAG_LOGI(AAFwkTag::FA, "called");
1051     size_t argcAsync = ARGS_THREE;
1052     const size_t argcPromise = ARGS_TWO;
1053     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1054     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1055     napi_value ret = nullptr;
1056     napi_value thisVar = nullptr;
1057 
1058     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1059     if (argcAsync > argCountWithAsync) {
1060         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1061         return nullptr;
1062     }
1063 
1064     napi_valuetype valuetype = napi_undefined;
1065     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1066     if (valuetype == napi_string) {
1067         deleteCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1068         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", deleteCB->uri.c_str());
1069     }
1070 
1071     UnwrapDataAbilityPredicates(deleteCB->predicates, env, args[PARAM1]);
1072     GetDataAbilityHelper(env, thisVar, deleteCB->dataAbilityHelper);
1073 
1074     if (argcAsync > argcPromise) {
1075         ret = DeleteAsync(env, args, ARGS_TWO, deleteCB);
1076     } else {
1077         ret = DeletePromise(env, deleteCB);
1078     }
1079 
1080     return ret;
1081 }
1082 
1083 /**
1084  * @brief DataAbilityHelper NAPI method : insert.
1085  *
1086  * @param env The environment that the Node-API call is invoked under.
1087  * @param info The callback info passed into the callback function.
1088  *
1089  * @return The return value from NAPI C++ to JS for the module.
1090  */
NAPI_Update(napi_env env,napi_callback_info info)1091 napi_value NAPI_Update(napi_env env, napi_callback_info info)
1092 {
1093     TAG_LOGI(AAFwkTag::FA, "called");
1094     DAHelperUpdateCB *updateCB = new DAHelperUpdateCB;
1095     updateCB->cbBase.cbInfo.env = env;
1096     updateCB->cbBase.asyncWork = nullptr;
1097     updateCB->cbBase.deferred = nullptr;
1098     updateCB->cbBase.ability = nullptr;
1099 
1100     napi_value ret = UpdateWrap(env, info, updateCB);
1101     if (ret == nullptr) {
1102         TAG_LOGE(AAFwkTag::FA, "null ret");
1103         delete updateCB;
1104         updateCB = nullptr;
1105         ret = WrapVoidToJS(env);
1106     }
1107 
1108     return ret;
1109 }
1110 
1111 /**
1112  * @brief Insert processing function.
1113  *
1114  * @param env The environment that the Node-API call is invoked under.
1115  * @param insertCB Process data asynchronously.
1116  *
1117  * @return Return JS data successfully, otherwise return nullptr.
1118  */
UpdateWrap(napi_env env,napi_callback_info info,DAHelperUpdateCB * updateCB)1119 napi_value UpdateWrap(napi_env env, napi_callback_info info, DAHelperUpdateCB *updateCB)
1120 {
1121     TAG_LOGI(AAFwkTag::FA, "called");
1122     size_t argcAsync = ARGS_FOUR;
1123     const size_t argcPromise = ARGS_THREE;
1124     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1125     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1126     napi_value ret = nullptr;
1127     napi_value thisVar = nullptr;
1128 
1129     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1130     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1131         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1132         return nullptr;
1133     }
1134 
1135     napi_valuetype valuetype = napi_undefined;
1136     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1137     if (valuetype == napi_string) {
1138         updateCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1139         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", updateCB->uri.c_str());
1140     }
1141 
1142     updateCB->valueBucket.Clear();
1143     AnalysisValuesBucket(updateCB->valueBucket, env, args[PARAM1]);
1144     UnwrapDataAbilityPredicates(updateCB->predicates, env, args[PARAM2]);
1145     GetDataAbilityHelper(env, thisVar, updateCB->dataAbilityHelper);
1146 
1147     if (argcAsync > argcPromise) {
1148         ret = UpdateAsync(env, args, ARGS_THREE, updateCB);
1149     } else {
1150         ret = UpdatePromise(env, updateCB);
1151     }
1152 
1153     return ret;
1154 }
SetPacMapObject(AppExecFwk::PacMap & pacMap,const napi_env & env,std::string keyStr,napi_value value)1155 void SetPacMapObject(AppExecFwk::PacMap &pacMap, const napi_env &env, std::string keyStr, napi_value value)
1156 {
1157     napi_valuetype valueType = napi_undefined;
1158     napi_typeof(env, value, &valueType);
1159     if (valueType == napi_string) {
1160         std::string valueString = UnwrapStringFromJS(env, value);
1161         pacMap.PutStringValue(keyStr, valueString);
1162     } else if (valueType == napi_number) {
1163         double valueNumber = 0;
1164         napi_get_value_double(env, value, &valueNumber);
1165         pacMap.PutDoubleValue(keyStr, valueNumber);
1166     } else if (valueType == napi_boolean) {
1167         bool valueBool = false;
1168         napi_get_value_bool(env, value, &valueBool);
1169         pacMap.PutBooleanValue(keyStr, valueBool);
1170     } else if (valueType == napi_null) {
1171         pacMap.PutObject(keyStr, nullptr);
1172     } else if (valueType == napi_object) {
1173         pacMap.PutStringValueArray(keyStr, ConvertStringVector(env, value));
1174     } else {
1175         TAG_LOGE(AAFwkTag::FA, "pacMap type error");
1176     }
1177 }
1178 
AnalysisPacMap(AppExecFwk::PacMap & pacMap,const napi_env & env,const napi_value & arg)1179 void AnalysisPacMap(AppExecFwk::PacMap &pacMap, const napi_env &env, const napi_value &arg)
1180 {
1181     napi_value keys = nullptr;
1182     napi_get_property_names(env, arg, &keys);
1183     uint32_t arrLen = 0;
1184     napi_status status = napi_get_array_length(env, keys, &arrLen);
1185     if (status != napi_ok) {
1186         TAG_LOGE(AAFwkTag::FA, "status err");
1187         return;
1188     }
1189     for (size_t i = 0; i < arrLen; ++i) {
1190         napi_value key = nullptr;
1191         (void)napi_get_element(env, keys, i, &key);
1192         std::string keyStr = UnwrapStringFromJS(env, key);
1193         napi_value value = nullptr;
1194         napi_get_property(env, arg, key, &value);
1195         SetPacMapObject(pacMap, env, keyStr, value);
1196     }
1197 }
1198 
1199 /**
1200  * @brief Call processing function.
1201  *
1202  * @param env The environment that the Node-API call is invoked under.
1203  * @param callCB Process data asynchronously.
1204  *
1205  * @return Return JS data successfully, otherwise return nullptr.
1206  */
CallWrap(napi_env env,napi_callback_info info,DAHelperCallCB * callCB)1207 napi_value CallWrap(napi_env env, napi_callback_info info, DAHelperCallCB *callCB)
1208 {
1209     TAG_LOGI(AAFwkTag::FA, "called");
1210     size_t argcAsync = ARGS_FIVE;
1211     const size_t argcPromise = ARGS_FOUR;
1212     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1213     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1214     napi_value ret = nullptr;
1215     napi_value thisVar = nullptr;
1216     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1217     if (argcAsync != ARGS_FOUR && argcAsync != ARGS_FIVE) {
1218         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1219         return nullptr;
1220     }
1221     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1222         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1223         return nullptr;
1224     }
1225     bool isPromise = (argcAsync <= argcPromise) ? true : false;
1226     napi_valuetype valuetype = napi_undefined;
1227     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1228     if (valuetype == napi_string) {
1229         callCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1230     } else {
1231         return CallErrorWrap(env, thisVar, info, args, isPromise);
1232     }
1233     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
1234     if (valuetype == napi_string) {
1235         callCB->method = NapiValueToStringUtf8(env, args[PARAM1]);
1236     } else {
1237         return CallErrorWrap(env, thisVar, info, args, isPromise);
1238     }
1239     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valuetype));
1240     if (valuetype == napi_string) {
1241         callCB->arg = NapiValueToStringUtf8(env, args[PARAM2]);
1242     }
1243     NAPI_CALL(env, napi_typeof(env, args[PARAM3], &valuetype));
1244     if (valuetype == napi_object) {
1245         AnalysisPacMap(callCB->pacMap, env, args[PARAM3]);
1246     }
1247     GetDataAbilityHelper(env, thisVar, callCB->dataAbilityHelper);
1248     if (!isPromise) {
1249         ret = CallAsync(env, args, ARGS_TWO, callCB);
1250     } else {
1251         ret = CallPromise(env, callCB);
1252     }
1253     return ret;
1254 }
1255 
1256 /**
1257  * @brief DataAbilityHelper NAPI method : call.
1258  *
1259  * @param env The environment that the Node-API call is invoked under.
1260  * @param info The callback info passed into the callback function.
1261  *
1262  * @return The return value from NAPI C++ to JS for the module.
1263  */
NAPI_Call(napi_env env,napi_callback_info info)1264 napi_value NAPI_Call(napi_env env, napi_callback_info info)
1265 {
1266     TAG_LOGI(AAFwkTag::FA, "called");
1267     DAHelperCallCB *callCB = new (std::nothrow) DAHelperCallCB;
1268     if (callCB == nullptr) {
1269         TAG_LOGE(AAFwkTag::FA, "null callCB");
1270         return WrapVoidToJS(env);
1271     }
1272     callCB->cbBase.cbInfo.env = env;
1273     callCB->cbBase.asyncWork = nullptr;
1274     callCB->cbBase.deferred = nullptr;
1275     callCB->cbBase.ability = nullptr;
1276 
1277     napi_value ret = CallWrap(env, info, callCB);
1278     if (ret == nullptr) {
1279         TAG_LOGE(AAFwkTag::FA, "null ret");
1280         delete callCB;
1281         callCB = nullptr;
1282         ret = WrapVoidToJS(env);
1283     }
1284 
1285     return ret;
1286 }
1287 
1288 /**
1289  * @brief DataAbilityHelper NAPI method : insert.
1290  *
1291  * @param env The environment that the Node-API call is invoked under.
1292  * @param info The callback info passed into the callback function.
1293  *
1294  * @return The return value from NAPI C++ to JS for the module.
1295  */
NAPI_OpenFile(napi_env env,napi_callback_info info)1296 napi_value NAPI_OpenFile(napi_env env, napi_callback_info info)
1297 {
1298     TAG_LOGI(AAFwkTag::FA, "called");
1299     DAHelperOpenFileCB *openFileCB = new (std::nothrow) DAHelperOpenFileCB;
1300     if (openFileCB == nullptr) {
1301         TAG_LOGE(AAFwkTag::FA, "null openFileCB");
1302         return WrapVoidToJS(env);
1303     }
1304     openFileCB->cbBase.cbInfo.env = env;
1305     openFileCB->cbBase.asyncWork = nullptr;
1306     openFileCB->cbBase.deferred = nullptr;
1307     openFileCB->cbBase.ability = nullptr;
1308 
1309     napi_value ret = OpenFileWrap(env, info, openFileCB);
1310     if (ret == nullptr) {
1311         TAG_LOGE(AAFwkTag::FA, "null ret");
1312         delete openFileCB;
1313         openFileCB = nullptr;
1314         ret = WrapVoidToJS(env);
1315     }
1316 
1317     return ret;
1318 }
1319 
1320 /**
1321  * @brief Insert processing function.
1322  *
1323  * @param env The environment that the Node-API call is invoked under.
1324  * @param insertCB Process data asynchronously.
1325  *
1326  * @return Return JS data successfully, otherwise return nullptr.
1327  */
OpenFileWrap(napi_env env,napi_callback_info info,DAHelperOpenFileCB * openFileCB)1328 napi_value OpenFileWrap(napi_env env, napi_callback_info info, DAHelperOpenFileCB *openFileCB)
1329 {
1330     TAG_LOGI(AAFwkTag::FA, "called");
1331     size_t argcAsync = ARGS_THREE;
1332     const size_t argcPromise = ARGS_TWO;
1333     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1334     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1335     napi_value ret = nullptr;
1336     napi_value thisVar = nullptr;
1337 
1338     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1339     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1340         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1341         return nullptr;
1342     }
1343 
1344     napi_valuetype valuetype = napi_undefined;
1345     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1346     if (valuetype == napi_string) {
1347         openFileCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1348         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", openFileCB->uri.c_str());
1349     }
1350 
1351     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valuetype));
1352     if (valuetype == napi_string) {
1353         openFileCB->mode = NapiValueToStringUtf8(env, args[PARAM1]);
1354         TAG_LOGI(AAFwkTag::FA, "mode=%{public}s", openFileCB->mode.c_str());
1355     }
1356     GetDataAbilityHelper(env, thisVar, openFileCB->dataAbilityHelper);
1357 
1358     if (argcAsync > argcPromise) {
1359         ret = OpenFileAsync(env, args, ARGS_TWO, openFileCB);
1360     } else {
1361         ret = OpenFilePromise(env, openFileCB);
1362     }
1363 
1364     return ret;
1365 }
1366 
1367 /**
1368  * @brief DataAbilityHelper NAPI method : insert.
1369  *
1370  * @param env The environment that the Node-API call is invoked under.
1371  * @param info The callback info passed into the callback function.
1372  *
1373  * @return The return value from NAPI C++ to JS for the module.
1374  */
NAPI_BatchInsert(napi_env env,napi_callback_info info)1375 napi_value NAPI_BatchInsert(napi_env env, napi_callback_info info)
1376 {
1377     TAG_LOGI(AAFwkTag::FA, "called");
1378     DAHelperBatchInsertCB *BatchInsertCB = new (std::nothrow) DAHelperBatchInsertCB;
1379     if (BatchInsertCB == nullptr) {
1380         TAG_LOGE(AAFwkTag::FA, "null BatchInsertCB");
1381         return WrapVoidToJS(env);
1382     }
1383     BatchInsertCB->cbBase.cbInfo.env = env;
1384     BatchInsertCB->cbBase.asyncWork = nullptr;
1385     BatchInsertCB->cbBase.deferred = nullptr;
1386     BatchInsertCB->cbBase.ability = nullptr;
1387 
1388     napi_value ret = BatchInsertWrap(env, info, BatchInsertCB);
1389     if (ret == nullptr) {
1390         TAG_LOGE(AAFwkTag::FA, "null ret");
1391         delete BatchInsertCB;
1392         BatchInsertCB = nullptr;
1393         ret = WrapVoidToJS(env);
1394     }
1395 
1396     return ret;
1397 }
1398 
NapiValueObject(napi_env env,napi_value param)1399 std::vector<NativeRdb::ValuesBucket> NapiValueObject(napi_env env, napi_value param)
1400 {
1401     TAG_LOGI(AAFwkTag::FA, "called");
1402     std::vector<NativeRdb::ValuesBucket> result;
1403     UnwrapArrayObjectFromJS(env, param, result);
1404     return result;
1405 }
1406 
UnwrapArrayObjectFromJS(napi_env env,napi_value param,std::vector<NativeRdb::ValuesBucket> & value)1407 bool UnwrapArrayObjectFromJS(napi_env env, napi_value param, std::vector<NativeRdb::ValuesBucket> &value)
1408 {
1409     TAG_LOGI(AAFwkTag::FA, "called");
1410     uint32_t arraySize = 0;
1411     napi_value jsValue = nullptr;
1412     std::string strValue = "";
1413 
1414     if (!IsArrayForNapiValue(env, param, arraySize)) {
1415         TAG_LOGI(AAFwkTag::FA, "IsArrayForNapiValue:false");
1416         return false;
1417     }
1418 
1419     value.clear();
1420     for (uint32_t i = 0; i < arraySize; i++) {
1421         jsValue = nullptr;
1422         if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
1423             TAG_LOGI(AAFwkTag::FA, "get jsValue failed");
1424             return false;
1425         }
1426 
1427         NativeRdb::ValuesBucket valueBucket;
1428         valueBucket.Clear();
1429         AnalysisValuesBucket(valueBucket, env, jsValue);
1430 
1431         value.push_back(valueBucket);
1432     }
1433 
1434     return true;
1435 }
1436 
1437 /**
1438  * @brief Insert processing function.
1439  *
1440  * @param env The environment that the Node-API call is invoked under.
1441  * @param insertCB Process data asynchronously.
1442  *
1443  * @return Return JS data successfully, otherwise return nullptr.
1444  */
BatchInsertWrap(napi_env env,napi_callback_info info,DAHelperBatchInsertCB * batchInsertCB)1445 napi_value BatchInsertWrap(napi_env env, napi_callback_info info, DAHelperBatchInsertCB *batchInsertCB)
1446 {
1447     TAG_LOGI(AAFwkTag::FA, "called");
1448     size_t argcAsync = ARGS_THREE;
1449     const size_t argcPromise = ARGS_TWO;
1450     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1451     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1452     napi_value ret = nullptr;
1453     napi_value thisVar = nullptr;
1454 
1455     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1456     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1457         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1458         return nullptr;
1459     }
1460 
1461     napi_valuetype valuetype = napi_undefined;
1462     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1463     if (valuetype == napi_string) {
1464         batchInsertCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1465         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", batchInsertCB->uri.c_str());
1466     }
1467 
1468     batchInsertCB->values = NapiValueObject(env, args[PARAM1]);
1469     GetDataAbilityHelper(env, thisVar, batchInsertCB->dataAbilityHelper);
1470 
1471     if (argcAsync > argcPromise) {
1472         ret = BatchInsertAsync(env, args, ARGS_TWO, batchInsertCB);
1473     } else {
1474         ret = BatchInsertPromise(env, batchInsertCB);
1475     }
1476 
1477     return ret;
1478 }
1479 
1480 /**
1481  * @brief DataAbilityHelper NAPI method : insert.
1482  *
1483  * @param env The environment that the Node-API call is invoked under.
1484  * @param info The callback info passed into the callback function.
1485  *
1486  * @return The return value from NAPI C++ to JS for the module.
1487  */
NAPI_Query(napi_env env,napi_callback_info info)1488 napi_value NAPI_Query(napi_env env, napi_callback_info info)
1489 {
1490     TAG_LOGI(AAFwkTag::FA, "called");
1491     DAHelperQueryCB *queryCB = new DAHelperQueryCB;
1492     queryCB->cbBase.cbInfo.env = env;
1493     queryCB->cbBase.asyncWork = nullptr;
1494     queryCB->cbBase.deferred = nullptr;
1495     queryCB->cbBase.ability = nullptr;
1496 
1497     napi_value ret = QueryWrap(env, info, queryCB);
1498     if (ret == nullptr) {
1499         TAG_LOGE(AAFwkTag::FA, "null ret");
1500         delete queryCB;
1501         queryCB = nullptr;
1502         ret = WrapVoidToJS(env);
1503     }
1504 
1505     return ret;
1506 }
1507 
1508 /**
1509  * @brief Insert processing function.
1510  *
1511  * @param env The environment that the Node-API call is invoked under.
1512  * @param insertCB Process data asynchronously.
1513  *
1514  * @return Return JS data successfully, otherwise return nullptr.
1515  */
QueryWrap(napi_env env,napi_callback_info info,DAHelperQueryCB * queryCB)1516 napi_value QueryWrap(napi_env env, napi_callback_info info, DAHelperQueryCB *queryCB)
1517 {
1518     size_t argcAsync = ARGS_FOUR;
1519     const size_t argcPromise = ARGS_THREE;
1520     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1521     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1522     napi_value ret = nullptr;
1523     napi_value thisVar = nullptr;
1524 
1525     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1526     if (argcAsync > argCountWithAsync) {
1527         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1528         return nullptr;
1529     }
1530 
1531     napi_valuetype valuetype = napi_undefined;
1532     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1533     if (valuetype == napi_string) {
1534         queryCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1535         TAG_LOGD(AAFwkTag::FA, "uri=%{public}s", queryCB->uri.c_str());
1536     }
1537 
1538     std::vector<std::string> result;
1539     bool arrayStringbool = NapiValueToArrayStringUtf8(env, args[PARAM1], result);
1540     if (!arrayStringbool) {
1541         TAG_LOGE(AAFwkTag::FA, "The return value of arraystringbool is false");
1542     }
1543     queryCB->columns = result;
1544 
1545     UnwrapDataAbilityPredicates(queryCB->predicates, env, args[PARAM2]);
1546     GetDataAbilityHelper(env, thisVar, queryCB->dataAbilityHelper);
1547 
1548     if (argcAsync > argcPromise) {
1549         ret = QuerySync(env, args, ARGS_THREE, queryCB);
1550     } else {
1551         ret = QueryPromise(env, queryCB);
1552     }
1553     return ret;
1554 }
1555 
NAPI_ExecuteBatch(napi_env env,napi_callback_info info)1556 napi_value NAPI_ExecuteBatch(napi_env env, napi_callback_info info)
1557 {
1558     TAG_LOGI(AAFwkTag::FA, "start");
1559     DAHelperExecuteBatchCB *executeBatchCB = new (std::nothrow) DAHelperExecuteBatchCB;
1560     if (executeBatchCB == nullptr) {
1561         TAG_LOGE(AAFwkTag::FA, "invalid executeBatchCB");
1562         return WrapVoidToJS(env);
1563     }
1564     executeBatchCB->cbBase.cbInfo.env = env;
1565     executeBatchCB->cbBase.asyncWork = nullptr;
1566     executeBatchCB->cbBase.deferred = nullptr;
1567     executeBatchCB->cbBase.ability = nullptr;
1568 
1569     napi_value ret = ExecuteBatchWrap(env, info, executeBatchCB);
1570     if (ret == nullptr) {
1571         TAG_LOGE(AAFwkTag::FA, "null ret");
1572         delete executeBatchCB;
1573         executeBatchCB = nullptr;
1574         ret = WrapVoidToJS(env);
1575     }
1576 
1577     return ret;
1578 }
1579 
UnwrapArrayOperationFromJS(napi_env env,napi_callback_info info,napi_value param,std::vector<std::shared_ptr<DataAbilityOperation>> & result)1580 bool UnwrapArrayOperationFromJS(
1581     napi_env env, napi_callback_info info, napi_value param, std::vector<std::shared_ptr<DataAbilityOperation>> &result)
1582 {
1583     TAG_LOGI(AAFwkTag::FA, "called");
1584     uint32_t arraySize = 0;
1585     napi_value jsValue = nullptr;
1586     std::string strValue = "";
1587 
1588     if (!IsArrayForNapiValue(env, param, arraySize)) {
1589         TAG_LOGE(AAFwkTag::FA, "Wrong argument type");
1590         return false;
1591     }
1592     TAG_LOGI(AAFwkTag::FA, "param size:%{public}d", arraySize);
1593     result.clear();
1594     for (uint32_t i = 0; i < arraySize; i++) {
1595         jsValue = nullptr;
1596         if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
1597             TAG_LOGE(AAFwkTag::FA, "get index:%{public}d failed", i);
1598             return false;
1599         }
1600         std::shared_ptr<DataAbilityOperation> operation = nullptr;
1601         UnwrapDataAbilityOperation(operation, env, jsValue);
1602         TAG_LOGI(AAFwkTag::FA, "UnwrapDataAbilityOperation index:%{public}d", i);
1603         result.push_back(operation);
1604     }
1605     return true;
1606 }
1607 
ExecuteBatchWrap(napi_env env,napi_callback_info info,DAHelperExecuteBatchCB * executeBatchCB)1608 napi_value ExecuteBatchWrap(napi_env env, napi_callback_info info, DAHelperExecuteBatchCB *executeBatchCB)
1609 {
1610     TAG_LOGI(AAFwkTag::FA, "start");
1611     size_t argcAsync = ARGS_THREE;
1612     const size_t argcPromise = ARGS_TWO;
1613     const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT;
1614     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1615     napi_value ret = nullptr;
1616     napi_value thisVar = nullptr;
1617 
1618     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisVar, nullptr));
1619     if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) {
1620         TAG_LOGE(AAFwkTag::FA, "invalid argc");
1621         return nullptr;
1622     }
1623 
1624     napi_valuetype valuetype = napi_undefined;
1625     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
1626     if (valuetype == napi_string) {
1627         executeBatchCB->uri = NapiValueToStringUtf8(env, args[PARAM0]);
1628         TAG_LOGI(AAFwkTag::FA, "uri=%{public}s", executeBatchCB->uri.c_str());
1629     } else {
1630         TAG_LOGE(AAFwkTag::FA, "Wrong argument type");
1631     }
1632 
1633     std::vector<std::shared_ptr<DataAbilityOperation>> operations;
1634     UnwrapArrayOperationFromJS(env, info, args[PARAM1], operations);
1635     TAG_LOGI(AAFwkTag::FA, "operations size=%{public}zu", operations.size());
1636     executeBatchCB->operations = operations;
1637     GetDataAbilityHelper(env, thisVar, executeBatchCB->dataAbilityHelper);
1638 
1639     if (argcAsync > argcPromise) {
1640         ret = ExecuteBatchAsync(env, args, argcAsync, argcPromise, executeBatchCB);
1641     } else {
1642         ret = ExecuteBatchPromise(env, executeBatchCB);
1643     }
1644 
1645     return ret;
1646 }
1647 
1648 
EraseMemberProperties(DAHelperOnOffCB * onCB)1649 void EraseMemberProperties(DAHelperOnOffCB* onCB)
1650 {
1651     if (onCB->observer) {
1652         TAG_LOGD(AAFwkTag::FA, "call ReleaseJSCallback");
1653         onCB->observer->ReleaseJSCallback();
1654     }
1655     auto dataAbilityHelper = onCB->dataAbilityHelper;
1656     if (dataAbilityHelper != nullptr) {
1657         TAG_LOGD(AAFwkTag::FA, "call Release");
1658         dataAbilityHelper->Release();
1659     }
1660 }
1661 
NeedErase(std::vector<DAHelperOnOffCB * >::iterator & iter,const std::shared_ptr<DataAbilityHelper> && dataAbilityHelper)1662 bool NeedErase(std::vector<DAHelperOnOffCB*>::iterator& iter,
1663     const std::shared_ptr<DataAbilityHelper>&& dataAbilityHelper)
1664 {
1665     if ((*iter) == nullptr) {
1666         return false;
1667     }
1668     if ((*iter)->dataAbilityHelper == dataAbilityHelper) {
1669         EraseMemberProperties(*iter);
1670         delete (*iter);
1671         (*iter) = nullptr;
1672         iter = g_registerInstances.erase(iter);
1673     } else {
1674         ++iter;
1675     }
1676     return true;
1677 }
1678 
DeleteDAHelperOnOffCB(DAHelperOnOffCB * onCB)1679 void DeleteDAHelperOnOffCB(DAHelperOnOffCB *onCB)
1680 {
1681     if (!onCB) {
1682         TAG_LOGI(AAFwkTag::FA, "null onCB");
1683         return;
1684     }
1685     EraseMemberProperties(onCB);
1686 
1687     auto end = remove(g_registerInstances.begin(), g_registerInstances.end(), onCB);
1688     if (end != g_registerInstances.end()) {
1689         (void)g_registerInstances.erase(end);
1690     }
1691     delete onCB;
1692     onCB = nullptr;
1693 }
1694 }  // namespace AppExecFwk
1695 }  // namespace OHOS
1696