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