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