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