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