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