• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #include "napi_settings.h"
17 
18 #include <pthread.h>
19 #include <unistd.h>
20 
21 #include "abs_shared_result_set.h"
22 #include "data_ability_helper.h"
23 #include "data_ability_predicates.h"
24 #include "napi_settings_log.h"
25 #include "values_bucket.h"
26 
27 #include "napi_base_context.h"
28 #include "datashare_helper.h"
29 #include "datashare_predicates.h"
30 
31 
32 using namespace OHOS::AppExecFwk;
33 using namespace OHOS::DataShare;
34 
35 namespace OHOS {
36 namespace Settings {
37 const std::string SETTINGS_DATA_BASE_URI = "dataability:///com.ohos.settingsdata.DataAbility";
38 const std::string SETTINGS_DATA_FIELD_KEYWORD = "KEYWORD";
39 const std::string SETTINGS_DATA_FIELD_VALUE = "VALUE";
40 
41 /**
42  * @brief Wrap void to js value.
43  * ability_context
44  * @param env the environment that the Node-API call is invoked under
45  * @return napi_value napi_value after wrapped
46  */
wrap_void_to_js(napi_env env)47 napi_value wrap_void_to_js(napi_env env)
48 {
49     napi_value result = nullptr;
50     NAPI_CALL(env, napi_get_null(env, &result));
51     return result;
52 }
53 
54 /**
55  * @brief Unwrap string from js value.
56  *
57  * @param env the environment that the Node-API call is invoked under
58  * @param param js value to unwrap
59  * @return std::string string value after unwrapped
60  */
unwrap_string_from_js(napi_env env,napi_value param)61 std::string unwrap_string_from_js(napi_env env, napi_value param)
62 {
63     std::string defaultValue("");
64 
65     size_t size = 0;
66     if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
67         return defaultValue;
68     }
69 
70     if (size == 0) {
71         return defaultValue;
72     }
73 
74     std::string value("");
75 
76     char *buf = new (std::nothrow) char[size + 1];
77     if (buf == nullptr) {
78         SETTING_LOG_INFO("settingsnapi : unwarp");
79         return value;
80     }
81     memset_s(buf, size + 1, 0, size + 1);
82 
83     bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
84     if (rev) {
85         value = buf;
86     } else {
87         value = defaultValue;
88     }
89 
90     delete[] buf;
91     buf = nullptr;
92     SETTING_LOG_INFO("settingsnapi : unwarp string is : %{public}s", value.c_str());
93     return value;
94 }
95 
96 /**
97  * @brief Wrap string to js value.
98  *
99  * @param env the environment that the Node-API call is invoked under
100  * @param value string value to be wrap
101  * @return napi_value js value after wrapped
102  */
wrap_string_to_js(napi_env env,const std::string & value)103 napi_value wrap_string_to_js(napi_env env, const std::string &value)
104 {
105     napi_value result = nullptr;
106     NAPI_CALL(env, napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result));
107     return result;
108 }
109 
110 /**
111  * @brief Wrap bool to js value.
112  *
113  * @param env the environment that the Node-API call is invoked under
114  * @param value bool value to be wrap
115  * @return napi_value js value after wrapped
116  */
wrap_bool_to_js(napi_env env,bool value)117 napi_value wrap_bool_to_js(napi_env env, bool value)
118 {
119     napi_value result = nullptr;
120     NAPI_CALL(env, napi_get_boolean(env, value, &result));
121     return result;
122 }
123 
124 struct AsyncCallbackInfo {
125     napi_env env;
126     napi_async_work asyncWork;
127     napi_deferred deferred;
128     napi_ref callbackRef;
129     DataAbilityHelper *dataAbilityHelper;
130     std::string key;
131     std::string value;
132     std::string uri;
133     int status;
134     std::shared_ptr<DataShareHelper> dataShareHelper = nullptr;
135 };
136 
137 /**
138  * @brief getUri NAPI implementation.
139  *
140  * @param env the environment that the Node-API call is invoked under
141  * @param info the callback info passed into the callback function
142  * @return napi_value the return value from NAPI C++ to JS for the module.
143  */
napi_get_uri_sync(napi_env env,napi_callback_info info)144 napi_value napi_get_uri_sync(napi_env env, napi_callback_info info)
145 {
146     napi_value retUri = nullptr;
147 
148     // Check the number of the arguments
149     size_t argc = ARGS_ONE;
150     napi_value args[ARGS_ONE] = {nullptr};
151     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
152     if (argc != ARGS_ONE) {
153         SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
154         return wrap_void_to_js(env);
155     }
156 
157     // Check the value type of the arguments
158     napi_valuetype valueType;
159     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
160     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument type. String expected.");
161 
162     std::string uriArgStr = unwrap_string_from_js(env, args[PARAM0]);
163     uriArgStr = uriArgStr.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + uriArgStr);
164 
165     retUri = wrap_string_to_js(env, uriArgStr);
166     return retUri;
167 }
168 
napi_get_uri(napi_env env,napi_callback_info info)169 napi_value napi_get_uri(napi_env env, napi_callback_info info)
170 {
171     SETTING_LOG_INFO("settingsnapi : uri napi_set_value called...");
172     // Check the number of the arguments
173     size_t argc = ARGS_TWO;
174     napi_value args[ARGS_TWO] = {nullptr};
175     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
176     if (argc != ARGS_ONE && argc != ARGS_TWO) {
177         SETTING_LOG_ERROR("settingsnapi : uri %{public}s, wrong number of arguments, expect 1 or 2 but get %{public}zd",
178             __func__, argc);
179         return wrap_void_to_js(env);
180     }
181 
182     SETTING_LOG_INFO("settingsnapi : uri arg count is %{public}zd", argc);
183     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
184         .env = env,
185         .asyncWork = nullptr,
186         .deferred = nullptr,
187         .callbackRef = nullptr,
188         .dataAbilityHelper = nullptr,
189         .key = "",
190         .value = "",
191         .uri = "",
192         .status = false,
193     };
194 
195     // Check the value type of the arguments
196     napi_valuetype valueType;
197     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
198     NAPI_ASSERT(env, valueType == napi_string, "settingsnapi : uri Wrong argument type. String expected.");
199 
200     std::string uriArgStr = unwrap_string_from_js(env, args[PARAM0]);
201     uriArgStr = uriArgStr.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + uriArgStr);
202     asyncCallbackInfo->uri = uriArgStr;
203     SETTING_LOG_INFO("settingsnapi : uri after uri is %{public}s", asyncCallbackInfo->uri.c_str());
204 
205     napi_value resource = nullptr;
206     NAPI_CALL(env, napi_create_string_utf8(env, "getUri", NAPI_AUTO_LENGTH, &resource));
207 
208     if (argc == 2) {
209         napi_create_reference(env, args[PARAM1], 1, &asyncCallbackInfo->callbackRef);
210 
211         napi_create_async_work(
212             env,
213             nullptr,
214             resource,
215             [](napi_env env, void* data) {
216             },
217             [](napi_env env, napi_status status, void* data) {
218                 if (data == nullptr) {
219                     SETTING_LOG_INFO("settingsnapi : uri callback async end data is null");
220                     return;
221                 }
222                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
223                 napi_value undefine;
224                 napi_get_undefined(env, &undefine);
225                 napi_value callback = nullptr;
226                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->uri);
227                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
228                 napi_call_function(env, nullptr, callback, 1, &result, &undefine);
229                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
230                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
231                 delete asyncCallbackInfo;
232                 SETTING_LOG_INFO("settingsnapi : uri callback change callback complete");
233             },
234             (void*)asyncCallbackInfo,
235             &asyncCallbackInfo->asyncWork
236         );
237         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
238         return wrap_void_to_js(env);
239     } else {
240         SETTING_LOG_INFO("settingsnapi : uri do promise");
241         napi_value promise;
242         napi_deferred deferred;
243         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
244         asyncCallbackInfo->deferred = deferred;
245 
246         napi_create_async_work(
247             env,
248             nullptr,
249             resource,
250             // aysnc executed task
251             [](napi_env env, void* data) {
252             },
253             // async end called callback
254             [](napi_env env, napi_status status, void* data) {
255                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
256                 SETTING_LOG_INFO("settingsnapi : uri promise end get callback value is %{public}s",
257                     asyncCallbackInfo->uri.c_str());
258                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->uri);
259                 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
260                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
261                 delete asyncCallbackInfo;
262             },
263             (void*)asyncCallbackInfo,
264             &asyncCallbackInfo->asyncWork);
265         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
266         SETTING_LOG_INFO("settingsnapi: uri promise end sync work");
267         return promise;
268     }
269 }
270 
getDataShareHelper(napi_env env,const napi_value context,const bool stageMode)271 std::shared_ptr<DataShareHelper> getDataShareHelper(napi_env env, const napi_value context, const bool stageMode)
272 {
273     std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
274     std::shared_ptr<OHOS::DataShare::DataShareResultSet> resultset = nullptr;
275     std::string strUri = "datashare:///com.ohos.settingsdata.DataAbility";
276     std::string strProxyUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
277     OHOS::Uri proxyUri(strProxyUri);
278     auto contextS = OHOS::AbilityRuntime::GetStageModeContext(env, context);
279 
280     dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strProxyUri);
281     SETTING_LOG_INFO("getDataShareHelper called");
282 
283     DataSharePredicates predicates;
284     predicates.Limit(1, 0);
285     std::vector<std::string> columns;
286     if (dataShareHelper == nullptr) {
287         SETTING_LOG_INFO("getDataShareHelper dataShareHelper = nullptr");
288         dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strUri);
289         return dataShareHelper;
290     }
291 
292     resultset = dataShareHelper->Query(proxyUri, predicates, columns);
293     if (resultset == nullptr) {
294         dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strUri);
295         return dataShareHelper;
296     }
297     resultset->Close();
298     return dataShareHelper;
299 }
300 
GetValueExecuteExt(napi_env env,void * data)301 void GetValueExecuteExt(napi_env env, void *data)
302 {
303     if (data == nullptr) {
304         SETTING_LOG_INFO("settingsnapi : execute data is null");
305         return;
306     }
307 
308     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
309 
310     std::vector<std::string> columns;
311     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
312 
313     OHOS::DataShare::DataSharePredicates predicates;
314     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
315 
316     std::string strUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + asyncCallbackInfo->key;
317     OHOS::Uri uri(strUri);
318 
319     std::shared_ptr<OHOS::DataShare::DataShareResultSet> resultset = nullptr;
320     if (asyncCallbackInfo->dataShareHelper != nullptr) {
321         resultset = asyncCallbackInfo->dataShareHelper->Query(uri, predicates, columns);
322     }
323     int numRows = 0;
324     if (resultset != nullptr) {
325         resultset->GetRowCount(numRows);
326     }
327 
328     if (resultset == nullptr || numRows == 0) {
329         SETTING_LOG_INFO("settingsnapi : GetValueExecuteExt called... return error");
330         asyncCallbackInfo->status = -1;
331     } else {
332         std::string val;
333         int32_t columnIndex = 0;
334         resultset->GoToFirstRow();
335         resultset->GetString(columnIndex, val);
336 
337         SETTING_LOG_INFO("napi_get_value_ext called... %{public}s", val.c_str());
338         asyncCallbackInfo->value = val;
339         asyncCallbackInfo->status = napi_ok;
340     }
341 
342     if (resultset != nullptr) {
343         resultset->Close();
344     }
345 }
346 
DeleteCallbackInfo(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)347 void DeleteCallbackInfo(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
348 {
349     if (env != nullptr) {
350         napi_delete_reference(env, asyncCallbackInfo->callbackRef);
351         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
352     }
353     asyncCallbackInfo->dataShareHelper = nullptr;
354     delete asyncCallbackInfo;
355 }
356 
CompleteCall(napi_env env,napi_status status,void * data,const napi_value retVaule)357 void CompleteCall(napi_env env, napi_status status, void *data, const napi_value retVaule)
358 {
359     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
360     napi_value result[PARAM2] = {0};
361     if (status == napi_ok && asyncCallbackInfo->status == napi_ok) {
362         napi_get_undefined(env, &result[PARAM0]);
363         result[PARAM1] = retVaule;
364     } else {
365         napi_value message = nullptr;
366         napi_create_string_utf8(env, "async call failed", NAPI_AUTO_LENGTH, &message);
367         napi_create_error(env, nullptr, message, &result[PARAM0]);
368         napi_get_undefined(env, &result[PARAM1]);
369     }
370     napi_value callback = nullptr;
371     napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
372     napi_value returnValue;
373     napi_call_function(env, nullptr, callback, PARAM2, result, &returnValue);
374     DeleteCallbackInfo(env, asyncCallbackInfo);
375     SETTING_LOG_INFO("settingsnapi : callback change callback complete");
376 }
377 
CompletePromise(napi_env env,napi_status status,void * data,const napi_value retVaule)378 void CompletePromise(napi_env env, napi_status status, void *data, const napi_value retVaule)
379 {
380     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
381     napi_value result = nullptr;
382     if (status == napi_ok && asyncCallbackInfo->status == napi_ok) {
383         napi_resolve_deferred(env, asyncCallbackInfo->deferred, retVaule);
384     } else {
385         napi_get_undefined(env, &result);
386         napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
387     }
388     DeleteCallbackInfo(env, asyncCallbackInfo);
389 }
390 
SetValueExecuteExt(napi_env env,void * data,const std::string setValue)391 void SetValueExecuteExt(napi_env env, void *data, const std::string setValue)
392 {
393     if (data == nullptr) {
394         return;
395     }
396     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
397 
398     OHOS::DataShare::DataShareValuesBucket val;
399     val.Put(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
400     val.Put(SETTINGS_DATA_FIELD_VALUE, setValue);
401 
402     std::string strUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + asyncCallbackInfo->key;
403     SETTING_LOG_INFO("strUri = %{public}s", strUri.c_str());
404     OHOS::Uri uri(strUri);
405 
406     OHOS::DataShare::DataSharePredicates predicates;
407     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
408 
409     int retInt = 0;
410     if (asyncCallbackInfo->status == -1) {
411         SETTING_LOG_INFO("napi_set_value_ext called... before Insert");
412         if (asyncCallbackInfo->dataShareHelper != nullptr) {
413             retInt = asyncCallbackInfo->dataShareHelper->Insert(uri, val);
414         }
415     } else {
416         SETTING_LOG_INFO("napi_set_value_ext called... before Update");
417         if (asyncCallbackInfo->dataShareHelper != nullptr) {
418             retInt = asyncCallbackInfo->dataShareHelper->Update(uri, predicates, val);
419         }
420     }
421     asyncCallbackInfo->status = retInt;
422 }
423 
424 /**
425  * @brief getValue NAPI implementation.
426  *
427  * @param env the environment that the Node-API call is invoked under
428  * @param info the callback info passed into the callback function
429  * @return napi_value the return value from NAPI C++ to JS for the module.
430  */
napi_get_value_sync(napi_env env,napi_callback_info info)431 napi_value napi_get_value_sync(napi_env env, napi_callback_info info)
432 {
433     SETTING_LOG_INFO("napi_get_value called...");
434 
435     // Check the number of the arguments
436     size_t argc = ARGS_THREE;
437     napi_value args[ARGS_THREE] = {nullptr};
438     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
439     if (argc != ARGS_THREE) {
440         SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
441         return wrap_void_to_js(env);
442     }
443 
444     // Check the value type of the arguments
445     napi_valuetype valueType;
446     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
447     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
448     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
449     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected.");
450     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
451     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected.");
452 
453     bool stageMode = false;
454     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
455     if (status == napi_ok) {
456         AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
457         asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
458         std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
459         asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
460         GetValueExecuteExt(env, (void*)asyncCallbackInfo);
461         SETTING_LOG_INFO("settingsnapi : napi_get_value_sync called... return  %{public}s",
462             asyncCallbackInfo->value.c_str());
463         napi_value retVal = nullptr;
464         if(asyncCallbackInfo->value.size() <= 0){
465             retVal = args[PARAM2];
466         } else {
467             retVal = wrap_string_to_js(env, asyncCallbackInfo->value);
468         }
469         delete asyncCallbackInfo;
470         return retVal;
471     }
472 
473     std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
474     DataAbilityHelper *dataAbilityHelper = nullptr;
475     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&dataAbilityHelper)));
476 
477     std::vector<std::string> columns;
478     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
479     OHOS::NativeRdb::DataAbilityPredicates predicates;
480     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, unwrap_string_from_js(env, args[PARAM1]));
481 
482     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
483     if(dataAbilityHelper != nullptr ){
484       resultset = dataAbilityHelper->Query(*uri, columns, predicates);
485     };
486     SETTING_LOG_INFO("napi_get_value called... after dataAbilityHelper->Query");
487 
488     napi_value retVal = nullptr;
489     int numRows = 0;
490 
491     if (resultset != nullptr) {
492         resultset->GetRowCount(numRows);
493     }
494 
495     if (resultset == nullptr || numRows == 0) {
496         retVal = args[PARAM2];
497     } else {
498         SETTING_LOG_INFO("napi_get_value called... return value from resultset");
499         std::string val;
500         int32_t columnIndex = 0;
501         resultset->GoToFirstRow();
502         resultset->GetString(columnIndex, val);
503         retVal = wrap_string_to_js(env, val);
504     }
505 
506     if (resultset != nullptr) {
507         resultset->Close();
508     }
509     dataAbilityHelper = nullptr;
510     SETTING_LOG_INFO("napi_get_value called... END!");
511     return retVal;
512 }
513 
napi_get_value(napi_env env,napi_callback_info info)514 napi_value napi_get_value(napi_env env, napi_callback_info info)
515 {
516     // getValue api need 3 parameters when Promise mode and need 4 parameters when callback mode
517     const size_t paramOfPromise = ARGS_TWO;
518     const size_t paramOfCallback = ARGS_THREE;
519 
520     size_t argc = ARGS_THREE;
521     napi_value args[ARGS_THREE] = {nullptr};
522     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
523     if (argc != paramOfCallback && argc != paramOfPromise) {
524         SETTING_LOG_ERROR("settingsnapi : %{public}s, wrong number of arguments, expect 2 or 3 but get %{public}zd",
525             __func__, argc);
526         return wrap_void_to_js(env);
527     }
528 
529     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
530         .env = env,
531         .asyncWork = nullptr,
532         .deferred = nullptr,
533         .callbackRef = nullptr,
534         .dataAbilityHelper = nullptr,
535         .key = "",
536         .value = "",
537         .uri = "",
538         .status = false,
539     };
540     SETTING_LOG_INFO("settingsnapi : after create aysnc call back info");
541     // Check the value type of the arguments
542     napi_valuetype valueType;
543     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
544 
545     bool stageMode = false;
546     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
547     if (status == napi_ok) {
548         SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
549         return napi_get_value_ext(env, info, stageMode);
550     }
551 
552     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
553     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
554     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1], type. String expected");
555 
556     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&asyncCallbackInfo->dataAbilityHelper)));
557 
558     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
559 
560     napi_value resource = nullptr;
561     NAPI_CALL(env, napi_create_string_utf8(env, "getValue", NAPI_AUTO_LENGTH, &resource));
562 
563     if (argc == paramOfCallback) {
564         SETTING_LOG_INFO("settingsnapi : do callback");
565 
566         napi_create_reference(env, args[PARAM2], 1, &asyncCallbackInfo->callbackRef);
567 
568         napi_create_async_work(
569             env,
570             nullptr,
571             resource,
572             // aysnc executed task
573             [](napi_env env, void* data) {
574                 if (data == nullptr) {
575                     return;
576                 }
577                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
578 
579                 std::vector<std::string> columns;
580                 columns.push_back(SETTINGS_DATA_FIELD_VALUE);
581                 OHOS::NativeRdb::DataAbilityPredicates predicates;
582                 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
583 
584                 std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
585                 SETTING_LOG_INFO("settingsnapi : callback napi_get_value called... before dataAbilityHelper->Query");
586                 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
587                 if(asyncCallbackInfo->dataAbilityHelper != nullptr){
588                     resultset = asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
589                 };
590 
591                 int numRows = 0;
592                 if (resultset != nullptr) {
593                     resultset->GetRowCount(numRows);
594                 }
595                 if (resultset == nullptr || numRows == 0) {
596                 } else {
597                     SETTING_LOG_INFO("settingsnapi : callback napi_get_value called... return value from resultset");
598                     std::string val;
599                     int32_t columnIndex = 0;
600                     resultset->GoToFirstRow();
601                     resultset->GetString(columnIndex, val);
602                     SETTING_LOG_INFO("settingsnapi : callback retVal is %{public}s", val.c_str());
603                     asyncCallbackInfo->value = val;
604                 }
605                 if (resultset != nullptr) {
606                     resultset->Close();
607                 }
608             },
609             // async end called callback
610             [](napi_env env, napi_status status, void* data) {
611                 if (data == nullptr) {
612                     SETTING_LOG_INFO("settingsnapi : callback async end data is null");
613                     return;
614                 }
615                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
616                 napi_value undefine;
617                 napi_get_undefined(env, &undefine);
618                 napi_value callback = nullptr;
619                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
620                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
621                 napi_call_function(env, nullptr, callback, 1, &result, &undefine);
622                 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
623                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
624                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
625                 asyncCallbackInfo->dataAbilityHelper = nullptr;
626                 delete asyncCallbackInfo;
627             },
628             (void*)asyncCallbackInfo,
629             &asyncCallbackInfo->asyncWork
630         );
631 
632         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
633         return wrap_void_to_js(env);
634     } else {
635         SETTING_LOG_INFO("settingsnapi : do promise");
636         napi_value promise;
637         napi_deferred deferred;
638         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
639         asyncCallbackInfo->deferred = deferred;
640 
641         napi_create_async_work(
642         env,
643         nullptr,
644         resource,
645         // aysnc executed task
646         [](napi_env env, void* data) {
647             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
648             SETTING_LOG_INFO("settingsnapi : promise get callback key is %{public}s", asyncCallbackInfo->key.c_str());
649             std::vector<std::string> columns;
650             columns.push_back(SETTINGS_DATA_FIELD_VALUE);
651             OHOS::NativeRdb::DataAbilityPredicates predicates;
652             predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
653 
654             std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
655             SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... before dataAbilityHelper->Query");
656             std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
657             if(asyncCallbackInfo->dataAbilityHelper != nullptr){
658                 resultset = asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
659             }
660 
661             int numRows = 0;
662             if (resultset != nullptr) {
663                 SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... resultset is NOT empty");
664                 resultset->GetRowCount(numRows);
665             }
666             if (resultset == nullptr || numRows == 0) {
667                 SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... return default value");
668             } else {
669                 std::string val;
670                 int32_t columnIndex = 0;
671                 resultset->GoToFirstRow();
672                 resultset->GetString(columnIndex, val);
673                 asyncCallbackInfo->value = val;
674             }
675             if (resultset != nullptr) {
676                 resultset->Close();
677             }
678         },
679         // async end called callback
680         [](napi_env env, napi_status status, void* data) {
681             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
682             SETTING_LOG_INFO("settingsnapi : promise end get callback value is %{public}s",
683                 asyncCallbackInfo->value.c_str());
684             napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
685             napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
686             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
687             asyncCallbackInfo->dataAbilityHelper = nullptr;
688             delete asyncCallbackInfo;
689         },
690         (void*)asyncCallbackInfo,
691         &asyncCallbackInfo->asyncWork);
692         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
693         return promise;
694     }
695 }
696 
697 // api9
napi_get_value_ext(napi_env env,napi_callback_info info,const bool stageMode)698 napi_value napi_get_value_ext(napi_env env, napi_callback_info info, const bool stageMode)
699 {
700     SETTING_LOG_INFO("settingsnapi : napi_get_value_ext start");
701     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
702         .env = env,
703         .asyncWork = nullptr,
704         .deferred = nullptr,
705         .callbackRef = nullptr,
706         .dataAbilityHelper = nullptr,
707         .key = "",
708         .value = "",
709         .uri = "",
710         .status = false,
711     };
712 
713     size_t argc = ARGS_THREE;
714     napi_value args[ARGS_THREE] = {nullptr};
715     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
716     std::string strUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
717     OHOS::Uri uri(strUri);
718 
719     std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
720     asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
721 
722     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
723 
724     napi_value resource = nullptr;
725     NAPI_CALL(env, napi_create_string_utf8(env, "getValue", NAPI_AUTO_LENGTH, &resource));
726 
727     if (argc == ARGS_THREE) {
728         napi_create_reference(env, args[PARAM2], 1, &asyncCallbackInfo->callbackRef);
729         napi_create_async_work(
730             env,
731             nullptr,
732             resource,
733             GetValueExecuteExt,
734             [](napi_env env, napi_status status, void* data) {
735                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
736                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
737                 CompleteCall(env, status, data, result);
738             },
739             (void*)asyncCallbackInfo,
740             &asyncCallbackInfo->asyncWork
741         );
742         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
743         SETTING_LOG_INFO("settingsnapi : callback end async work");
744         return wrap_void_to_js(env);
745     } else {
746         napi_value promise;
747         napi_deferred deferred;
748         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
749         asyncCallbackInfo->deferred = deferred;
750         napi_create_async_work(
751             env,
752             nullptr,
753             resource,
754             GetValueExecuteExt,
755             [](napi_env env, napi_status status, void* data) {
756                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
757                 napi_value result = nullptr;
758                 result = wrap_string_to_js(env, asyncCallbackInfo->value);
759                 CompletePromise(env, status, data, result);
760             },
761             (void*)asyncCallbackInfo,
762             &asyncCallbackInfo->asyncWork
763         );
764         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
765         return promise;
766     }
767 }
768 
769 
770 /**
771  * @brief setValue NAPI implementation.
772  *
773  * @param env the environment that the Node-API call is invoked under
774  * @param info the callback info passed into the callback function
775  * @return napi_value the return value from NAPI C++ to JS for the module.
776  */
napi_set_value_sync(napi_env env,napi_callback_info info)777 napi_value napi_set_value_sync(napi_env env, napi_callback_info info)
778 {
779     SETTING_LOG_INFO("napi_set_value called...");
780 
781     // Check the number of the arguments
782     size_t argc = ARGS_THREE;
783     napi_value args[ARGS_THREE] = {nullptr};
784     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
785     if (argc != ARGS_THREE) {
786         SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
787         return wrap_void_to_js(env);
788     }
789 
790     // Check the value type of the arguments
791     napi_valuetype valueType;
792     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
793     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
794     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
795     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected.");
796     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
797     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected.");
798 
799     bool stageMode = false;
800     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
801     if (status == napi_ok) {
802         SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
803         AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
804         asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
805         std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
806         asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
807         GetValueExecuteExt(env, (void*)asyncCallbackInfo);
808         SetValueExecuteExt(env, (void*)asyncCallbackInfo, unwrap_string_from_js(env, args[PARAM2]));
809         napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
810         delete asyncCallbackInfo;
811         return result;
812     }
813 
814     DataAbilityHelper *dataAbilityHelper = nullptr;
815     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&dataAbilityHelper)));
816 
817     std::string argsName = unwrap_string_from_js(env, args[PARAM1]);
818     std::string argsDefaultValue = unwrap_string_from_js(env, args[PARAM2]);
819 
820     OHOS::NativeRdb::ValuesBucket val;
821     val.PutString(SETTINGS_DATA_FIELD_KEYWORD, argsName);
822     val.PutString(SETTINGS_DATA_FIELD_VALUE, argsDefaultValue);
823 
824     std::vector<std::string> columns;
825     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
826     OHOS::NativeRdb::DataAbilityPredicates predicates;
827     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, argsName);
828 
829     std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
830     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
831     if(dataAbilityHelper != nullptr){
832         resultset = dataAbilityHelper->Query(*uri, columns, predicates);
833     }
834 
835     int retInt = 0;
836     int numRows = 0;
837 
838     if (resultset != nullptr) {
839         resultset->GetRowCount(numRows);
840     }
841 
842     // insert
843     if (resultset == nullptr || numRows == 0) {
844         retInt = dataAbilityHelper->Insert(*uri, val);
845         SETTING_LOG_INFO("napi_set_value called... after Insert");
846     // update
847     } else {
848         retInt = dataAbilityHelper->Update(*uri, val, predicates);
849         SETTING_LOG_INFO("napi_set_value called... after Update");
850     }
851     // notify change
852     if (retInt != 0) {
853         std::string uriWithNameStr =
854             argsName.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + argsName);
855         std::shared_ptr<Uri> uriWithName = std::make_shared<Uri>(uriWithNameStr);
856         dataAbilityHelper->NotifyChange(*uriWithName);
857         SETTING_LOG_INFO("napi_set_value called... after NotifyChange with uri: %{public}s", uriWithNameStr.c_str());
858     }
859 
860     if (resultset != nullptr) {
861         resultset->Close();
862     }
863 
864     return wrap_bool_to_js(env, retInt != 0);
865 }
866 
SetValueExecuteCB(napi_env env,void * data)867 void SetValueExecuteCB(napi_env env, void *data)
868 {
869     if (data == nullptr) {
870         SETTING_LOG_INFO("settingsnapi : execute data is null");
871         return;
872     }
873     SETTING_LOG_INFO("settingsnapi : execute start");
874     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
875 
876     std::string argsName = asyncCallbackInfo->key;
877     std::string argsDefaultValue = asyncCallbackInfo->value;
878 
879     OHOS::NativeRdb::ValuesBucket val;
880     val.PutString(SETTINGS_DATA_FIELD_KEYWORD, argsName);
881     val.PutString(SETTINGS_DATA_FIELD_VALUE, argsDefaultValue);
882 
883     std::vector<std::string> columns;
884     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
885     OHOS::NativeRdb::DataAbilityPredicates predicates;
886     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, argsName);
887 
888     std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
889     SETTING_LOG_INFO("settingsnapi : execute... before dataAbilityHelper->Query");
890     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
891     if(asyncCallbackInfo->dataAbilityHelper != nullptr){
892         resultset = asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
893     }
894 
895     int retInt = 0;
896     int numRows = 0;
897     if (resultset != nullptr) {
898         resultset->GetRowCount(numRows);
899     }
900     // insert
901     if (resultset == nullptr || numRows == 0) {
902         retInt = asyncCallbackInfo->dataAbilityHelper->Insert(*uri, val);
903         SETTING_LOG_INFO("settingsnapi : execute... after Insert");
904     // update
905     } else {
906         retInt = asyncCallbackInfo->dataAbilityHelper->Update(*uri, val, predicates);
907         SETTING_LOG_INFO("settingsnapi : execute... after Update");
908     }
909     // notify change
910     if (retInt != 0) {
911         std::string uriWithNameStr =
912             argsName.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + argsName);
913         std::shared_ptr<Uri> uriWithName = std::make_shared<Uri>(uriWithNameStr);
914         asyncCallbackInfo->dataAbilityHelper->NotifyChange(*uriWithName);
915         SETTING_LOG_INFO(
916             "settingsnapi : execute... after NotifyChange with uri: %{public}s",
917             uriWithNameStr.c_str());
918     }
919     if (resultset != nullptr) {
920         resultset->Close();
921     }
922     asyncCallbackInfo->status = retInt;
923 }
924 
SetValueAsync(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)925 napi_value SetValueAsync(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
926 {
927     SETTING_LOG_INFO("settingsnapi : set do callback");
928     napi_value resource = nullptr;
929     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resource));
930 
931     napi_create_async_work(
932         env,
933         nullptr,
934         resource,
935         SetValueExecuteCB,
936         [](napi_env env, napi_status status, void* data) {
937             if (data == nullptr) {
938                 SETTING_LOG_INFO("settingsnapi : callback set async end data is null");
939                 return;
940             }
941             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
942             napi_value undefine;
943             napi_get_undefined(env, &undefine);
944             napi_value callback = nullptr;
945             napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
946             napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
947             napi_call_function(env, nullptr, callback, 1, &result, &undefine);
948             napi_delete_reference(env, asyncCallbackInfo->callbackRef);
949             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
950             asyncCallbackInfo->dataAbilityHelper = nullptr;
951             delete asyncCallbackInfo;
952             SETTING_LOG_INFO("settingsnapi : callback set change callback complete");
953         },
954         (void*)asyncCallbackInfo,
955         &asyncCallbackInfo->asyncWork
956     );
957     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
958     return wrap_void_to_js(env);
959 }
960 
SetValuePromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)961 napi_value SetValuePromise(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
962 {
963     SETTING_LOG_INFO("settingsnapi : set  do promise");
964     napi_value promise;
965     napi_deferred deferred;
966     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
967     asyncCallbackInfo->deferred = deferred;
968 
969     napi_value resource = nullptr;
970     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resource));
971 
972     napi_create_async_work(
973         env,
974         nullptr,
975         resource,
976         SetValueExecuteCB,
977         [](napi_env env, napi_status status, void* data) {
978             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
979             SETTING_LOG_INFO("settingsnapi : promise set end get callback value is %{public}d",
980                 asyncCallbackInfo->status);
981             napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
982             napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
983             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
984             asyncCallbackInfo->dataAbilityHelper = nullptr;
985             delete asyncCallbackInfo;
986         },
987         (void*)asyncCallbackInfo,
988         &asyncCallbackInfo->asyncWork);
989     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
990     return promise;
991 }
992 
993 /**
994  * @brief setValue NAPI implementation.
995  *
996  * @param env the environment that the Node-API call is invoked under
997  * @param info the callback info passed into the callback function
998  * @return napi_value the return value from NAPI C++ to JS for the module.
999  */
napi_set_value(napi_env env,napi_callback_info info)1000 napi_value napi_set_value(napi_env env, napi_callback_info info)
1001 {
1002     SETTING_LOG_INFO("settingsnapi : set  napi_set_value called...");
1003 
1004     // getValue api need 3 parameters when Promise mode and need 4 parameters when callback mode
1005     const size_t paramOfPromise = ARGS_THREE;
1006     const size_t paramOfCallback = ARGS_FOUR;
1007 
1008     size_t argc = ARGS_FOUR;
1009     napi_value args[ARGS_FOUR] = {nullptr};
1010     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1011     if (argc != paramOfPromise && argc != paramOfCallback) {
1012         SETTING_LOG_ERROR("settingsnapi : set %{public}s, wrong number of arguments, expect 3 or 4 but get %{public}zd",
1013             __func__, argc);
1014         return wrap_void_to_js(env);
1015     }
1016 
1017     SETTING_LOG_INFO("settingsnapi : set  arg count is %{public}zd", argc);
1018     // Check the value type of the arguments
1019     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1020         .env = env,
1021         .asyncWork = nullptr,
1022         .deferred = nullptr,
1023         .callbackRef = nullptr,
1024         .dataAbilityHelper = nullptr,
1025         .key = "",
1026         .value = "",
1027         .uri = "",
1028         .status = false,
1029     };
1030     napi_valuetype valueType;
1031     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
1032 
1033     // api9 napi_set_value_ext
1034     bool stageMode = false;
1035     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
1036     if (status == napi_ok) {
1037         SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
1038         return napi_set_value_ext(env, info, stageMode);
1039     }
1040 
1041     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
1042     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
1043     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1], type. String expected");
1044     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
1045     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2], type. String expected");
1046 
1047     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&asyncCallbackInfo->dataAbilityHelper)));
1048     SETTING_LOG_INFO("settingsnapi : input paramter is (DataAbilityHelper)");
1049 
1050     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1051     asyncCallbackInfo->value = unwrap_string_from_js(env, args[PARAM2]);
1052     SETTING_LOG_INFO("settingsnapi : set  input parameter is : (key %{public}s, value %{public}s)",
1053         asyncCallbackInfo->key.c_str(), asyncCallbackInfo->value.c_str());
1054 
1055     napi_value ret = nullptr;
1056     if (argc == paramOfCallback) {
1057         napi_create_reference(env, args[PARAM3], 1, &asyncCallbackInfo->callbackRef);
1058         ret = SetValueAsync(env, asyncCallbackInfo);
1059     } else {
1060         ret = SetValuePromise(env, asyncCallbackInfo);
1061     }
1062     SETTING_LOG_INFO("settingsnapi : set  value end");
1063     return ret;
1064 }
1065 
napi_set_value_ext(napi_env env,napi_callback_info info,const bool stageMode)1066 napi_value napi_set_value_ext(napi_env env, napi_callback_info info, const bool stageMode)
1067 {
1068     const size_t paramOfCallback = ARGS_FOUR;
1069 
1070     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1071         .env = env,
1072         .asyncWork = nullptr,
1073         .deferred = nullptr,
1074         .callbackRef = nullptr,
1075         .dataAbilityHelper = nullptr,
1076         .key = "",
1077         .value = "",
1078         .uri = "",
1079         .status = false,
1080     };
1081 
1082     size_t argc = ARGS_FOUR;
1083     napi_value args[ARGS_FOUR] = {nullptr};
1084     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1085 
1086     asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
1087     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1088     asyncCallbackInfo->uri = unwrap_string_from_js(env, args[PARAM2]); //temp
1089     napi_value resource = nullptr;
1090     NAPI_CALL(env, napi_create_string_utf8(env, "napi_set_value_ext", NAPI_AUTO_LENGTH, &resource));
1091 
1092     if (argc == paramOfCallback) {
1093         napi_create_reference(env, args[PARAM3], 1, &asyncCallbackInfo->callbackRef);
1094         napi_create_async_work(
1095             env,
1096             nullptr,
1097             resource,
1098             [](napi_env env, void* data) {
1099                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1100                 GetValueExecuteExt(env, (void*)asyncCallbackInfo);
1101                 SetValueExecuteExt(env, (void*)asyncCallbackInfo, asyncCallbackInfo->uri);
1102             },
1103             [](napi_env env, napi_status status, void* data) {
1104                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1105                 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
1106                 asyncCallbackInfo->status = napi_ok;
1107                 CompleteCall(env, status, data, result);
1108             },
1109             (void*)asyncCallbackInfo,
1110             &asyncCallbackInfo->asyncWork
1111         );
1112         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1113         SETTING_LOG_INFO("settingsnapi : callback end async work");
1114         return wrap_void_to_js(env);
1115     } else {
1116         napi_value promise;
1117         napi_deferred deferred;
1118         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1119         asyncCallbackInfo->deferred = deferred;
1120         napi_create_async_work(
1121             env,
1122             nullptr,
1123             resource,
1124             [](napi_env env, void* data) {
1125                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1126                 GetValueExecuteExt(env, (void*)asyncCallbackInfo);
1127                 SetValueExecuteExt(env, (void*)asyncCallbackInfo, asyncCallbackInfo->uri);
1128             },
1129             [](napi_env env, napi_status status, void* data) {
1130                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1131                 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
1132                 asyncCallbackInfo->status = napi_ok;
1133                 CompletePromise(env, status, data, result);
1134             },
1135             (void*)asyncCallbackInfo,
1136             &asyncCallbackInfo->asyncWork
1137         );
1138         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1139         return promise;
1140     }
1141     return wrap_void_to_js(env);
1142 }
1143 /**
1144  * @brief enableAirplaneMode NAPI implementation.
1145  * @param env the environment that the Node-API call is invoked under
1146  * @param info the callback info passed into the callback function
1147  * @return napi_value the return value from NAPI C++ to JS for the module.
1148  */
napi_enable_airplane_mode(napi_env env,napi_callback_info info)1149 napi_value napi_enable_airplane_mode(napi_env env, napi_callback_info info)
1150 {
1151     const size_t paramOfPromise = ARGS_ONE;
1152     const size_t paramOfCallback = ARGS_TWO;
1153 
1154     size_t argc = ARGS_TWO;
1155     napi_value args[ARGS_TWO] = {nullptr};
1156     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1157     if (argc != paramOfCallback && argc != paramOfPromise) {
1158         SETTING_LOG_ERROR("settingsnapi : %{public}s, wrong number of arguments, expect 1 or 2 but get %{public}zd",
1159             __func__, argc);
1160         return wrap_void_to_js(env);
1161     }
1162 
1163     SETTING_LOG_INFO("settingsnapi : napi_enable_airplane_mode start create aysnc call back info");
1164     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1165         .env = env,
1166         .asyncWork = nullptr,
1167         .deferred = nullptr,
1168         .callbackRef = nullptr,
1169         .dataAbilityHelper = nullptr,
1170         .key = "",
1171         .value = "",
1172         .uri = "",
1173         .status = 0,
1174     };
1175     SETTING_LOG_INFO("settingsnapi : after create aysnc call back info");
1176 
1177     napi_valuetype valueType;
1178     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
1179     NAPI_ASSERT(env, valueType == napi_boolean, "Wrong argument[0], type. Boolean expected");
1180 
1181     napi_value resource = nullptr;
1182     NAPI_CALL(env, napi_create_string_utf8(env, "enableAirplaneMode", NAPI_AUTO_LENGTH, &resource));
1183 
1184     if (argc == paramOfCallback) {
1185         SETTING_LOG_INFO("%{public}s, asyncCallback.", __func__);
1186 
1187         napi_create_reference(env, args[PARAM1], 1, &asyncCallbackInfo->callbackRef);
1188         napi_create_async_work(
1189             env,
1190             nullptr,
1191             resource,
1192             [](napi_env env, void* data) {},
1193             [](napi_env env, napi_status status, void* data) {
1194                 if (data == nullptr) {
1195                     SETTING_LOG_INFO("settingsnapi : callback async end data is null");
1196                     return;
1197                 }
1198                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1199 
1200                 napi_value callback = nullptr;
1201                 napi_value undefined;
1202                 napi_get_undefined(env, &undefined);
1203 
1204                 napi_value result[PARAM2] = {0};
1205 
1206                 // create error code
1207                 napi_value error = nullptr;
1208                 napi_create_object(env, &error);
1209                 int unSupportCode = 801;
1210                 napi_value errCode = nullptr;
1211                 napi_create_int32(env, unSupportCode, &errCode);
1212                 napi_set_named_property(env, error, "code", errCode);
1213                 result[0] = error;
1214                 napi_get_undefined(env, &result[1]);
1215 
1216                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
1217                 napi_value callResult;
1218                 napi_call_function(env, undefined, callback, PARAM2, result, &callResult);
1219                 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
1220 
1221                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
1222                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1223                 delete asyncCallbackInfo;
1224                 SETTING_LOG_INFO("settingsnapi : callback change callback complete");
1225             },
1226             (void*)asyncCallbackInfo,
1227             &asyncCallbackInfo->asyncWork
1228         );
1229         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1230         return wrap_void_to_js(env);
1231     } else {
1232         SETTING_LOG_INFO("%{public}s, promise.", __func__);
1233         napi_deferred deferred;
1234         napi_value promise;
1235         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1236         asyncCallbackInfo->deferred = deferred;
1237 
1238         napi_create_async_work(
1239             env,
1240             nullptr,
1241             resource,
1242             [](napi_env env, void *data) {},
1243             [](napi_env env, napi_status status, void *data) {
1244                 SETTING_LOG_INFO("%{public}s, promise complete", __func__);
1245                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1246 
1247                 napi_value result;
1248                 napi_value error = nullptr;
1249                 napi_create_object(env, &error);
1250                 int unSupportCode = 801;
1251                 napi_value errCode = nullptr;
1252                 napi_create_int32(env, unSupportCode, &errCode);
1253                 napi_set_named_property(env, error, "code", errCode);
1254                 result = error;
1255 
1256                 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1257                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1258                 delete asyncCallbackInfo;
1259             },
1260             (void *)asyncCallbackInfo,
1261             &asyncCallbackInfo->asyncWork);
1262         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1263         return promise;
1264     }
1265 }
1266 
1267 /**
1268  * @brief canShowFloating NAPI implementation.
1269  * @param env the environment that the Node-API call is invoked under
1270  * @param info the callback info passed into the callback function
1271  * @return napi_value the return value from NAPI C++ to JS for the module.
1272  */
napi_can_show_floating(napi_env env,napi_callback_info info)1273 napi_value napi_can_show_floating(napi_env env, napi_callback_info info)
1274 {
1275     const size_t paramOfPromise = PARAM0;
1276     const size_t paramOfCallback = PARAM1;
1277 
1278     size_t argc = PARAM1;
1279     napi_value args[PARAM1] = {nullptr};
1280     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1281     if (argc != paramOfCallback && argc != paramOfPromise) {
1282         SETTING_LOG_ERROR("settingsnapi : %{public}s, wrong number of arguments, expect 0 or 1 but get %{public}zd",
1283             __func__, argc);
1284         return wrap_void_to_js(env);
1285     }
1286 
1287     SETTING_LOG_INFO("settingsnapi : napi_enable_airplane_mode arg count is %{public}zd", argc);
1288     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1289         .env = env,
1290         .asyncWork = nullptr,
1291         .deferred = nullptr,
1292         .callbackRef = nullptr,
1293         .dataAbilityHelper = nullptr,
1294         .key = "",
1295         .value = "",
1296         .uri = "",
1297         .status = 0,
1298     };
1299     SETTING_LOG_INFO("settingsnapi : after create aysnc call back info");
1300 
1301     napi_value resource = nullptr;
1302     NAPI_CALL(env, napi_create_string_utf8(env, "enableAirplaneMode", NAPI_AUTO_LENGTH, &resource));
1303 
1304     if (argc == paramOfCallback) {
1305         SETTING_LOG_INFO("%{public}s, asyncCallback.", __func__);
1306 
1307         napi_create_reference(env, args[PARAM0], 1, &asyncCallbackInfo->callbackRef);
1308         napi_create_async_work(
1309             env,
1310             nullptr,
1311             resource,
1312             [](napi_env env, void* data) {},
1313             [](napi_env env, napi_status status, void* data) {
1314                 if (data == nullptr) {
1315                     SETTING_LOG_INFO("settingsnapi : callback async end data is null");
1316                     return;
1317                 }
1318                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1319 
1320                 napi_value callback = nullptr;
1321                 napi_value undefined;
1322                 napi_get_undefined(env, &undefined);
1323 
1324                 napi_value result[PARAM2] = {0};
1325 
1326                 // create error code
1327                 napi_value error = nullptr;
1328                 napi_create_object(env, &error);
1329                 int unSupportCode = 801;
1330                 napi_value errCode = nullptr;
1331                 napi_create_int32(env, unSupportCode, &errCode);
1332                 napi_set_named_property(env, error, "code", errCode);
1333                 result[0] = error;
1334                 result[1] = wrap_bool_to_js(env, false);
1335 
1336                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
1337                 napi_value callResult;
1338                 napi_call_function(env, undefined, callback, PARAM2, result, &callResult);
1339                 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
1340 
1341                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
1342                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1343                 delete asyncCallbackInfo;
1344                 SETTING_LOG_INFO("settingsnapi : callback change callback complete");
1345             },
1346             (void*)asyncCallbackInfo,
1347             &asyncCallbackInfo->asyncWork
1348         );
1349         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1350         return wrap_void_to_js(env);
1351     } else {
1352         SETTING_LOG_INFO("%{public}s, promise.", __func__);
1353         napi_deferred deferred;
1354         napi_value promise;
1355         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1356         asyncCallbackInfo->deferred = deferred;
1357 
1358         napi_create_async_work(
1359             env,
1360             nullptr,
1361             resource,
1362             [](napi_env env, void *data) {},
1363             [](napi_env env, napi_status status, void *data) {
1364                 SETTING_LOG_INFO("%{public}s, promise complete", __func__);
1365                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1366 
1367                 napi_value result;
1368                 napi_value error = nullptr;
1369                 napi_create_object(env, &error);
1370                 int unSupportCode = 801;
1371                 napi_value errCode = nullptr;
1372                 napi_create_int32(env, unSupportCode, &errCode);
1373                 napi_set_named_property(env, error, "code", errCode);
1374                 result = error;
1375 
1376                 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1377                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1378                 delete asyncCallbackInfo;
1379             },
1380             (void *)asyncCallbackInfo,
1381             &asyncCallbackInfo->asyncWork);
1382         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1383         return promise;
1384     }
1385 }
1386 }  // namespace Settings
1387 }  // namespace OHOS
1388