• 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 #include "napi_settings_observer.h"
18 
19 #include <pthread.h>
20 #include <unistd.h>
21 
22 #include "abs_shared_result_set.h"
23 #include "napi_settings_log.h"
24 #include "values_bucket.h"
25 #include "datashare_business_error.h"
26 
27 #include "napi_base_context.h"
28 #include "os_account_manager.h"
29 
30 
31 using namespace OHOS::AppExecFwk;
32 using namespace OHOS::DataShare;
33 using namespace OHOS::AccountSA;
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 const std::string PERMISSION_EXCEPTION = "201 - Permission denied";
41 const int PERMISSION_DENIED_CODE = -2;
42 const int DB_HELPER_TRIAL_NUMBER = 2;
43 const int USERID_HELPER_NUMBER = 100;
44 
ThrowExistingError(napi_env env,std::string errorMessage)45 void ThrowExistingError(napi_env env, std::string errorMessage)
46 {
47     napi_value message;
48     napi_value error;
49     napi_create_string_utf8(env, errorMessage.c_str(), NAPI_AUTO_LENGTH, &message);
50     napi_create_error(env, NULL, message, &error);
51     napi_throw(env, error);
52 }
53 
ThrowError(napi_env env,int status)54 bool ThrowError(napi_env env, int status)
55 {
56     if (status >= 0) {
57         return true;
58     }
59     if (status == PERMISSION_DENIED_CODE) {
60         ThrowExistingError(env, PERMISSION_EXCEPTION);
61     }
62     return false;
63 }
64 
65 /**
66  * @brief Wrap void to js value.
67  * ability_context
68  * @param env the environment that the Node-API call is invoked under
69  * @return napi_value napi_value after wrapped
70  */
wrap_void_to_js(napi_env env)71 napi_value wrap_void_to_js(napi_env env)
72 {
73     napi_value result = nullptr;
74     NAPI_CALL(env, napi_get_null(env, &result));
75     return result;
76 }
77 
78 /**
79  * @brief Unwrap string from js value.
80  *
81  * @param env the environment that the Node-API call is invoked under
82  * @param param js value to unwrap
83  * @return std::string string value after unwrapped
84  */
unwrap_string_from_js(napi_env env,napi_value param)85 std::string unwrap_string_from_js(napi_env env, napi_value param)
86 {
87     std::string defaultValue("");
88 
89     size_t size = 0;
90     if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
91         return defaultValue;
92     }
93 
94     if (size == 0) {
95         return defaultValue;
96     }
97 
98     std::string value("");
99 
100     char *buf = new (std::nothrow) char[size + 1];
101     if (buf == nullptr) {
102         SETTING_LOG_INFO("unwarp");
103         return value;
104     }
105     memset_s(buf, size + 1, 0, size + 1);
106 
107     bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
108     if (rev) {
109         value = buf;
110     } else {
111         value = defaultValue;
112     }
113 
114     delete[] buf;
115     buf = nullptr;
116     SETTING_LOG_INFO("unwarp str is : %{public}s", value.c_str());
117     return value;
118 }
119 
120 /**
121  * @brief Wrap string to js value.
122  *
123  * @param env the environment that the Node-API call is invoked under
124  * @param value string value to be wrap
125  * @return napi_value js value after wrapped
126  */
wrap_string_to_js(napi_env env,const std::string & value)127 napi_value wrap_string_to_js(napi_env env, const std::string &value)
128 {
129     napi_value result = nullptr;
130     NAPI_CALL(env, napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result));
131     return result;
132 }
133 
134 /**
135  * @brief Wrap bool to js value.
136  *
137  * @param env the environment that the Node-API call is invoked under
138  * @param value bool value to be wrap
139  * @return napi_value js value after wrapped
140  */
wrap_bool_to_js(napi_env env,bool value)141 napi_value wrap_bool_to_js(napi_env env, bool value)
142 {
143     napi_value result = nullptr;
144     NAPI_CALL(env, napi_get_boolean(env, value, &result));
145     return result;
146 }
147 
148 /**
149  * @brief getUri NAPI implementation.
150  *
151  * @param env the environment that the Node-API call is invoked under
152  * @param info the callback info passed into the callback function
153  * @return napi_value the return value from NAPI C++ to JS for the module.
154  */
napi_get_uri_sync(napi_env env,napi_callback_info info)155 napi_value napi_get_uri_sync(napi_env env, napi_callback_info info)
156 {
157     SETTING_LOG_INFO("called");
158 
159     napi_value retUri = nullptr;
160 
161     // Check the number of the arguments
162     size_t argc = ARGS_TWO;
163     napi_value args[ARGS_TWO] = {nullptr};
164     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
165     if (argc != ARGS_ONE && argc != ARGS_TWO) {
166         SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
167         return wrap_void_to_js(env);
168     }
169 
170     // Check the value type of the arguments
171     napi_valuetype valueType;
172     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
173     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument type. String expected.");
174 
175     if (argc == ARGS_TWO) {
176         SETTING_LOG_INFO("ARGS_TWO");
177         std::string keyStr = unwrap_string_from_js(env, args[PARAM0]);
178         // get userId string
179         std::vector<int> tmpId;
180         OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(tmpId);
181         std::string tmpIdStr = "100";
182         if (tmpId.size() > 0) {
183             tmpIdStr = std::to_string(tmpId[0]);
184         } else {
185             SETTING_LOG_ERROR("userid is invalid, use id 100 instead");
186         }
187         std::string tableName = unwrap_string_from_js(env, args[PARAM1]);
188         std::string retStr = GetStageUriStr(tableName, tmpIdStr, keyStr);
189         retUri = wrap_string_to_js(env, retStr);
190         return retUri;
191     } else {
192         SETTING_LOG_INFO("ARGS_OTHER (should one)");
193         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
194         if (argc != ARGS_ONE) {
195             SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
196             return wrap_void_to_js(env);
197         }
198 
199         std::string uriArgStr = unwrap_string_from_js(env, args[PARAM0]);
200         uriArgStr = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + uriArgStr;
201         retUri = wrap_string_to_js(env, uriArgStr);
202         return retUri;
203     }
204 }
205 
napi_get_uri(napi_env env,napi_callback_info info)206 napi_value napi_get_uri(napi_env env, napi_callback_info info)
207 {
208     SETTING_LOG_INFO("uri called");
209     // Check the number of the arguments
210     size_t argc = ARGS_THREE;
211     napi_value args[ARGS_THREE] = {nullptr};
212     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
213     if (argc != ARGS_ONE && argc != ARGS_TWO && argc != ARGS_THREE) {
214         SETTING_LOG_ERROR(
215             "uri %{public}s, wrong number of arguments, expect 1 or 2 or 3 but get %{public}zd",
216             __func__,
217             argc);
218         return wrap_void_to_js(env);
219     }
220 
221     // Check the value type of the arguments
222     napi_valuetype valueType;
223     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
224     NAPI_ASSERT(env, valueType == napi_string, "uri Wrong argument type. String expected.");
225 
226     // check call type for stage model
227     CallType callType = INVALID_CALL;
228     if (argc == ARGS_ONE) {
229         callType = STAGE_PROMISE;
230     } else if (argc == ARGS_TWO) {
231         napi_valuetype valueType;
232         NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
233         if (valueType == napi_string) {
234             callType = STAGE_PROMISE_SPECIFIC;
235         } else {
236             callType = STAGE_CALLBACK;
237         }
238     } else if (argc == ARGS_THREE) {
239         callType = STAGE_CALLBACK_SPECIFIC;
240     }
241 
242     SETTING_LOG_INFO("uri arg count is %{public}zd", argc);
243     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
244         .env = env,
245         .asyncWork = nullptr,
246         .deferred = nullptr,
247         .callbackRef = nullptr,
248         .dataAbilityHelper = nullptr,
249         .key = "",
250         .value = "",
251         .uri = "",
252         .status = false,
253     };
254 
255     std::string keyStr = unwrap_string_from_js(env, args[PARAM0]);
256     // get userId string
257     std::vector<int> tmpId;
258     OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(tmpId);
259     std::string tmpIdStr = "100";
260     if (tmpId.size() > 0) {
261         tmpIdStr = std::to_string(tmpId[0]);
262     } else {
263         SETTING_LOG_ERROR("userid is invalid, use id 100 instead");
264     }
265     std::string tableName = "";
266     if (callType == STAGE_CALLBACK_SPECIFIC) {
267         tableName = unwrap_string_from_js(env, args[PARAM2]);
268     } else if (callType == STAGE_PROMISE_SPECIFIC) {
269         tableName = unwrap_string_from_js(env, args[PARAM1]);
270     } else {
271         tableName = "global";
272     }
273     std::string retStr = GetStageUriStr(tableName, tmpIdStr, keyStr);
274     asyncCallbackInfo->uri = retStr;
275     SETTING_LOG_INFO("uri aft is %{public}s", asyncCallbackInfo->uri.c_str());
276 
277     napi_value resource = nullptr;
278     NAPI_CALL(env, napi_create_string_utf8(env, "getUri", NAPI_AUTO_LENGTH, &resource));
279 
280     if (callType == STAGE_CALLBACK || callType == STAGE_CALLBACK_SPECIFIC) {
281         SETTING_LOG_INFO("uri do c_b");
282         napi_create_reference(env, args[PARAM1], 1, &asyncCallbackInfo->callbackRef);
283 
284         napi_create_async_work(
285             env,
286             nullptr,
287             resource,
288             [](napi_env env, void* data) {
289                 SETTING_LOG_INFO("uri c_b asy execute c_b");
290             },
291             [](napi_env env, napi_status status, void* data) {
292                 if (data == nullptr) {
293                     SETTING_LOG_INFO("uri c_b asy end data is null");
294                     return;
295                 }
296                 SETTING_LOG_INFO("uri c_b asy end");
297                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
298                 napi_value undefine;
299                 napi_get_undefined(env, &undefine);
300                 napi_value callback = nullptr;
301                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->uri);
302                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
303                 napi_call_function(env, nullptr, callback, 1, &result, &undefine);
304                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
305                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
306                 delete asyncCallbackInfo;
307                 SETTING_LOG_INFO("uri c_b change complete");
308             },
309             (void*)asyncCallbackInfo,
310             &asyncCallbackInfo->asyncWork
311         );
312 
313         SETTING_LOG_INFO("uri c_b start asy work");
314         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
315         SETTING_LOG_INFO("uri c_b end asy work");
316         return wrap_void_to_js(env);
317     } else {
318         SETTING_LOG_INFO("uri do p_m");
319         napi_value promise;
320         napi_deferred deferred;
321         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
322         asyncCallbackInfo->deferred = deferred;
323 
324         napi_create_async_work(
325             env,
326             nullptr,
327             resource,
328             // aysnc executed task
329             [](napi_env env, void* data) {
330                 SETTING_LOG_INFO("uri p_m asy execute c_b");
331             },
332             // async end called callback+
333             [](napi_env env, napi_status status, void* data) {
334                 SETTING_LOG_INFO("uri p_m asy end");
335                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
336                 SETTING_LOG_INFO("uri p_m end get c_b value is %{public}s",
337                     asyncCallbackInfo->uri.c_str());
338                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->uri);
339                 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
340                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
341                 delete asyncCallbackInfo;
342             },
343             (void*)asyncCallbackInfo,
344             &asyncCallbackInfo->asyncWork);
345         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
346         SETTING_LOG_INFO("uri p_m end asy work");
347         return promise;
348     }
349 }
350 
CheckDataShareHelper(napi_env env,const napi_value context,std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper,OHOS::Uri proxyUri)351 void CheckDataShareHelper(napi_env env, const napi_value context,
352     std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper, OHOS::Uri proxyUri)
353 {
354     std::shared_ptr<OHOS::DataShare::DataShareResultSet> resultset = nullptr;
355     std::string strUri = "datashare:///com.ohos.settingsdata.DataAbility";
356     DataSharePredicates predicates;
357     predicates.Limit(1, 0);
358     auto contextS = OHOS::AbilityRuntime::GetStageModeContext(env, context);
359     std::vector<std::string> columns;
360     DatashareBusinessError businessError;
361     resultset = dataShareHelper->Query(proxyUri, predicates, columns, &businessError);
362     int numRows = 0;
363     if (resultset != nullptr) {
364         resultset->GetRowCount(numRows);
365     }
366     SETTING_LOG_INFO("numRows %{public}d, error code %{public}d", numRows, businessError.GetCode());
367     if (businessError.GetCode() == PERMISSION_DENIED_CODE) {
368         if (resultset != nullptr) {
369             resultset->Close();
370         }
371         return;
372     } else if (resultset == nullptr || numRows <= 0) {
373         int trial = 0;
374         do {
375             SETTING_LOG_INFO("settingsnapi : getDataShareHelper resultset == nullptr, strUri %{public}s %{public}d",
376                 strUri.c_str(),
377                 trial);
378             dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strUri);
379         } while (trial++ < DB_HELPER_TRIAL_NUMBER && dataShareHelper == nullptr);
380         if (resultset != nullptr) {
381             resultset->Close();
382         }
383         return;
384     }
385     resultset->Close();
386 }
387 
getDataShareHelper(napi_env env,const napi_value context,const bool stageMode,std::string tableName,AsyncCallbackInfo * asyncCallbackInfo)388 std::shared_ptr<DataShareHelper> getDataShareHelper(
389     napi_env env, const napi_value context, const bool stageMode, std::string tableName,
390     AsyncCallbackInfo *asyncCallbackInfo)
391 {
392     std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
393     std::vector<int> tmpId;
394     OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(tmpId);
395     std::string tmpIdStr = "100";
396     if (tmpId.size() > 0) {
397         tmpIdStr = std::to_string(tmpId[0]);
398     } else {
399         SETTING_LOG_ERROR("userid is invalid, use id 100 instead");
400     }
401     std::string strUri = "datashare:///com.ohos.settingsdata.DataAbility";
402     std::string strProxyUri = GetProxyUriStr(tableName, tmpIdStr);
403     OHOS::Uri proxyUri(strProxyUri);
404     SETTING_LOG_INFO("<Ver-11-14> strProxyUri: %{public}s", strProxyUri.c_str());
405     auto contextS = OHOS::AbilityRuntime::GetStageModeContext(env, context);
406 
407     dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strProxyUri);
408     if (!dataShareHelper) {
409         SETTING_LOG_ERROR("dataShareHelper from strProxyUri is null");
410         dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strUri);
411         if (asyncCallbackInfo) {
412             asyncCallbackInfo->useSilent = true;
413         }
414     }
415     SETTING_LOG_INFO("g_D_S_H Creator called, valid %{public}d", dataShareHelper != nullptr);
416     return dataShareHelper;
417 }
418 
QueryValue(napi_env env,AsyncCallbackInfo * asyncCallbackInfo,OHOS::Uri uri)419 void QueryValue(napi_env env, AsyncCallbackInfo* asyncCallbackInfo, OHOS::Uri uri)
420 {
421     SETTING_LOG_INFO("a_C_B_I->d_S_H != nullptr");
422     if (asyncCallbackInfo->dataShareHelper == nullptr) {
423         SETTING_LOG_ERROR("helper is null");
424         asyncCallbackInfo->status = -1;
425         return;
426     }
427 
428     std::vector<std::string> columns;
429     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
430 
431     OHOS::DataShare::DataSharePredicates predicates;
432     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
433 
434     DatashareBusinessError businessError;
435     std::shared_ptr<OHOS::DataShare::DataShareResultSet> resultset = nullptr;
436     resultset = asyncCallbackInfo->dataShareHelper->Query(uri, predicates, columns, &businessError);
437     int numRows = 0;
438     if (resultset != nullptr) {
439         SETTING_LOG_INFO("G_V_E_E resultset is NOT empty");
440         resultset->GetRowCount(numRows);
441     }
442     SETTING_LOG_INFO("numRows %{public}d, error code %{public}d", numRows, businessError.GetCode());
443     if (businessError.GetCode() != 0) {
444         asyncCallbackInfo->status = businessError.GetCode();
445     } else if (resultset == nullptr || numRows <= 0) {
446         SETTING_LOG_INFO("G_V_E_E value is empty");
447         asyncCallbackInfo->status = -1;
448     } else {
449         std::string val;
450         int32_t columnIndex = 0;
451         resultset->GoToFirstRow();
452         resultset->GetString(columnIndex, val);
453 
454         SETTING_LOG_INFO("n_g_v_e %{public}s", val.c_str());
455         asyncCallbackInfo->value = val;
456         asyncCallbackInfo->status = napi_ok;
457     }
458 
459     if (resultset != nullptr) {
460         resultset->Close();
461     }
462 }
463 
GetValueExecuteExt(napi_env env,void * data)464 void GetValueExecuteExt(napi_env env, void *data)
465 {
466     if (data == nullptr) {
467         SETTING_LOG_INFO("execute data is null");
468         return;
469     }
470 
471     SETTING_LOG_INFO("G_V_E_E start");
472     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
473 
474     if (asyncCallbackInfo->dataShareHelper == nullptr) {
475         SETTING_LOG_ERROR("dataShareHelper is empty");
476         asyncCallbackInfo->status = -1;
477         return;
478     }
479 
480     std::vector<int> tmpId;
481     OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(tmpId);
482     std::string tmpIdStr = "100";
483     if (tmpId.size() > 0) {
484         tmpIdStr = std::to_string(tmpId[0]);
485     } else {
486         SETTING_LOG_ERROR("userid is invalid, use id 100 instead");
487     }
488     std::string strUri = GetStageUriStr(asyncCallbackInfo->tableName, tmpIdStr, asyncCallbackInfo->key);
489     SETTING_LOG_INFO(
490         "Get uri : %{public}s, key: %{public}s", strUri.c_str(), (asyncCallbackInfo->key).c_str());
491     OHOS::Uri uri(strUri);
492 
493     QueryValue(env, asyncCallbackInfo, uri);
494 }
495 
DeleteCallbackInfo(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)496 void DeleteCallbackInfo(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
497 {
498     if (env != nullptr) {
499         napi_delete_reference(env, asyncCallbackInfo->callbackRef);
500         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
501     }
502     asyncCallbackInfo->dataShareHelper = nullptr;
503     delete asyncCallbackInfo;
504 }
505 
CompleteCall(napi_env env,napi_status status,void * data,const napi_value retVaule)506 void CompleteCall(napi_env env, napi_status status, void *data, const napi_value retVaule)
507 {
508     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
509     napi_value result[PARAM2] = {0};
510     if (status == napi_ok && asyncCallbackInfo->status == napi_ok) {
511         napi_get_undefined(env, &result[PARAM0]);
512         result[PARAM1] = retVaule;
513     } else {
514         napi_value message = nullptr;
515         napi_create_string_utf8(env, "async call failed", NAPI_AUTO_LENGTH, &message);
516         napi_create_error(env, nullptr, message, &result[PARAM0]);
517         napi_get_undefined(env, &result[PARAM1]);
518     }
519     napi_value callback = nullptr;
520     napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
521     napi_value returnValue;
522     napi_call_function(env, nullptr, callback, PARAM2, result, &returnValue);
523     DeleteCallbackInfo(env, asyncCallbackInfo);
524     SETTING_LOG_INFO("c_b complete");
525 }
526 
CompletePromise(napi_env env,napi_status status,void * data,const napi_value retVaule)527 void CompletePromise(napi_env env, napi_status status, void *data, const napi_value retVaule)
528 {
529     SETTING_LOG_INFO("p_m asy end  c_b");
530     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
531     napi_value result = nullptr;
532     if (status == napi_ok && asyncCallbackInfo->status == napi_ok) {
533         napi_resolve_deferred(env, asyncCallbackInfo->deferred, retVaule);
534     } else {
535         napi_get_undefined(env, &result);
536         napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
537     }
538     DeleteCallbackInfo(env, asyncCallbackInfo);
539 }
540 
SetValueExecuteExt(napi_env env,void * data,const std::string setValue)541 void SetValueExecuteExt(napi_env env, void *data, const std::string setValue)
542 {
543     if (data == nullptr) {
544         SETTING_LOG_INFO("s_V_E_E data is null");
545         return;
546     }
547     SETTING_LOG_INFO("execute start");
548     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
549 
550     if (asyncCallbackInfo->dataShareHelper == nullptr) {
551         SETTING_LOG_INFO("helper is null");
552         asyncCallbackInfo->status = -1;
553         return;
554     }
555 
556     OHOS::DataShare::DataShareValuesBucket val;
557     val.Put(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
558     val.Put(SETTINGS_DATA_FIELD_VALUE, setValue);
559 
560     std::vector<int> tmpId;
561     OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(tmpId);
562     std::string tmpIdStr = "100";
563     if (tmpId.size() > 0) {
564         tmpIdStr = std::to_string(tmpId[0]);
565     } else {
566         SETTING_LOG_ERROR("userid is invalid, use id 100 instead");
567     }
568     std::string strUri = GetStageUriStr(asyncCallbackInfo->tableName, tmpIdStr, asyncCallbackInfo->key);
569     SETTING_LOG_INFO(
570         "Set uri : %{public}s, key: %{public}s", strUri.c_str(), (asyncCallbackInfo->key).c_str());
571     OHOS::Uri uri(strUri);
572 
573     OHOS::DataShare::DataSharePredicates predicates;
574     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
575 
576     // update first.
577     int retInt = asyncCallbackInfo->dataShareHelper->Update(uri, predicates, val);
578     SETTING_LOG_ERROR("update ret: %{public}d", retInt);
579     if (retInt <= 0) {
580         // retry to insert.
581         retInt = asyncCallbackInfo->dataShareHelper->Insert(uri, val);
582         SETTING_LOG_ERROR("insert ret: %{public}d", retInt);
583     }
584     if (retInt > 0 && asyncCallbackInfo->useSilent) {
585         SETTING_LOG_INFO("use silent and notifyChange!");
586         asyncCallbackInfo->dataShareHelper->NotifyChange(uri);
587     }
588     asyncCallbackInfo->status = retInt;
589 }
590 
591 /**
592  * @brief getValue NAPI implementation.
593  *
594  * @param env the environment that the Node-API call is invoked under
595  * @param info the callback info passed into the callback function
596  * @return napi_value the return value from NAPI C++ to JS for the module.
597  */
napi_get_value_sync(napi_env env,napi_callback_info info)598 napi_value napi_get_value_sync(napi_env env, napi_callback_info info)
599 {
600     SETTING_LOG_INFO("n_g_v");
601 
602     // Check the number of the arguments
603     size_t argc = ARGS_FOUR;
604     napi_value args[ARGS_FOUR] = {nullptr};
605     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
606     if (argc != ARGS_THREE && argc != ARGS_FOUR) {
607         SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
608         return wrap_void_to_js(env);
609     }
610 
611     // Check the value type of the arguments
612     napi_valuetype valueType;
613     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
614     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
615     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
616     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected.");
617     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
618     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected.");
619 
620     bool stageMode = false;
621     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
622     if (status == napi_ok) {
623         return napi_get_value_sync_ext(stageMode, argc, env, args);
624     }
625 
626     std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
627     std::shared_ptr<DataAbilityHelper> dataAbilityHelper = nullptr;
628     NAPIDataAbilityHelperWrapper* wrapper = nullptr;
629     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&wrapper)));
630     if (wrapper != nullptr) {
631         dataAbilityHelper = wrapper->GetDataAbilityHelper();
632     }
633 
634     std::vector<std::string> columns;
635     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
636     OHOS::NativeRdb::DataAbilityPredicates predicates;
637     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, unwrap_string_from_js(env, args[PARAM1]));
638 
639     SETTING_LOG_INFO("n_g_v bef d_A_H->Query");
640     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
641     if (dataAbilityHelper != nullptr) {
642         resultset = dataAbilityHelper->Query(*uri, columns, predicates);
643     };
644 
645     napi_value retVal = nullptr;
646     int numRows = 0;
647 
648     if (resultset != nullptr) {
649         SETTING_LOG_INFO("n_g_v resultset is NOT empty");
650         resultset->GetRowCount(numRows);
651     }
652 
653     if (resultset == nullptr || numRows == 0) {
654         SETTING_LOG_INFO("n_g_v return def value");
655         retVal = args[PARAM2];
656     } else {
657         SETTING_LOG_INFO("n_g_v return value from resultset");
658         std::string val;
659         int32_t columnIndex = 0;
660         resultset->GoToFirstRow();
661         resultset->GetString(columnIndex, val);
662         retVal = wrap_string_to_js(env, val);
663     }
664 
665     if (resultset != nullptr) {
666         resultset->Close();
667     }
668     dataAbilityHelper = nullptr;
669     SETTING_LOG_INFO("n_g_v END!");
670     return retVal;
671 }
672 
get_val_CB_exe_CB(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)673 void get_val_CB_exe_CB(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
674 {
675     std::vector<std::string> columns;
676     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
677     OHOS::NativeRdb::DataAbilityPredicates predicates;
678     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
679 
680     std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
681     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
682     if (asyncCallbackInfo->dataAbilityHelper != nullptr) {
683         resultset = asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
684     };
685     SETTING_LOG_INFO("c_b n_g_v aft d_A_H->Query");
686 
687     int numRows = 0;
688     if (resultset != nullptr) {
689         SETTING_LOG_INFO("c_b n_g_v resultset is NOT empty");
690         resultset->GetRowCount(numRows);
691     }
692     if (resultset == nullptr || numRows == 0) {
693         SETTING_LOG_INFO("c_b n_g_v return def value");
694     } else {
695         std::string val;
696         int32_t columnIndex = 0;
697         resultset->GoToFirstRow();
698         resultset->GetString(columnIndex, val);
699         SETTING_LOG_INFO("c_b retVal is %{public}s", val.c_str());
700         asyncCallbackInfo->value = val;
701     }
702     if (resultset != nullptr) {
703         resultset->Close();
704     }
705 }
706 
napi_get_value(napi_env env,napi_callback_info info)707 napi_value napi_get_value(napi_env env, napi_callback_info info)
708 {
709     // getValue api need 3 parameters when Promise mode and need 4 parameters when callback mode
710     const size_t paramOfCallback = ARGS_THREE;
711 
712     size_t argc = ARGS_FOUR;
713     napi_value args[ARGS_FOUR] = {nullptr};
714     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
715     if (argc != ARGS_TWO && argc != ARGS_THREE && argc != ARGS_FOUR) {
716         SETTING_LOG_ERROR(
717             "%{public}s, wrong number of arguments, expect 2 or 3 or 4 but get %{public}zd",
718             __func__,
719             argc);
720         return wrap_void_to_js(env);
721     }
722 
723     SETTING_LOG_INFO("n_g_v arg count is %{public}zd", argc);
724     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
725         .env = env,
726         .asyncWork = nullptr,
727         .deferred = nullptr,
728         .callbackRef = nullptr,
729         .dataAbilityHelper = nullptr,
730         .key = "",
731         .value = "",
732         .uri = "",
733         .status = false,
734     };
735     // Check the value type of the arguments
736     napi_valuetype valueType;
737     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
738     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
739     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
740     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1], type. String expected");
741 
742     bool stageMode = false;
743     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
744     if (status == napi_ok) {
745         SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
746         return napi_get_value_ext(env, info, stageMode);
747     }
748 
749     NAPIDataAbilityHelperWrapper* wrapper = nullptr;
750     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&wrapper)));
751     if (wrapper != nullptr) {
752         asyncCallbackInfo->dataAbilityHelper = wrapper->GetDataAbilityHelper();
753     }
754 
755     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
756     SETTING_LOG_INFO("input param is : (key %{public}s", asyncCallbackInfo->key.c_str());
757 
758     napi_value resource = nullptr;
759     NAPI_CALL(env, napi_create_string_utf8(env, "getValue", NAPI_AUTO_LENGTH, &resource));
760 
761     if (argc == paramOfCallback) {
762         SETTING_LOG_INFO("do c_b");
763 
764         napi_create_reference(env, args[PARAM2], 1, &asyncCallbackInfo->callbackRef);
765 
766         napi_create_async_work(
767             env,
768             nullptr,
769             resource,
770             // aysnc executed task
771             [](napi_env env, void *data) {
772                 if (data == nullptr) {
773                     SETTING_LOG_INFO("c_b async execute data is null");
774                     return;
775                 }
776                 SETTING_LOG_INFO("c_b async execute c_b");
777                 AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data;
778                 get_val_CB_exe_CB(env, asyncCallbackInfo);
779             },
780             // async end called callback
781             [](napi_env env, napi_status status, void *data) {
782                 if (data == nullptr) {
783                     SETTING_LOG_INFO("c_b end data is null");
784                     return;
785                 }
786                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
787                 napi_value undefine;
788                 napi_get_undefined(env, &undefine);
789                 napi_value callback = nullptr;
790                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
791                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
792                 napi_call_function(env, nullptr, callback, 1, &result, &undefine);
793                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
794                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
795                 asyncCallbackInfo->dataAbilityHelper = nullptr;
796                 delete asyncCallbackInfo;
797                 SETTING_LOG_INFO("c_b change complete");
798             },
799             (void *)asyncCallbackInfo,
800             &asyncCallbackInfo->asyncWork);
801 
802         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
803         SETTING_LOG_INFO("c_b end async work");
804         return wrap_void_to_js(env);
805     } else {
806         SETTING_LOG_INFO("do p_m");
807         napi_value promise;
808         napi_deferred deferred;
809         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
810         asyncCallbackInfo->deferred = deferred;
811 
812         napi_create_async_work(
813         env,
814         nullptr,
815         resource,
816         // aysnc executed task
817         [](napi_env env, void* data) {
818             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
819             SETTING_LOG_INFO("p_m get c_b key is %{public}s, value is: %{public}s",
820 			    asyncCallbackInfo->key.c_str(), asyncCallbackInfo->value.c_str());
821 
822             std::vector<std::string> columns;
823             columns.push_back(SETTINGS_DATA_FIELD_VALUE);
824             OHOS::NativeRdb::DataAbilityPredicates predicates;
825             predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
826 
827             std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
828             std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
829             if (asyncCallbackInfo->dataAbilityHelper != nullptr) {
830                 resultset = asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
831             }
832             SETTING_LOG_INFO("p_m n_g_v aft d_A_H->Query");
833 
834             int numRows = 0;
835             if (resultset != nullptr) {
836                 SETTING_LOG_INFO("p_m n_g_v resultset is NOT empty");
837                 resultset->GetRowCount(numRows);
838             }
839             if (resultset == nullptr || numRows == 0) {
840                 SETTING_LOG_INFO("p_m n_g_v return def value");
841             } else {
842                 SETTING_LOG_INFO("p_m n_g_v return value from resultset");
843                 std::string val;
844                 int32_t columnIndex = 0;
845                 resultset->GoToFirstRow();
846                 resultset->GetString(columnIndex, val);
847                 asyncCallbackInfo->value = val;
848             }
849             if (resultset != nullptr) {
850                 resultset->Close();
851             }
852         },
853         // async end called callback
854         [](napi_env env, napi_status status, void* data) {
855             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
856             SETTING_LOG_INFO("p_m end get c_b value is %{public}s",
857                 asyncCallbackInfo->value.c_str());
858             napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
859             napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
860             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
861             asyncCallbackInfo->dataAbilityHelper = nullptr;
862             delete asyncCallbackInfo;
863         },
864         (void*)asyncCallbackInfo,
865         &asyncCallbackInfo->asyncWork);
866         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
867         return promise;
868     }
869 }
870 
871 // api9
napi_get_value_ext(napi_env env,napi_callback_info info,const bool stageMode)872 napi_value napi_get_value_ext(napi_env env, napi_callback_info info, const bool stageMode)
873 {
874     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
875         .env = env,
876         .asyncWork = nullptr,
877         .deferred = nullptr,
878         .callbackRef = nullptr,
879         .dataAbilityHelper = nullptr,
880         .key = "",
881         .value = "",
882         .uri = "",
883         .status = false,
884     };
885 
886     SETTING_LOG_INFO("n_g_v_e called");
887     size_t argc = ARGS_FOUR;
888     napi_value args[ARGS_FOUR] = {nullptr};
889     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
890 
891     asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
892 
893     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
894 
895     napi_value resource = nullptr;
896     NAPI_CALL(env, napi_create_string_utf8(env, "getValue", NAPI_AUTO_LENGTH, &resource));
897 
898     // set call type and table name, and check whether the parameter is valid
899     napi_valuetype valueType;
900     if (argc == ARGS_TWO) {
901         asyncCallbackInfo->callType = STAGE_PROMISE;
902         asyncCallbackInfo->tableName = "global";
903     } else if (argc == ARGS_THREE) {
904         NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
905         if (valueType == napi_string) {
906             asyncCallbackInfo->tableName = unwrap_string_from_js(env, args[PARAM2]);
907             if (IsTableNameInvalid(asyncCallbackInfo->tableName)) {
908                 SETTING_LOG_ERROR("INVALID tableName [ARGS_THREE]");
909                 return wrap_void_to_js(env);
910             } else {
911                 asyncCallbackInfo->callType = STAGE_PROMISE_SPECIFIC;
912             }
913         } else {
914             asyncCallbackInfo->callType = STAGE_CALLBACK;
915             asyncCallbackInfo->tableName = "global";
916         }
917     } else if (argc == ARGS_FOUR) {
918         asyncCallbackInfo->callType = STAGE_CALLBACK_SPECIFIC;
919         asyncCallbackInfo->tableName = unwrap_string_from_js(env, args[PARAM3]);
920     } else {
921         asyncCallbackInfo->callType = INVALID_CALL;
922     }
923 
924     // check whether invalid call
925     if (asyncCallbackInfo->callType == INVALID_CALL) {
926         SETTING_LOG_ERROR("INVALID CALL");
927         return wrap_void_to_js(env);
928     }
929 
930     if (asyncCallbackInfo->callType == STAGE_CALLBACK || asyncCallbackInfo->callType == STAGE_CALLBACK_SPECIFIC) {
931         napi_create_reference(env, args[PARAM2], 1, &asyncCallbackInfo->callbackRef);
932         napi_create_async_work(
933             env,
934             nullptr,
935             resource,
936             GetValueExecuteExt,
937             [](napi_env env, napi_status status, void* data) {
938                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
939                 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
940                 CompleteCall(env, status, data, result);
941             },
942             (void*)asyncCallbackInfo,
943             &asyncCallbackInfo->asyncWork
944         );
945         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
946         SETTING_LOG_INFO("c_b end async work");
947         return wrap_void_to_js(env);
948     } else if (asyncCallbackInfo->callType != INVALID_CALL) {
949         napi_value promise;
950         napi_deferred deferred;
951         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
952         asyncCallbackInfo->deferred = deferred;
953         napi_create_async_work(
954             env,
955             nullptr,
956             resource,
957             GetValueExecuteExt,
958             [](napi_env env, napi_status status, void* data) {
959                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
960                 napi_value result = nullptr;
961                 result = wrap_string_to_js(env, asyncCallbackInfo->value);
962                 CompletePromise(env, status, data, result);
963             },
964             (void*)asyncCallbackInfo,
965             &asyncCallbackInfo->asyncWork
966         );
967         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
968         return promise;
969     } else {
970         SETTING_LOG_ERROR("INVALID CALL");
971         return wrap_void_to_js(env);
972     }
973 }
974 
975 /**
976  * @brief setValue NAPI implementation.
977  *
978  * @param env the environment that the Node-API call is invoked under
979  * @param info the callback info passed into the callback function
980  * @return napi_value the return value from NAPI C++ to JS for the module.
981  */
napi_set_value_sync(napi_env env,napi_callback_info info)982 napi_value napi_set_value_sync(napi_env env, napi_callback_info info)
983 {
984     SETTING_LOG_INFO("n_s_v");
985 
986     // Check the number of the arguments
987     size_t argc = ARGS_FOUR;
988     napi_value args[ARGS_FOUR] = {nullptr};
989     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
990     if (argc != ARGS_THREE && argc != ARGS_FOUR) {
991         SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
992         return wrap_void_to_js(env);
993     }
994 
995     // Check the value type of the arguments
996     napi_valuetype valueType;
997     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
998     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
999     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
1000     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected.");
1001     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
1002     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected.");
1003 
1004     bool stageMode = false;
1005     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
1006     if (status == napi_ok) {
1007         return napi_set_value_sync_ext(stageMode, argc, env, args);
1008     }
1009 
1010     std::shared_ptr<DataAbilityHelper> dataAbilityHelper = nullptr;
1011     NAPIDataAbilityHelperWrapper* wrapper = nullptr;
1012     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&wrapper)));
1013     if (wrapper != nullptr) {
1014         dataAbilityHelper = wrapper->GetDataAbilityHelper();
1015     }
1016 
1017     std::string argsName = unwrap_string_from_js(env, args[PARAM1]);
1018     std::string argsDefaultValue = unwrap_string_from_js(env, args[PARAM2]);
1019 
1020     OHOS::NativeRdb::ValuesBucket val;
1021     val.PutString(SETTINGS_DATA_FIELD_KEYWORD, argsName);
1022     val.PutString(SETTINGS_DATA_FIELD_VALUE, argsDefaultValue);
1023 
1024     std::vector<std::string> columns;
1025     columns.push_back(SETTINGS_DATA_FIELD_VALUE);
1026     OHOS::NativeRdb::DataAbilityPredicates predicates;
1027     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, argsName);
1028 
1029     std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
1030     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset = nullptr;
1031     if (dataAbilityHelper != nullptr) {
1032         resultset = dataAbilityHelper->Query(*uri, columns, predicates);
1033     }
1034     SETTING_LOG_INFO("n_s_v aft d_A_H->Query");
1035 
1036     int retInt = 0;
1037     int numRows = 0;
1038 
1039     if (resultset != nullptr) {
1040         SETTING_LOG_INFO("n_s_v resultset is NOT empty");
1041         resultset->GetRowCount(numRows);
1042     }
1043 
1044     // insert
1045     if (resultset == nullptr || numRows == 0) {
1046         retInt = dataAbilityHelper->Insert(*uri, val);
1047         SETTING_LOG_INFO("n_s_v aft In");
1048     // update
1049     } else {
1050         retInt = dataAbilityHelper->Update(*uri, val, predicates);
1051         SETTING_LOG_INFO("n_s_v aft Up");
1052     }
1053     // notify change
1054     if (retInt != 0) {
1055         std::string uriWithNameStr =
1056             argsName.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + argsName);
1057         std::shared_ptr<Uri> uriWithName = std::make_shared<Uri>(uriWithNameStr);
1058         dataAbilityHelper->NotifyChange(*uriWithName);
1059         SETTING_LOG_INFO("n_s_v aft NotifyChange with uri: %{public}s", uriWithNameStr.c_str());
1060     }
1061 
1062     if (resultset != nullptr) {
1063         resultset->Close();
1064     }
1065 
1066     return wrap_bool_to_js(env, ThrowError(env, retInt));
1067 }
1068 
SetValueExecuteCB(napi_env env,void * data)1069 void SetValueExecuteCB(napi_env env, void *data)
1070 {
1071     if (data == nullptr) {
1072         SETTING_LOG_INFO("execute data is null");
1073         return;
1074     }
1075     AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1076 
1077     if (asyncCallbackInfo->dataAbilityHelper == nullptr) {
1078         SETTING_LOG_ERROR("helper is null");
1079         asyncCallbackInfo->status = -1;
1080         return;
1081     }
1082 
1083     std::string argsName = asyncCallbackInfo->key;
1084     std::string argsDefaultValue = asyncCallbackInfo->value;
1085 
1086     OHOS::NativeRdb::ValuesBucket val;
1087     val.PutString(SETTINGS_DATA_FIELD_KEYWORD, argsName);
1088     val.PutString(SETTINGS_DATA_FIELD_VALUE, argsDefaultValue);
1089 
1090     OHOS::NativeRdb::DataAbilityPredicates predicates;
1091     predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, argsName);
1092 
1093     std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
1094     SETTING_LOG_INFO("execute bef d_A_H->Update");
1095     // update first
1096     int retInt = asyncCallbackInfo->dataAbilityHelper->Update(*uri, val, predicates);
1097     SETTING_LOG_ERROR("update ret: %{public}d", retInt);
1098     if (retInt <= 0) {
1099         // retry to insert
1100         retInt = asyncCallbackInfo->dataAbilityHelper->Insert(*uri, val);
1101         SETTING_LOG_ERROR("insert ret: %{public}d", retInt);
1102     }
1103     // notify change
1104     if (retInt > 0) {
1105         std::string uriWithNameStr =
1106             argsName.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + argsName);
1107         std::shared_ptr<Uri> uriWithName = std::make_shared<Uri>(uriWithNameStr);
1108         asyncCallbackInfo->dataAbilityHelper->NotifyChange(*uriWithName);
1109         SETTING_LOG_INFO("execute aft NotifyC with uri: %{public}s", uriWithNameStr.c_str());
1110     }
1111     SETTING_LOG_INFO("execute... END!");
1112     asyncCallbackInfo->status = retInt;
1113 }
1114 
SetValueAsync(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1115 napi_value SetValueAsync(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
1116 {
1117     SETTING_LOG_INFO("set do c_b");
1118     napi_value resource = nullptr;
1119     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resource));
1120 
1121     napi_create_async_work(
1122         env,
1123         nullptr,
1124         resource,
1125         SetValueExecuteCB,
1126         [](napi_env env, napi_status status, void* data) {
1127             if (data == nullptr) {
1128                 SETTING_LOG_INFO("c_b set asy end data is null");
1129                 return;
1130             }
1131             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1132             napi_value undefine;
1133             napi_get_undefined(env, &undefine);
1134             napi_value callback = nullptr;
1135             napi_value result = wrap_bool_to_js(env, ThrowError(env, asyncCallbackInfo->status));
1136             napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
1137             napi_call_function(env, nullptr, callback, 1, &result, &undefine);
1138             napi_delete_reference(env, asyncCallbackInfo->callbackRef);
1139             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1140             asyncCallbackInfo->dataAbilityHelper = nullptr;
1141             delete asyncCallbackInfo;
1142             SETTING_LOG_INFO("c_b set change complete");
1143         },
1144         (void*)asyncCallbackInfo,
1145         &asyncCallbackInfo->asyncWork
1146     );
1147     NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1148     SETTING_LOG_INFO("c_b set end asy work");
1149     return wrap_void_to_js(env);
1150 }
1151 
SetValuePromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1152 napi_value SetValuePromise(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
1153 {
1154     SETTING_LOG_INFO("set do promise");
1155     napi_value promise;
1156     napi_deferred deferred;
1157     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1158     asyncCallbackInfo->deferred = deferred;
1159 
1160     napi_value resource = nullptr;
1161     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resource));
1162 
1163     napi_create_async_work(
1164         env,
1165         nullptr,
1166         resource,
1167         SetValueExecuteCB,
1168         [](napi_env env, napi_status status, void* data) {
1169             AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1170             SETTING_LOG_INFO("p_m set end get c_b value is %{public}d",
1171                 asyncCallbackInfo->status);
1172             napi_value result = wrap_bool_to_js(env, ThrowError(env, asyncCallbackInfo->status));
1173             napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
1174             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1175             asyncCallbackInfo->dataAbilityHelper = nullptr;
1176             delete asyncCallbackInfo;
1177         },
1178         (void*)asyncCallbackInfo,
1179         &asyncCallbackInfo->asyncWork);
1180     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1181     return promise;
1182 }
1183 
1184 /**
1185  * @brief setValue NAPI implementation.
1186  *
1187  * @param env the environment that the Node-API call is invoked under
1188  * @param info the callback info passed into the callback function
1189  * @return napi_value the return value from NAPI C++ to JS for the module.
1190  */
napi_set_value(napi_env env,napi_callback_info info)1191 napi_value napi_set_value(napi_env env, napi_callback_info info)
1192 {
1193     SETTING_LOG_INFO("set  napi_set_value");
1194 
1195     // getValue api need 3 parameters when Promise mode and need 4 parameters when callback mode
1196     const size_t paramOfCallback = ARGS_FOUR;
1197 
1198     size_t argc = ARGS_FIVE;
1199     napi_value args[ARGS_FIVE] = {nullptr};
1200     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1201     if (argc != ARGS_THREE && argc != ARGS_FOUR && argc != ARGS_FIVE) {
1202         SETTING_LOG_ERROR(
1203             "set %{public}s, wrong number of arguments, expect 3 or 4 or 5 but get %{public}zd",
1204             __func__,
1205             argc);
1206         return wrap_void_to_js(env);
1207     }
1208 
1209     SETTING_LOG_INFO("set  arg count is %{public}zd", argc);
1210     // Check the value type of the arguments
1211     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1212         .env = env,
1213         .asyncWork = nullptr,
1214         .deferred = nullptr,
1215         .callbackRef = nullptr,
1216         .dataAbilityHelper = nullptr,
1217         .key = "",
1218         .value = "",
1219         .uri = "",
1220         .status = false,
1221     };
1222     SETTING_LOG_INFO("set  aft create aysnc call back info");
1223     napi_valuetype valueType;
1224     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
1225     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
1226     NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
1227     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1], type. String expected");
1228     NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
1229     NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2], type. String expected");
1230 
1231     // api9 napi_set_value_ext
1232     bool stageMode = false;
1233     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
1234     if (status == napi_ok) {
1235         SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
1236         return napi_set_value_ext(env, info, stageMode);
1237     }
1238 
1239     NAPIDataAbilityHelperWrapper* wrapper = nullptr;
1240     NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&wrapper)));
1241     if (wrapper != nullptr) {
1242         asyncCallbackInfo->dataAbilityHelper = wrapper->GetDataAbilityHelper();
1243     }
1244 
1245     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1246     asyncCallbackInfo->value = unwrap_string_from_js(env, args[PARAM2]);
1247     SETTING_LOG_INFO("set  input param is : (key %{public}s, value %{public}s)",
1248         asyncCallbackInfo->key.c_str(), asyncCallbackInfo->value.c_str());
1249 
1250     napi_value ret = nullptr;
1251     if (argc == paramOfCallback) {
1252         napi_create_reference(env, args[PARAM3], 1, &asyncCallbackInfo->callbackRef);
1253         ret = SetValueAsync(env, asyncCallbackInfo);
1254     } else {
1255         ret = SetValuePromise(env, asyncCallbackInfo);
1256     }
1257     SETTING_LOG_INFO("set  value end");
1258     return ret;
1259 }
1260 
napi_set_value_ext(napi_env env,napi_callback_info info,const bool stageMode)1261 napi_value napi_set_value_ext(napi_env env, napi_callback_info info, const bool stageMode)
1262 {
1263     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1264         .env = env,
1265         .asyncWork = nullptr,
1266         .deferred = nullptr,
1267         .callbackRef = nullptr,
1268         .dataAbilityHelper = nullptr,
1269         .key = "",
1270         .value = "",
1271         .uri = "",
1272         .status = false,
1273         .useSilent = false,
1274     };
1275 
1276     size_t argc = ARGS_FIVE;
1277     napi_value args[ARGS_FIVE] = {nullptr};
1278     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1279 
1280     asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode, "global", asyncCallbackInfo);
1281     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1282     asyncCallbackInfo->uri = unwrap_string_from_js(env, args[PARAM2]); //temp
1283     napi_value resource = nullptr;
1284     NAPI_CALL(env, napi_create_string_utf8(env, "napi_set_value_ext", NAPI_AUTO_LENGTH, &resource));
1285 
1286     // set call type and table name
1287     napi_valuetype valueType;
1288     if (argc == ARGS_THREE) {
1289         asyncCallbackInfo->callType = STAGE_PROMISE;
1290         asyncCallbackInfo->tableName = "global";
1291     } else if (argc == ARGS_FOUR) {
1292         NAPI_CALL(env, napi_typeof(env, args[PARAM3], &valueType));
1293         if (valueType == napi_string) {
1294             asyncCallbackInfo->tableName = unwrap_string_from_js(env, args[PARAM3]);
1295             if (IsTableNameInvalid(asyncCallbackInfo->tableName)) {
1296                 SETTING_LOG_ERROR("INVALID tableName [ARGS_FOUR]");
1297                 return wrap_void_to_js(env);
1298             } else {
1299                 asyncCallbackInfo->callType = STAGE_PROMISE_SPECIFIC;
1300             }
1301         } else {
1302             asyncCallbackInfo->callType = STAGE_CALLBACK;
1303             asyncCallbackInfo->tableName = "global";
1304         }
1305     } else if (argc == ARGS_FIVE) {
1306         asyncCallbackInfo->callType = STAGE_CALLBACK_SPECIFIC;
1307         asyncCallbackInfo->tableName = unwrap_string_from_js(env, args[PARAM4]);
1308     } else {
1309         asyncCallbackInfo->callType = INVALID_CALL;
1310     }
1311 
1312     // check whether invalid call
1313     if (asyncCallbackInfo->callType == INVALID_CALL) {
1314         SETTING_LOG_ERROR("INVALID CALL");
1315         return wrap_void_to_js(env);
1316     }
1317 
1318     if (asyncCallbackInfo->callType == STAGE_CALLBACK || asyncCallbackInfo->callType == STAGE_CALLBACK_SPECIFIC) {
1319         napi_create_reference(env, args[PARAM3], 1, &asyncCallbackInfo->callbackRef);
1320         napi_create_async_work(
1321             env,
1322             nullptr,
1323             resource,
1324             [](napi_env env, void* data) {
1325                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1326                 SetValueExecuteExt(env, (void*)asyncCallbackInfo, asyncCallbackInfo->uri);
1327             },
1328             [](napi_env env, napi_status status, void* data) {
1329                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1330                 napi_value result = wrap_bool_to_js(env, ThrowError(env, asyncCallbackInfo->status));
1331                 asyncCallbackInfo->status = napi_ok;
1332                 CompleteCall(env, status, data, result);
1333             },
1334             (void*)asyncCallbackInfo,
1335             &asyncCallbackInfo->asyncWork
1336         );
1337         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1338         SETTING_LOG_INFO("c_b end async work");
1339         return wrap_void_to_js(env);
1340     } else if (asyncCallbackInfo->callType != INVALID_CALL) {
1341         napi_value promise;
1342         napi_deferred deferred;
1343         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1344         asyncCallbackInfo->deferred = deferred;
1345         napi_create_async_work(
1346             env,
1347             nullptr,
1348             resource,
1349             [](napi_env env, void* data) {
1350                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1351                 SETTING_LOG_INFO("in async work");
1352                 SetValueExecuteExt(env, (void*)asyncCallbackInfo, asyncCallbackInfo->uri);
1353             },
1354             [](napi_env env, napi_status status, void* data) {
1355                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1356                 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
1357                 asyncCallbackInfo->status = napi_ok;
1358                 CompletePromise(env, status, data, result);
1359             },
1360             (void*)asyncCallbackInfo,
1361             &asyncCallbackInfo->asyncWork
1362         );
1363         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1364         return promise;
1365     } else {
1366         SETTING_LOG_ERROR("INVALID CALL");
1367         return wrap_void_to_js(env);
1368     }
1369 }
1370 /**
1371  * @brief enableAirplaneMode NAPI implementation.
1372  * @param env the environment that the Node-API call is invoked under
1373  * @param info the callback info passed into the callback function
1374  * @return napi_value the return value from NAPI C++ to JS for the module.
1375  */
napi_enable_airplane_mode(napi_env env,napi_callback_info info)1376 napi_value napi_enable_airplane_mode(napi_env env, napi_callback_info info)
1377 {
1378     const size_t paramOfPromise = ARGS_ONE;
1379     const size_t paramOfCallback = ARGS_TWO;
1380 
1381     size_t argc = ARGS_TWO;
1382     napi_value args[ARGS_TWO] = {nullptr};
1383     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1384     if (argc != paramOfCallback && argc != paramOfPromise) {
1385         SETTING_LOG_ERROR("%{public}s, wrong number of arguments, expect 1 or 2 but get %{public}zd",
1386             __func__, argc);
1387         return wrap_void_to_js(env);
1388     }
1389 
1390     SETTING_LOG_INFO("n_e_a_m arg count is %{public}zd", argc);
1391     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1392         .env = env,
1393         .asyncWork = nullptr,
1394         .deferred = nullptr,
1395         .callbackRef = nullptr,
1396         .dataAbilityHelper = nullptr,
1397         .key = "",
1398         .value = "",
1399         .uri = "",
1400         .status = 0,
1401     };
1402     SETTING_LOG_INFO("aft create aysnc call back info");
1403 
1404     napi_valuetype valueType;
1405     NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
1406     NAPI_ASSERT(env, valueType == napi_boolean, "Wrong argument[0], type. Boolean expected");
1407 
1408     napi_value resource = nullptr;
1409     NAPI_CALL(env, napi_create_string_utf8(env, "enableAirplaneMode", NAPI_AUTO_LENGTH, &resource));
1410 
1411     if (argc == paramOfCallback) {
1412         SETTING_LOG_INFO("%{public}s, asyncCallback.", __func__);
1413 
1414         napi_create_reference(env, args[PARAM1], 1, &asyncCallbackInfo->callbackRef);
1415         napi_create_async_work(
1416             env,
1417             nullptr,
1418             resource,
1419             [](napi_env env, void* data) {},
1420             [](napi_env env, napi_status status, void* data) {
1421                 if (data == nullptr) {
1422                     SETTING_LOG_INFO("c_b asy end data is null");
1423                     return;
1424                 }
1425                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1426 
1427                 napi_value callback = nullptr;
1428                 napi_value undefined;
1429                 napi_get_undefined(env, &undefined);
1430 
1431                 napi_value result[PARAM2] = {0};
1432 
1433                 // create error code
1434                 napi_value error = nullptr;
1435                 napi_create_object(env, &error);
1436                 int unSupportCode = 801;
1437                 napi_value errCode = nullptr;
1438                 napi_create_int32(env, unSupportCode, &errCode);
1439                 napi_set_named_property(env, error, "code", errCode);
1440                 result[0] = error;
1441                 napi_get_undefined(env, &result[1]);
1442 
1443                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
1444                 napi_value callResult;
1445                 napi_call_function(env, undefined, callback, PARAM2, result, &callResult);
1446 
1447                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
1448                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1449                 delete asyncCallbackInfo;
1450                 SETTING_LOG_INFO("c_b change c_b complete");
1451             },
1452             (void*)asyncCallbackInfo,
1453             &asyncCallbackInfo->asyncWork
1454         );
1455         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1456         return wrap_void_to_js(env);
1457     } else {
1458         SETTING_LOG_INFO("%{public}s, promise.", __func__);
1459         napi_deferred deferred;
1460         napi_value promise;
1461         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1462         asyncCallbackInfo->deferred = deferred;
1463 
1464         napi_create_async_work(
1465             env,
1466             nullptr,
1467             resource,
1468             [](napi_env env, void *data) {},
1469             [](napi_env env, napi_status status, void *data) {
1470                 SETTING_LOG_INFO("%{public}s, promise complete", __func__);
1471                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1472 
1473                 napi_value result;
1474                 napi_value error = nullptr;
1475                 napi_create_object(env, &error);
1476                 int unSupportCode = 801;
1477                 napi_value errCode = nullptr;
1478                 napi_create_int32(env, unSupportCode, &errCode);
1479                 napi_set_named_property(env, error, "code", errCode);
1480                 result = error;
1481 
1482                 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1483                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1484                 delete asyncCallbackInfo;
1485             },
1486             (void *)asyncCallbackInfo,
1487             &asyncCallbackInfo->asyncWork);
1488         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1489         return promise;
1490     }
1491 }
1492 
1493 /**
1494  * @brief canShowFloating NAPI implementation.
1495  * @param env the environment that the Node-API call is invoked under
1496  * @param info the callback info passed into the callback function
1497  * @return napi_value the return value from NAPI C++ to JS for the module.
1498  */
napi_can_show_floating(napi_env env,napi_callback_info info)1499 napi_value napi_can_show_floating(napi_env env, napi_callback_info info)
1500 {
1501     const size_t paramOfPromise = PARAM0;
1502     const size_t paramOfCallback = PARAM1;
1503 
1504     size_t argc = PARAM1;
1505     napi_value args[PARAM1] = {nullptr};
1506     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1507     if (argc != paramOfCallback && argc != paramOfPromise) {
1508         SETTING_LOG_ERROR("%{public}s, wrong number of arguments, expect 0 or 1 but get %{public}zd",
1509             __func__, argc);
1510         return wrap_void_to_js(env);
1511     }
1512 
1513     SETTING_LOG_INFO("n_e_a_m arg count is %{public}zd", argc);
1514     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1515         .env = env,
1516         .asyncWork = nullptr,
1517         .deferred = nullptr,
1518         .callbackRef = nullptr,
1519         .dataAbilityHelper = nullptr,
1520         .key = "",
1521         .value = "",
1522         .uri = "",
1523         .status = 0,
1524     };
1525 
1526     napi_value resource = nullptr;
1527     NAPI_CALL(env, napi_create_string_utf8(env, "enableAirplaneMode", NAPI_AUTO_LENGTH, &resource));
1528 
1529     if (argc == paramOfCallback) {
1530         SETTING_LOG_INFO("%{public}s, a_C_B.", __func__);
1531 
1532         napi_create_reference(env, args[PARAM0], 1, &asyncCallbackInfo->callbackRef);
1533         napi_create_async_work(
1534             env,
1535             nullptr,
1536             resource,
1537             [](napi_env env, void* data) {},
1538             [](napi_env env, napi_status status, void* data) {
1539                 if (data == nullptr) {
1540                     SETTING_LOG_INFO("c_b asy end data is null");
1541                     return;
1542                 }
1543                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1544 
1545                 napi_value callback = nullptr;
1546                 napi_value undefined;
1547                 napi_get_undefined(env, &undefined);
1548 
1549                 napi_value result[PARAM2] = {0};
1550 
1551                 // create error code
1552                 napi_value error = nullptr;
1553                 napi_create_object(env, &error);
1554                 int unSupportCode = 801;
1555                 napi_value errCode = nullptr;
1556                 napi_create_int32(env, unSupportCode, &errCode);
1557                 napi_set_named_property(env, error, "code", errCode);
1558                 result[0] = error;
1559                 result[1] = wrap_bool_to_js(env, false);
1560 
1561                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
1562                 napi_value callResult;
1563                 napi_call_function(env, undefined, callback, PARAM2, result, &callResult);
1564 
1565                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
1566                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1567                 delete asyncCallbackInfo;
1568                 SETTING_LOG_INFO("c_b change complete");
1569             },
1570             (void*)asyncCallbackInfo,
1571             &asyncCallbackInfo->asyncWork
1572         );
1573         NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1574         return wrap_void_to_js(env);
1575     } else {
1576         SETTING_LOG_INFO("%{public}s, promise.", __func__);
1577         napi_deferred deferred;
1578         napi_value promise;
1579         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1580         asyncCallbackInfo->deferred = deferred;
1581 
1582         napi_create_async_work(
1583             env,
1584             nullptr,
1585             resource,
1586             [](napi_env env, void *data) {},
1587             [](napi_env env, napi_status status, void *data) {
1588                 SETTING_LOG_INFO("%{public}s, promise complete", __func__);
1589                 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1590 
1591                 napi_value result;
1592                 napi_value error = nullptr;
1593                 napi_create_object(env, &error);
1594                 int unSupportCode = 801;
1595                 napi_value errCode = nullptr;
1596                 napi_create_int32(env, unSupportCode, &errCode);
1597                 napi_set_named_property(env, error, "code", errCode);
1598                 result = error;
1599 
1600                 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1601                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1602                 delete asyncCallbackInfo;
1603             },
1604             (void *)asyncCallbackInfo,
1605             &asyncCallbackInfo->asyncWork);
1606         napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1607         return promise;
1608     }
1609 }
1610 
1611 // get uri for stage model
GetStageUriStr(std::string tableName,std::string idStr,std::string keyStr)1612 std::string GetStageUriStr(std::string tableName, std::string idStr, std::string keyStr)
1613 {
1614     if (std::stoi(idStr) < USERID_HELPER_NUMBER) {
1615         idStr = "100";
1616     }
1617     if (tableName == "global") {
1618         std::string retStr =
1619             "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + keyStr;
1620         return retStr;
1621     } else if (tableName == "system") {
1622         std::string retStr = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_" + idStr +
1623                              "?Proxy=true&key=" + keyStr;
1624         return retStr;
1625     } else if (tableName == "secure") {
1626         std::string retStr = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_" + idStr +
1627                              "?Proxy=true&key=" + keyStr;
1628         return retStr;
1629     } else {
1630         // return global uri
1631         std::string retStr =
1632             "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + keyStr;
1633         return retStr;
1634     }
1635 }
1636 
1637 // get proxy uri
GetProxyUriStr(std::string tableName,std::string idStr)1638 std::string GetProxyUriStr(std::string tableName, std::string idStr)
1639 {
1640     if (std::stoi(idStr) < USERID_HELPER_NUMBER) {
1641         idStr = "100";
1642     }
1643     if (tableName == "global") {
1644         // return global uri
1645         std::string retStr = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
1646         return retStr;
1647     } else if (tableName == "system") {
1648         std::string retStr =
1649             "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_" + idStr + "?Proxy=true";
1650         return retStr;
1651     } else {
1652         std::string retStr =
1653             "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_" + idStr + "?Proxy=true";
1654         return retStr;
1655     }
1656 }
1657 
1658 // check whether tableName is invalid, invalid -> true valid -> false
IsTableNameInvalid(std::string tableName)1659 bool IsTableNameInvalid(std::string tableName)
1660 {
1661     if (tableName != "global" && tableName != "system" && tableName != "secure") {
1662         return true;
1663     } else {
1664         return false;
1665     }
1666 }
1667 
napi_get_value_sync_ext(bool stageMode,size_t argc,napi_env env,napi_value * args)1668 napi_value napi_get_value_sync_ext(bool stageMode, size_t argc, napi_env env, napi_value* args)
1669 {
1670     SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
1671     AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo();
1672     if (asyncCallbackInfo == nullptr) {
1673         SETTING_LOG_ERROR("asyncCallbackInfo is null");
1674         return wrap_void_to_js(env);
1675     }
1676     napi_valuetype valueType;
1677 
1678     // define table name
1679     if (argc == ARGS_FOUR) {
1680         // check whether tableName is ok
1681         NAPI_CALL(env, napi_typeof(env, args[PARAM3], &valueType));
1682         if (valueType != napi_string) {
1683             SETTING_LOG_ERROR("tableName IS NOT STRING");
1684             return wrap_void_to_js(env);
1685         } else {
1686             asyncCallbackInfo->tableName = unwrap_string_from_js(env, args[PARAM3]);
1687             if (IsTableNameInvalid(asyncCallbackInfo->tableName)) {
1688                 SETTING_LOG_ERROR("INVALID tableName");
1689                 return wrap_void_to_js(env);
1690             }
1691         }
1692     } else {
1693         asyncCallbackInfo->tableName = "global";
1694     }
1695 
1696     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1697     asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode, asyncCallbackInfo->tableName);
1698     GetValueExecuteExt(env, (void *)asyncCallbackInfo);
1699     SETTING_LOG_INFO(
1700         "n_g_v return  %{public}s", asyncCallbackInfo->value.c_str());
1701     napi_value retVal = nullptr;
1702     if (asyncCallbackInfo->value.size() <= 0) {
1703         retVal = args[PARAM2];
1704         ThrowError(env, asyncCallbackInfo->status);
1705     } else {
1706         retVal = wrap_string_to_js(env, asyncCallbackInfo->value);
1707     }
1708     delete asyncCallbackInfo;
1709     return retVal;
1710 }
1711 
napi_set_value_sync_ext(bool stageMode,size_t argc,napi_env env,napi_value * args)1712 napi_value napi_set_value_sync_ext(bool stageMode, size_t argc, napi_env env, napi_value *args)
1713 {
1714     SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
1715     AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo();
1716     asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1717     napi_valuetype valueType;
1718 
1719     // define table name
1720     if (argc == ARGS_FOUR) {
1721         NAPI_CALL(env, napi_typeof(env, args[PARAM3], &valueType));
1722         if (valueType != napi_string) {
1723             SETTING_LOG_ERROR("tableName IS NOT STRING");
1724             return wrap_void_to_js(env);
1725         } else {
1726             asyncCallbackInfo->tableName = unwrap_string_from_js(env, args[PARAM3]);
1727             if (IsTableNameInvalid(asyncCallbackInfo->tableName)) {
1728                 SETTING_LOG_ERROR("INVALID tableName");
1729                 return wrap_void_to_js(env);
1730             }
1731         }
1732     } else {
1733         asyncCallbackInfo->tableName = "global";
1734     }
1735     asyncCallbackInfo->dataShareHelper = getDataShareHelper(
1736         env, args[PARAM0], stageMode, asyncCallbackInfo->tableName, asyncCallbackInfo);
1737     SetValueExecuteExt(env, (void *)asyncCallbackInfo, unwrap_string_from_js(env, args[PARAM2]));
1738     napi_value result = wrap_bool_to_js(env, ThrowError(env, asyncCallbackInfo->status));
1739     delete asyncCallbackInfo;
1740     return result;
1741 }
1742 
napi_register_key_observer(napi_env env,napi_callback_info info)1743 napi_value napi_register_key_observer(napi_env env, napi_callback_info info)
1744 {
1745     return npai_settings_register_observer(env, info);
1746 }
1747 
napi_unregister_key_observer(napi_env env,napi_callback_info info)1748 napi_value napi_unregister_key_observer(napi_env env, napi_callback_info info)
1749 {
1750     return npai_settings_unregister_observer(env, info);
1751 }
1752 }  // namespace Settings
1753 }  // namespace OHOS
1754