1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_settings.h"
17
18 #include <pthread.h>
19 #include <unistd.h>
20
21 #include "abs_shared_result_set.h"
22 #include "data_ability_helper.h"
23 #include "data_ability_predicates.h"
24 #include "napi_settings_log.h"
25 #include "values_bucket.h"
26
27 #include "napi_base_context.h"
28 #include "datashare_helper.h"
29 #include "datashare_predicates.h"
30
31
32 using namespace OHOS::AppExecFwk;
33 using namespace OHOS::DataShare;
34
35 namespace OHOS {
36 namespace Settings {
37 const std::string SETTINGS_DATA_BASE_URI = "dataability:///com.ohos.settingsdata.DataAbility";
38 const std::string SETTINGS_DATA_FIELD_KEYWORD = "KEYWORD";
39 const std::string SETTINGS_DATA_FIELD_VALUE = "VALUE";
40
41 /**
42 * @brief Wrap void to js value.
43 * ability_context
44 * @param env the environment that the Node-API call is invoked under
45 * @return napi_value napi_value after wrapped
46 */
wrap_void_to_js(napi_env env)47 napi_value wrap_void_to_js(napi_env env)
48 {
49 napi_value result = nullptr;
50 NAPI_CALL(env, napi_get_null(env, &result));
51 return result;
52 }
53
54 /**
55 * @brief Unwrap string from js value.
56 *
57 * @param env the environment that the Node-API call is invoked under
58 * @param param js value to unwrap
59 * @return std::string string value after unwrapped
60 */
unwrap_string_from_js(napi_env env,napi_value param)61 std::string unwrap_string_from_js(napi_env env, napi_value param)
62 {
63 std::string defaultValue("");
64
65 size_t size = 0;
66 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
67 return defaultValue;
68 }
69
70 if (size == 0) {
71 return defaultValue;
72 }
73
74 std::string value("");
75
76 char *buf = new (std::nothrow) char[size + 1];
77 if (buf == nullptr) {
78 SETTING_LOG_INFO("settingsnapi : unwarp");
79 return value;
80 }
81 memset_s(buf, size + 1, 0, size + 1);
82
83 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
84 if (rev) {
85 value = buf;
86 } else {
87 value = defaultValue;
88 }
89
90 delete[] buf;
91 buf = nullptr;
92 SETTING_LOG_INFO("settingsnapi : unwarp string is : %{public}s", value.c_str());
93 return value;
94 }
95
96 /**
97 * @brief Wrap string to js value.
98 *
99 * @param env the environment that the Node-API call is invoked under
100 * @param value string value to be wrap
101 * @return napi_value js value after wrapped
102 */
wrap_string_to_js(napi_env env,const std::string & value)103 napi_value wrap_string_to_js(napi_env env, const std::string &value)
104 {
105 napi_value result = nullptr;
106 NAPI_CALL(env, napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result));
107 return result;
108 }
109
110 /**
111 * @brief Wrap bool to js value.
112 *
113 * @param env the environment that the Node-API call is invoked under
114 * @param value bool value to be wrap
115 * @return napi_value js value after wrapped
116 */
wrap_bool_to_js(napi_env env,bool value)117 napi_value wrap_bool_to_js(napi_env env, bool value)
118 {
119 napi_value result = nullptr;
120 NAPI_CALL(env, napi_get_boolean(env, value, &result));
121 return result;
122 }
123
124 struct AsyncCallbackInfo {
125 napi_env env;
126 napi_async_work asyncWork;
127 napi_deferred deferred;
128 napi_ref callbackRef;
129 DataAbilityHelper *dataAbilityHelper;
130 std::string key;
131 std::string value;
132 std::string uri;
133 int status;
134 std::shared_ptr<DataShareHelper> dataShareHelper = nullptr;
135 };
136
137 /**
138 * @brief getUri NAPI implementation.
139 *
140 * @param env the environment that the Node-API call is invoked under
141 * @param info the callback info passed into the callback function
142 * @return napi_value the return value from NAPI C++ to JS for the module.
143 */
napi_get_uri_sync(napi_env env,napi_callback_info info)144 napi_value napi_get_uri_sync(napi_env env, napi_callback_info info)
145 {
146 SETTING_LOG_INFO("napi_get_uri called...");
147
148 napi_value retUri = nullptr;
149
150 // Check the number of the arguments
151 size_t argc = ARGS_ONE;
152 napi_value args[ARGS_ONE] = {nullptr};
153 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
154 if (argc != ARGS_ONE) {
155 SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
156 return wrap_void_to_js(env);
157 }
158
159 // Check the value type of the arguments
160 napi_valuetype valueType;
161 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
162 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument type. String expected.");
163
164 std::string uriArgStr = unwrap_string_from_js(env, args[PARAM0]);
165 uriArgStr = uriArgStr.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + uriArgStr);
166
167 retUri = wrap_string_to_js(env, uriArgStr);
168 return retUri;
169 }
170
napi_get_uri(napi_env env,napi_callback_info info)171 napi_value napi_get_uri(napi_env env, napi_callback_info info)
172 {
173 SETTING_LOG_INFO("settingsnapi : uri napi_set_value called...");
174 // Check the number of the arguments
175 size_t argc = ARGS_TWO;
176 napi_value args[ARGS_TWO] = {nullptr};
177 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
178 if (argc != ARGS_ONE && argc != ARGS_TWO) {
179 SETTING_LOG_ERROR("settingsnapi : uri %{public}s, wrong number of arguments, expect 1 or 2 but get %{public}zd",
180 __func__, argc);
181 return wrap_void_to_js(env);
182 }
183
184 SETTING_LOG_INFO("settingsnapi : uri arg count is %{public}zd", argc);
185 SETTING_LOG_INFO("settingsnapi : uri start create aysnc call back info");
186 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
187 .env = env,
188 .asyncWork = nullptr,
189 .deferred = nullptr,
190 .callbackRef = nullptr,
191 .dataAbilityHelper = nullptr,
192 .key = "",
193 .value = "",
194 .uri = "",
195 .status = false,
196 };
197
198 // Check the value type of the arguments
199 napi_valuetype valueType;
200 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
201 NAPI_ASSERT(env, valueType == napi_string, "settingsnapi : uri Wrong argument type. String expected.");
202
203 std::string uriArgStr = unwrap_string_from_js(env, args[PARAM0]);
204 uriArgStr = uriArgStr.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + uriArgStr);
205 asyncCallbackInfo->uri = uriArgStr;
206 SETTING_LOG_INFO("settingsnapi : uri after uri is %{public}s", asyncCallbackInfo->uri.c_str());
207 SETTING_LOG_INFO("settingsnapi : uri after create aysnc call back info");
208
209 napi_value resource = nullptr;
210 NAPI_CALL(env, napi_create_string_utf8(env, "getUri", NAPI_AUTO_LENGTH, &resource));
211
212 if (argc == 2) {
213 SETTING_LOG_INFO("settingsnapi : uri do callback");
214 napi_create_reference(env, args[PARAM1], 1, &asyncCallbackInfo->callbackRef);
215
216 napi_create_async_work(
217 env,
218 nullptr,
219 resource,
220 [](napi_env env, void* data) {
221 SETTING_LOG_INFO("settingsnapi : uri callback async execute callback");
222 },
223 [](napi_env env, napi_status status, void* data) {
224 if (data == nullptr) {
225 SETTING_LOG_INFO("settingsnapi : uri callback async end data is null");
226 return;
227 }
228 SETTING_LOG_INFO("settingsnapi : uri callback async end called callback");
229 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
230 napi_value undefine;
231 napi_get_undefined(env, &undefine);
232 napi_value callback = nullptr;
233 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->uri);
234 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
235 napi_call_function(env, nullptr, callback, 1, &result, &undefine);
236 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
237 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
238 delete asyncCallbackInfo;
239 SETTING_LOG_INFO("settingsnapi : uri callback change callback complete");
240 },
241 (void*)asyncCallbackInfo,
242 &asyncCallbackInfo->asyncWork
243 );
244
245 SETTING_LOG_INFO("settingsnapi : uri callback start async work");
246 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
247 SETTING_LOG_INFO("settingsnapi : uri callback end async work");
248 return wrap_void_to_js(env);
249 } else {
250 SETTING_LOG_INFO("settingsnapi : uri do promise");
251 napi_value promise;
252 napi_deferred deferred;
253 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
254 asyncCallbackInfo->deferred = deferred;
255
256 napi_create_async_work(
257 env,
258 nullptr,
259 resource,
260 // aysnc executed task
261 [](napi_env env, void* data) {
262 SETTING_LOG_INFO("settingsnapi : uri promise async execute callback");
263 },
264 // async end called callback
265 [](napi_env env, napi_status status, void* data) {
266 SETTING_LOG_INFO("settingsnapi : uri promise async end called callback");
267 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
268 SETTING_LOG_INFO("settingsnapi : uri promise end get callback value is %{public}s",
269 asyncCallbackInfo->uri.c_str());
270 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->uri);
271 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
272 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
273 delete asyncCallbackInfo;
274 },
275 (void*)asyncCallbackInfo,
276 &asyncCallbackInfo->asyncWork);
277 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
278 SETTING_LOG_INFO("settingsnapi: uri promise end sync work");
279 return promise;
280 }
281 }
282
getDataShareHelper(napi_env env,const napi_value context,const bool stageMode)283 std::shared_ptr<DataShareHelper> getDataShareHelper(napi_env env, const napi_value context, const bool stageMode)
284 {
285 std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
286 std::string strUri = "datashare:///com.ohos.settingsdata.DataAbility";
287 std::string strProxyUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
288 OHOS::Uri proxyUri(strProxyUri);
289 SETTING_LOG_INFO("getDataShareHelper called");
290 auto contextS = OHOS::AbilityRuntime::GetStageModeContext(env, context);
291
292 dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strProxyUri);
293 SETTING_LOG_INFO("getDataShareHelper called");
294
295 DataSharePredicates predicates;
296 predicates.Limit(1, 0);
297 std::vector<std::string> columns;
298 if (dataShareHelper == nullptr) {
299 SETTING_LOG_INFO("getDataShareHelper dataShareHelper = nullptr");
300 }
301 if (dataShareHelper == nullptr || dataShareHelper->Query(proxyUri, predicates, columns) == nullptr) {
302 dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(contextS->GetToken(), strUri);
303 return dataShareHelper;
304 }
305
306 return dataShareHelper;
307 }
308
GetValueExecuteExt(napi_env env,void * data)309 void GetValueExecuteExt(napi_env env, void *data)
310 {
311 if (data == nullptr) {
312 SETTING_LOG_INFO("settingsnapi : execute data is null");
313 return;
314 }
315
316 SETTING_LOG_INFO("settingsnapi : GetValueExecuteExt start");
317 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
318
319 std::vector<std::string> columns;
320 columns.push_back(SETTINGS_DATA_FIELD_VALUE);
321
322 OHOS::DataShare::DataSharePredicates predicates;
323 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
324
325 std::string strUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + asyncCallbackInfo->key;
326 OHOS::Uri uri(strUri);
327
328 std::shared_ptr<OHOS::DataShare::DataShareResultSet> resultset = nullptr;
329 if (asyncCallbackInfo->dataShareHelper != nullptr) {
330 resultset = asyncCallbackInfo->dataShareHelper->Query(uri, predicates, columns);
331 }
332 int numRows = 0;
333 if (resultset != nullptr) {
334 SETTING_LOG_INFO("settingsnapi : GetValueExecuteExt called... resultset is NOT empty");
335 resultset->GetRowCount(numRows);
336 }
337
338 if (resultset == nullptr || numRows == 0) {
339 SETTING_LOG_INFO("settingsnapi : GetValueExecuteExt called... return error");
340 asyncCallbackInfo->status = -1;
341 return;
342 }
343
344 std::string val;
345 int32_t columnIndex = 0;
346 resultset->GoToFirstRow();
347
348 resultset->GetString(columnIndex, val);
349 SETTING_LOG_INFO("napi_get_value_ext called... %{public}s", val.c_str());
350 asyncCallbackInfo->value = val;
351 asyncCallbackInfo->status = napi_ok;
352 }
353
DeleteCallbackInfo(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)354 void DeleteCallbackInfo(napi_env env, AsyncCallbackInfo *asyncCallbackInfo)
355 {
356 if (env != nullptr) {
357 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
358 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
359 }
360 asyncCallbackInfo->dataShareHelper = nullptr;
361 delete asyncCallbackInfo;
362 }
363
CompleteCall(napi_env env,napi_status status,void * data,const napi_value retVaule)364 void CompleteCall(napi_env env, napi_status status, void *data, const napi_value retVaule)
365 {
366 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
367 napi_value result[PARAM2] = {0};
368 if (status == napi_ok && asyncCallbackInfo->status == napi_ok) {
369 napi_get_undefined(env, &result[PARAM0]);
370 result[PARAM1] = retVaule;
371 } else {
372 napi_value message = nullptr;
373 napi_create_string_utf8(env, "async call failed", NAPI_AUTO_LENGTH, &message);
374 napi_create_error(env, nullptr, message, &result[PARAM0]);
375 napi_get_undefined(env, &result[PARAM1]);
376 }
377 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
378 napi_value callback = nullptr;
379 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
380 napi_value returnValue;
381 napi_call_function(env, nullptr, callback, PARAM2, result, &returnValue);
382 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
383 DeleteCallbackInfo(env, asyncCallbackInfo);
384 SETTING_LOG_INFO("settingsnapi : callback change callback complete");
385 }
386
CompletePromise(napi_env env,napi_status status,void * data,const napi_value retVaule)387 void CompletePromise(napi_env env, napi_status status, void *data, const napi_value retVaule)
388 {
389 SETTING_LOG_INFO("settingsnapi : promise async end called callback");
390 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
391 napi_value result = nullptr;
392 if (status == napi_ok && asyncCallbackInfo->status == napi_ok) {
393 napi_resolve_deferred(env, asyncCallbackInfo->deferred, retVaule);
394 } else {
395 napi_get_undefined(env, &result);
396 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
397 }
398 DeleteCallbackInfo(env, asyncCallbackInfo);
399 }
400
SetValueExecuteExt(napi_env env,void * data,const std::string setValue)401 void SetValueExecuteExt(napi_env env, void *data, const std::string setValue)
402 {
403 if (data == nullptr) {
404 SETTING_LOG_INFO("settingsnapi : SetValueExecuteExt data is null");
405 return;
406 }
407 SETTING_LOG_INFO("settingsnapi : execute start");
408 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
409
410 OHOS::DataShare::DataShareValuesBucket val;
411 val.Put(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
412 val.Put(SETTINGS_DATA_FIELD_VALUE, setValue);
413
414 std::string strUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=" + asyncCallbackInfo->key;
415 SETTING_LOG_INFO("strUri = %{public}s", strUri.c_str());
416 OHOS::Uri uri(strUri);
417
418 OHOS::DataShare::DataSharePredicates predicates;
419 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
420
421 int retInt = 0;
422 if (asyncCallbackInfo->status == -1 || asyncCallbackInfo->value.size() <= 0) {
423 SETTING_LOG_INFO("napi_set_value_ext called... before Insert");
424 if (asyncCallbackInfo->dataShareHelper != nullptr) {
425 retInt = asyncCallbackInfo->dataShareHelper->Insert(uri, val);
426 }
427 SETTING_LOG_INFO("napi_set_value_ext called... after Insert");
428 } else {
429 SETTING_LOG_INFO("napi_set_value_ext called... before Update");
430 if (asyncCallbackInfo->dataShareHelper != nullptr) {
431 retInt = asyncCallbackInfo->dataShareHelper->Update(uri, predicates, val);
432 }
433 SETTING_LOG_INFO("napi_set_value_ext called... after Update");
434 }
435 asyncCallbackInfo->status = retInt;
436 }
437
438 /**
439 * @brief getValue NAPI implementation.
440 *
441 * @param env the environment that the Node-API call is invoked under
442 * @param info the callback info passed into the callback function
443 * @return napi_value the return value from NAPI C++ to JS for the module.
444 */
napi_get_value_sync(napi_env env,napi_callback_info info)445 napi_value napi_get_value_sync(napi_env env, napi_callback_info info)
446 {
447 SETTING_LOG_INFO("napi_get_value called...");
448
449 // Check the number of the arguments
450 size_t argc = ARGS_THREE;
451 napi_value args[ARGS_THREE] = {nullptr};
452 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
453 if (argc != ARGS_THREE) {
454 SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
455 return wrap_void_to_js(env);
456 }
457
458 // Check the value type of the arguments
459 napi_valuetype valueType;
460 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
461 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
462 NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
463 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected.");
464 NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
465 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected.");
466
467 bool stageMode = false;
468 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
469 if (status == napi_ok) {
470 SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
471 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
472 asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
473 std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
474 asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
475 GetValueExecuteExt(env, (void*)asyncCallbackInfo);
476 SETTING_LOG_INFO("settingsnapi : napi_get_value_sync called... return %{public}s",
477 asyncCallbackInfo->value.c_str());
478 napi_value retVal = nullptr;
479 if(asyncCallbackInfo->value.size() <= 0){
480 retVal = args[PARAM2];
481 } else {
482 retVal = wrap_string_to_js(env, asyncCallbackInfo->value);
483 }
484 delete asyncCallbackInfo;
485 return retVal;
486 }
487
488 std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
489 DataAbilityHelper *dataAbilityHelper = nullptr;
490 NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&dataAbilityHelper)));
491
492 std::vector<std::string> columns;
493 columns.push_back(SETTINGS_DATA_FIELD_VALUE);
494 OHOS::NativeRdb::DataAbilityPredicates predicates;
495 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, unwrap_string_from_js(env, args[PARAM1]));
496
497 SETTING_LOG_INFO("napi_get_value called... before dataAbilityHelper->Query");
498 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset =
499 dataAbilityHelper->Query(*uri, columns, predicates);
500 SETTING_LOG_INFO("napi_get_value called... after dataAbilityHelper->Query");
501
502 napi_value retVal = nullptr;
503 int numRows = 0;
504
505 if (resultset != nullptr) {
506 SETTING_LOG_INFO("napi_get_value called... resultset is NOT empty");
507 resultset->GetRowCount(numRows);
508 }
509
510 if (resultset == nullptr || numRows == 0) {
511 SETTING_LOG_INFO("napi_get_value called... return default value");
512 retVal = args[PARAM2];
513 } else {
514 SETTING_LOG_INFO("napi_get_value called... return value from resultset");
515 std::string val;
516 int32_t columnIndex = 0;
517 resultset->GoToFirstRow();
518 resultset->GetString(columnIndex, val);
519 retVal = wrap_string_to_js(env, val);
520 }
521
522 if (resultset != nullptr) {
523 resultset->Close();
524 }
525 dataAbilityHelper = nullptr;
526 SETTING_LOG_INFO("napi_get_value called... END!");
527 return retVal;
528 }
529
napi_get_value(napi_env env,napi_callback_info info)530 napi_value napi_get_value(napi_env env, napi_callback_info info)
531 {
532 // getValue api need 3 parameters when Promise mode and need 4 parameters when callback mode
533 const size_t paramOfPromise = ARGS_TWO;
534 const size_t paramOfCallback = ARGS_THREE;
535
536 size_t argc = ARGS_THREE;
537 napi_value args[ARGS_THREE] = {nullptr};
538 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
539 if (argc != paramOfCallback && argc != paramOfPromise) {
540 SETTING_LOG_ERROR("settingsnapi : %{public}s, wrong number of arguments, expect 2 or 3 but get %{public}zd",
541 __func__, argc);
542 return wrap_void_to_js(env);
543 }
544
545 SETTING_LOG_INFO("settingsnapi : napi_get_value arg count is %{public}zd", argc);
546 SETTING_LOG_INFO("settingsnapi : napi_get_value start create aysnc call back info");
547 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
548 .env = env,
549 .asyncWork = nullptr,
550 .deferred = nullptr,
551 .callbackRef = nullptr,
552 .dataAbilityHelper = nullptr,
553 .key = "",
554 .value = "",
555 .uri = "",
556 .status = false,
557 };
558 SETTING_LOG_INFO("settingsnapi : after create aysnc call back info");
559 // Check the value type of the arguments
560 napi_valuetype valueType;
561 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
562
563 bool stageMode = false;
564 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
565 if (status == napi_ok) {
566 SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
567 return napi_get_value_ext(env, info, stageMode);
568 }
569
570 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
571 NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
572 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1], type. String expected");
573
574 NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&asyncCallbackInfo->dataAbilityHelper)));
575 SETTING_LOG_INFO("settingsnapi : input paramter is (DataAbilityHelper)");
576
577 asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
578 SETTING_LOG_INFO("settingsnapi : input parameter is : (key %{public}s", asyncCallbackInfo->key.c_str());
579
580 napi_value resource = nullptr;
581 NAPI_CALL(env, napi_create_string_utf8(env, "getValue", NAPI_AUTO_LENGTH, &resource));
582
583 if (argc == paramOfCallback) {
584 SETTING_LOG_INFO("settingsnapi : do callback");
585
586 napi_create_reference(env, args[PARAM2], 1, &asyncCallbackInfo->callbackRef);
587
588 napi_create_async_work(
589 env,
590 nullptr,
591 resource,
592 // aysnc executed task
593 [](napi_env env, void* data) {
594 if (data == nullptr) {
595 SETTING_LOG_INFO("settingsnapi : callback async execute data is null");
596 return;
597 }
598 SETTING_LOG_INFO("settingsnapi : callback async execute callback");
599 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
600
601 std::vector<std::string> columns;
602 columns.push_back(SETTINGS_DATA_FIELD_VALUE);
603 OHOS::NativeRdb::DataAbilityPredicates predicates;
604 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
605
606 std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
607 SETTING_LOG_INFO("settingsnapi : callback napi_get_value called... before dataAbilityHelper->Query");
608 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset =
609 asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
610 SETTING_LOG_INFO("settingsnapi : callback napi_get_value called... after dataAbilityHelper->Query");
611
612 int numRows = 0;
613 if (resultset != nullptr) {
614 SETTING_LOG_INFO("settingsnapi : callback napi_get_value called... resultset is NOT empty");
615 resultset->GetRowCount(numRows);
616 }
617 if (resultset == nullptr || numRows == 0) {
618 SETTING_LOG_INFO("settingsnapi : callback napi_get_value called... return default value");
619 } else {
620 SETTING_LOG_INFO("settingsnapi : callback napi_get_value called... return value from resultset");
621 std::string val;
622 int32_t columnIndex = 0;
623 resultset->GoToFirstRow();
624 resultset->GetString(columnIndex, val);
625 SETTING_LOG_INFO("settingsnapi : callback retVal is %{public}s", val.c_str());
626 asyncCallbackInfo->value = val;
627 }
628 if (resultset != nullptr) {
629 resultset->Close();
630 }
631 },
632 // async end called callback
633 [](napi_env env, napi_status status, void* data) {
634 if (data == nullptr) {
635 SETTING_LOG_INFO("settingsnapi : callback async end data is null");
636 return;
637 }
638 SETTING_LOG_INFO("settingsnapi : callback async end called callback");
639 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
640 napi_value undefine;
641 napi_get_undefined(env, &undefine);
642 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
643 napi_value callback = nullptr;
644 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
645 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
646 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
647 napi_call_function(env, nullptr, callback, 1, &result, &undefine);
648 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
649 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
650 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
651 asyncCallbackInfo->dataAbilityHelper = nullptr;
652 delete asyncCallbackInfo;
653 SETTING_LOG_INFO("settingsnapi : callback change callback complete");
654 },
655 (void*)asyncCallbackInfo,
656 &asyncCallbackInfo->asyncWork
657 );
658
659 SETTING_LOG_INFO("settingsnapi : callback start async work");
660 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
661 SETTING_LOG_INFO("settingsnapi : callback end async work");
662 return wrap_void_to_js(env);
663 } else {
664 SETTING_LOG_INFO("settingsnapi : do promise");
665 napi_value promise;
666 napi_deferred deferred;
667 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
668 asyncCallbackInfo->deferred = deferred;
669
670 napi_create_async_work(
671 env,
672 nullptr,
673 resource,
674 // aysnc executed task
675 [](napi_env env, void* data) {
676 SETTING_LOG_INFO("settingsnapi : promise async execute callback");
677 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
678 SETTING_LOG_INFO("settingsnapi : promise get callback key is %{public}s", asyncCallbackInfo->key.c_str());
679 SETTING_LOG_INFO("settingsnapi : promise get callback value is %{public}s",
680 asyncCallbackInfo->value.c_str());
681
682 std::vector<std::string> columns;
683 columns.push_back(SETTINGS_DATA_FIELD_VALUE);
684 OHOS::NativeRdb::DataAbilityPredicates predicates;
685 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, asyncCallbackInfo->key);
686
687 std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
688 SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... before dataAbilityHelper->Query");
689 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset =
690 asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
691 SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... after dataAbilityHelper->Query");
692
693 int numRows = 0;
694 if (resultset != nullptr) {
695 SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... resultset is NOT empty");
696 resultset->GetRowCount(numRows);
697 }
698 if (resultset == nullptr || numRows == 0) {
699 SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... return default value");
700 } else {
701 SETTING_LOG_INFO("settingsnapi : promise napi_get_value called... return value from resultset");
702 std::string val;
703 int32_t columnIndex = 0;
704 resultset->GoToFirstRow();
705 resultset->GetString(columnIndex, val);
706 asyncCallbackInfo->value = val;
707 }
708 if (resultset != nullptr) {
709 resultset->Close();
710 }
711 },
712 // async end called callback
713 [](napi_env env, napi_status status, void* data) {
714 SETTING_LOG_INFO("settingsnapi : promise async end called callback");
715 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
716 SETTING_LOG_INFO("settingsnapi : promise end get callback value is %{public}s",
717 asyncCallbackInfo->value.c_str());
718 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
719 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
720 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
721 asyncCallbackInfo->dataAbilityHelper = nullptr;
722 delete asyncCallbackInfo;
723 },
724 (void*)asyncCallbackInfo,
725 &asyncCallbackInfo->asyncWork);
726 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
727 return promise;
728 }
729 }
730
731 // api9
napi_get_value_ext(napi_env env,napi_callback_info info,const bool stageMode)732 napi_value napi_get_value_ext(napi_env env, napi_callback_info info, const bool stageMode)
733 {
734 SETTING_LOG_INFO("settingsnapi : napi_get_value_ext start");
735 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
736 .env = env,
737 .asyncWork = nullptr,
738 .deferred = nullptr,
739 .callbackRef = nullptr,
740 .dataAbilityHelper = nullptr,
741 .key = "",
742 .value = "",
743 .uri = "",
744 .status = false,
745 };
746
747 SETTING_LOG_INFO("napi_get_value_ext called");
748 size_t argc = ARGS_THREE;
749 napi_value args[ARGS_THREE] = {nullptr};
750 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
751 std::string strUri = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
752 OHOS::Uri uri(strUri);
753
754 std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
755 asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
756
757 asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
758
759 napi_value resource = nullptr;
760 NAPI_CALL(env, napi_create_string_utf8(env, "getValue", NAPI_AUTO_LENGTH, &resource));
761
762 if (argc == ARGS_THREE) {
763 napi_create_reference(env, args[PARAM2], 1, &asyncCallbackInfo->callbackRef);
764 napi_create_async_work(
765 env,
766 nullptr,
767 resource,
768 GetValueExecuteExt,
769 [](napi_env env, napi_status status, void* data) {
770 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
771 napi_value result = wrap_string_to_js(env, asyncCallbackInfo->value);
772 CompleteCall(env, status, data, result);
773 },
774 (void*)asyncCallbackInfo,
775 &asyncCallbackInfo->asyncWork
776 );
777 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
778 SETTING_LOG_INFO("settingsnapi : callback end async work");
779 return wrap_void_to_js(env);
780 } else {
781 napi_value promise;
782 napi_deferred deferred;
783 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
784 asyncCallbackInfo->deferred = deferred;
785 napi_create_async_work(
786 env,
787 nullptr,
788 resource,
789 GetValueExecuteExt,
790 [](napi_env env, napi_status status, void* data) {
791 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
792 napi_value result = nullptr;
793 result = wrap_string_to_js(env, asyncCallbackInfo->value);
794 CompletePromise(env, status, data, result);
795 },
796 (void*)asyncCallbackInfo,
797 &asyncCallbackInfo->asyncWork
798 );
799 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
800 return promise;
801 }
802 }
803
804
805 /**
806 * @brief setValue NAPI implementation.
807 *
808 * @param env the environment that the Node-API call is invoked under
809 * @param info the callback info passed into the callback function
810 * @return napi_value the return value from NAPI C++ to JS for the module.
811 */
napi_set_value_sync(napi_env env,napi_callback_info info)812 napi_value napi_set_value_sync(napi_env env, napi_callback_info info)
813 {
814 SETTING_LOG_INFO("napi_set_value called...");
815
816 // Check the number of the arguments
817 size_t argc = ARGS_THREE;
818 napi_value args[ARGS_THREE] = {nullptr};
819 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
820 if (argc != ARGS_THREE) {
821 SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__);
822 return wrap_void_to_js(env);
823 }
824
825 // Check the value type of the arguments
826 napi_valuetype valueType;
827 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
828 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
829 NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
830 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected.");
831 NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
832 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected.");
833
834 bool stageMode = false;
835 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
836 if (status == napi_ok) {
837 SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
838 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
839 asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
840 std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr;
841 asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
842 GetValueExecuteExt(env, (void*)asyncCallbackInfo);
843 SetValueExecuteExt(env, (void*)asyncCallbackInfo, unwrap_string_from_js(env, args[PARAM2]));
844 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
845 delete asyncCallbackInfo;
846 return result;
847 }
848
849 DataAbilityHelper *dataAbilityHelper = nullptr;
850 NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&dataAbilityHelper)));
851
852 std::string argsName = unwrap_string_from_js(env, args[PARAM1]);
853 std::string argsDefaultValue = unwrap_string_from_js(env, args[PARAM2]);
854
855 OHOS::NativeRdb::ValuesBucket val;
856 val.PutString(SETTINGS_DATA_FIELD_KEYWORD, argsName);
857 val.PutString(SETTINGS_DATA_FIELD_VALUE, argsDefaultValue);
858
859 std::vector<std::string> columns;
860 columns.push_back(SETTINGS_DATA_FIELD_VALUE);
861 OHOS::NativeRdb::DataAbilityPredicates predicates;
862 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, argsName);
863
864 std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
865 SETTING_LOG_INFO("napi_set_value called... before dataAbilityHelper->Query");
866 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset =
867 dataAbilityHelper->Query(*uri, columns, predicates);
868 SETTING_LOG_INFO("napi_set_value called... after dataAbilityHelper->Query");
869
870 int retInt = 0;
871 int numRows = 0;
872
873 if (resultset != nullptr) {
874 SETTING_LOG_INFO("napi_set_value called... resultset is NOT empty");
875 resultset->GetRowCount(numRows);
876 }
877
878 // insert
879 if (resultset == nullptr || numRows == 0) {
880 SETTING_LOG_INFO("napi_set_value called... before Insert");
881 retInt = dataAbilityHelper->Insert(*uri, val);
882 SETTING_LOG_INFO("napi_set_value called... after Insert");
883 // update
884 } else {
885 SETTING_LOG_INFO("napi_set_value called... before Update");
886 retInt = dataAbilityHelper->Update(*uri, val, predicates);
887 SETTING_LOG_INFO("napi_set_value called... after Update");
888 }
889 // notify change
890 if (retInt != 0) {
891 SETTING_LOG_INFO("napi_set_value called... retInt is NOT zero");
892 std::string uriWithNameStr =
893 argsName.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + argsName);
894 std::shared_ptr<Uri> uriWithName = std::make_shared<Uri>(uriWithNameStr);
895 dataAbilityHelper->NotifyChange(*uriWithName);
896 SETTING_LOG_INFO("napi_set_value called... after NotifyChange with uri: %{public}s", uriWithNameStr.c_str());
897 }
898
899 if (resultset != nullptr) {
900 resultset->Close();
901 }
902
903 SETTING_LOG_INFO("napi_set_value called... END!");
904 return wrap_bool_to_js(env, retInt != 0);
905 }
906
SetValueExecuteCB(napi_env env,void * data)907 void SetValueExecuteCB(napi_env env, void *data)
908 {
909 if (data == nullptr) {
910 SETTING_LOG_INFO("settingsnapi : execute data is null");
911 return;
912 }
913 SETTING_LOG_INFO("settingsnapi : execute start");
914 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
915
916 std::string argsName = asyncCallbackInfo->key;
917 std::string argsDefaultValue = asyncCallbackInfo->value;
918
919 OHOS::NativeRdb::ValuesBucket val;
920 val.PutString(SETTINGS_DATA_FIELD_KEYWORD, argsName);
921 val.PutString(SETTINGS_DATA_FIELD_VALUE, argsDefaultValue);
922
923 std::vector<std::string> columns;
924 columns.push_back(SETTINGS_DATA_FIELD_VALUE);
925 OHOS::NativeRdb::DataAbilityPredicates predicates;
926 predicates.EqualTo(SETTINGS_DATA_FIELD_KEYWORD, argsName);
927
928 std::shared_ptr<Uri> uri = std::make_shared<Uri>(SETTINGS_DATA_BASE_URI);
929 SETTING_LOG_INFO("settingsnapi : execute... before dataAbilityHelper->Query");
930 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultset =
931 asyncCallbackInfo->dataAbilityHelper->Query(*uri, columns, predicates);
932 SETTING_LOG_INFO("settingsnapi : execute... after dataAbilityHelper->Query");
933
934 int retInt = 0;
935 int numRows = 0;
936 if (resultset != nullptr) {
937 SETTING_LOG_INFO("settingsnapi : execute... resultset is NOT empty");
938 resultset->GetRowCount(numRows);
939 }
940 // insert
941 if (resultset == nullptr || numRows == 0) {
942 SETTING_LOG_INFO("settingsnapi : execute... before Insert");
943 retInt = asyncCallbackInfo->dataAbilityHelper->Insert(*uri, val);
944 SETTING_LOG_INFO("settingsnapi : execute... after Insert");
945 // update
946 } else {
947 SETTING_LOG_INFO("settingsnapi : execute... before Update");
948 retInt = asyncCallbackInfo->dataAbilityHelper->Update(*uri, val, predicates);
949 SETTING_LOG_INFO("settingsnapi : execute... after Update");
950 }
951 // notify change
952 if (retInt != 0) {
953 SETTING_LOG_INFO("settingsnapi : execute... retInt is NOT zero");
954 std::string uriWithNameStr =
955 argsName.empty() ? SETTINGS_DATA_BASE_URI : (SETTINGS_DATA_BASE_URI + "/" + argsName);
956 std::shared_ptr<Uri> uriWithName = std::make_shared<Uri>(uriWithNameStr);
957 asyncCallbackInfo->dataAbilityHelper->NotifyChange(*uriWithName);
958 SETTING_LOG_INFO(
959 "settingsnapi : execute... after NotifyChange with uri: %{public}s",
960 uriWithNameStr.c_str());
961 }
962 if (resultset != nullptr) {
963 resultset->Close();
964 }
965 SETTING_LOG_INFO("settingsnapi : execute... END!");
966 asyncCallbackInfo->status = retInt;
967 }
968
SetValueAsync(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)969 napi_value SetValueAsync(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
970 {
971 SETTING_LOG_INFO("settingsnapi : set do callback");
972 napi_value resource = nullptr;
973 NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resource));
974
975 napi_create_async_work(
976 env,
977 nullptr,
978 resource,
979 SetValueExecuteCB,
980 [](napi_env env, napi_status status, void* data) {
981 if (data == nullptr) {
982 SETTING_LOG_INFO("settingsnapi : callback set async end data is null");
983 return;
984 }
985 SETTING_LOG_INFO("settingsnapi : callback set async end called callback");
986 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
987 napi_value undefine;
988 napi_get_undefined(env, &undefine);
989 SETTING_LOG_INFO("settingsnapi : callback set aysnc end called");
990 napi_value callback = nullptr;
991 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
992 SETTING_LOG_INFO("settingsnapi : callback set aysnc end called");
993 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
994 napi_call_function(env, nullptr, callback, 1, &result, &undefine);
995 SETTING_LOG_INFO("settingsnapi : callback set aysnc end called");
996 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
997 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
998 asyncCallbackInfo->dataAbilityHelper = nullptr;
999 delete asyncCallbackInfo;
1000 SETTING_LOG_INFO("settingsnapi : callback set change callback complete");
1001 },
1002 (void*)asyncCallbackInfo,
1003 &asyncCallbackInfo->asyncWork
1004 );
1005 SETTING_LOG_INFO("settingsnapi : callback set start async work");
1006 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1007 SETTING_LOG_INFO("settingsnapi : callback set end async work");
1008 return wrap_void_to_js(env);
1009 }
1010
SetValuePromise(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1011 napi_value SetValuePromise(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
1012 {
1013 SETTING_LOG_INFO("settingsnapi : set do promise");
1014 napi_value promise;
1015 napi_deferred deferred;
1016 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1017 asyncCallbackInfo->deferred = deferred;
1018
1019 napi_value resource = nullptr;
1020 NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resource));
1021
1022 napi_create_async_work(
1023 env,
1024 nullptr,
1025 resource,
1026 SetValueExecuteCB,
1027 [](napi_env env, napi_status status, void* data) {
1028 SETTING_LOG_INFO("settingsnapi : promise set async end called callback");
1029 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1030 SETTING_LOG_INFO("settingsnapi : promise set end get callback value is %{public}d",
1031 asyncCallbackInfo->status);
1032 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
1033 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
1034 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1035 asyncCallbackInfo->dataAbilityHelper = nullptr;
1036 delete asyncCallbackInfo;
1037 },
1038 (void*)asyncCallbackInfo,
1039 &asyncCallbackInfo->asyncWork);
1040 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1041 return promise;
1042 }
1043
1044 /**
1045 * @brief setValue NAPI implementation.
1046 *
1047 * @param env the environment that the Node-API call is invoked under
1048 * @param info the callback info passed into the callback function
1049 * @return napi_value the return value from NAPI C++ to JS for the module.
1050 */
napi_set_value(napi_env env,napi_callback_info info)1051 napi_value napi_set_value(napi_env env, napi_callback_info info)
1052 {
1053 SETTING_LOG_INFO("settingsnapi : set napi_set_value called...");
1054
1055 // getValue api need 3 parameters when Promise mode and need 4 parameters when callback mode
1056 const size_t paramOfPromise = ARGS_THREE;
1057 const size_t paramOfCallback = ARGS_FOUR;
1058
1059 size_t argc = ARGS_FOUR;
1060 napi_value args[ARGS_FOUR] = {nullptr};
1061 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1062 if (argc != paramOfPromise && argc != paramOfCallback) {
1063 SETTING_LOG_ERROR("settingsnapi : set %{public}s, wrong number of arguments, expect 3 or 4 but get %{public}zd",
1064 __func__, argc);
1065 return wrap_void_to_js(env);
1066 }
1067
1068 SETTING_LOG_INFO("settingsnapi : set arg count is %{public}zd", argc);
1069 SETTING_LOG_INFO("settingsnapi : set start create aysnc call back info");
1070 // Check the value type of the arguments
1071 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1072 .env = env,
1073 .asyncWork = nullptr,
1074 .deferred = nullptr,
1075 .callbackRef = nullptr,
1076 .dataAbilityHelper = nullptr,
1077 .key = "",
1078 .value = "",
1079 .uri = "",
1080 .status = false,
1081 };
1082 SETTING_LOG_INFO("settingsnapi : set after create aysnc call back info");
1083 napi_valuetype valueType;
1084 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
1085
1086 // api9 napi_set_value_ext
1087 bool stageMode = false;
1088 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode);
1089 if (status == napi_ok) {
1090 SETTING_LOG_INFO("argv[0] is a context, Stage Model: %{public}d", stageMode);
1091 return napi_set_value_ext(env, info, stageMode);
1092 }
1093
1094 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected.");
1095 NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType));
1096 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1], type. String expected");
1097 NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType));
1098 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2], type. String expected");
1099
1100 NAPI_CALL(env, napi_unwrap(env, args[PARAM0], reinterpret_cast<void **>(&asyncCallbackInfo->dataAbilityHelper)));
1101 SETTING_LOG_INFO("settingsnapi : input paramter is (DataAbilityHelper)");
1102
1103 asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1104 asyncCallbackInfo->value = unwrap_string_from_js(env, args[PARAM2]);
1105 SETTING_LOG_INFO("settingsnapi : set input parameter is : (key %{public}s, value %{public}s)",
1106 asyncCallbackInfo->key.c_str(), asyncCallbackInfo->value.c_str());
1107
1108 napi_value ret = nullptr;
1109 if (argc == paramOfCallback) {
1110 napi_create_reference(env, args[PARAM3], 1, &asyncCallbackInfo->callbackRef);
1111 ret = SetValueAsync(env, asyncCallbackInfo);
1112 } else {
1113 ret = SetValuePromise(env, asyncCallbackInfo);
1114 }
1115 SETTING_LOG_INFO("settingsnapi : set value end");
1116 return ret;
1117 }
1118
napi_set_value_ext(napi_env env,napi_callback_info info,const bool stageMode)1119 napi_value napi_set_value_ext(napi_env env, napi_callback_info info, const bool stageMode)
1120 {
1121 const size_t paramOfCallback = ARGS_FOUR;
1122
1123 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1124 .env = env,
1125 .asyncWork = nullptr,
1126 .deferred = nullptr,
1127 .callbackRef = nullptr,
1128 .dataAbilityHelper = nullptr,
1129 .key = "",
1130 .value = "",
1131 .uri = "",
1132 .status = false,
1133 };
1134
1135 size_t argc = ARGS_FOUR;
1136 napi_value args[ARGS_FOUR] = {nullptr};
1137 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1138
1139 asyncCallbackInfo->dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode);
1140 asyncCallbackInfo->key = unwrap_string_from_js(env, args[PARAM1]);
1141 asyncCallbackInfo->uri = unwrap_string_from_js(env, args[PARAM2]); //temp
1142 napi_value resource = nullptr;
1143 NAPI_CALL(env, napi_create_string_utf8(env, "napi_set_value_ext", NAPI_AUTO_LENGTH, &resource));
1144
1145 if (argc == paramOfCallback) {
1146 napi_create_reference(env, args[PARAM3], 1, &asyncCallbackInfo->callbackRef);
1147 napi_create_async_work(
1148 env,
1149 nullptr,
1150 resource,
1151 [](napi_env env, void* data) {
1152 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1153 GetValueExecuteExt(env, (void*)asyncCallbackInfo);
1154 SetValueExecuteExt(env, (void*)asyncCallbackInfo, asyncCallbackInfo->uri);
1155 },
1156 [](napi_env env, napi_status status, void* data) {
1157 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1158 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
1159 asyncCallbackInfo->status = napi_ok;
1160 CompleteCall(env, status, data, result);
1161 },
1162 (void*)asyncCallbackInfo,
1163 &asyncCallbackInfo->asyncWork
1164 );
1165 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1166 SETTING_LOG_INFO("settingsnapi : callback end async work");
1167 return wrap_void_to_js(env);
1168 } else {
1169 napi_value promise;
1170 napi_deferred deferred;
1171 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1172 asyncCallbackInfo->deferred = deferred;
1173 napi_create_async_work(
1174 env,
1175 nullptr,
1176 resource,
1177 [](napi_env env, void* data) {
1178 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1179 GetValueExecuteExt(env, (void*)asyncCallbackInfo);
1180 SetValueExecuteExt(env, (void*)asyncCallbackInfo, asyncCallbackInfo->uri);
1181 },
1182 [](napi_env env, napi_status status, void* data) {
1183 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1184 napi_value result = wrap_bool_to_js(env, asyncCallbackInfo->status != 0);
1185 asyncCallbackInfo->status = napi_ok;
1186 CompletePromise(env, status, data, result);
1187 },
1188 (void*)asyncCallbackInfo,
1189 &asyncCallbackInfo->asyncWork
1190 );
1191 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1192 return promise;
1193 }
1194 return wrap_void_to_js(env);
1195 }
1196 /**
1197 * @brief enableAirplaneMode NAPI implementation.
1198 * @param env the environment that the Node-API call is invoked under
1199 * @param info the callback info passed into the callback function
1200 * @return napi_value the return value from NAPI C++ to JS for the module.
1201 */
napi_enable_airplane_mode(napi_env env,napi_callback_info info)1202 napi_value napi_enable_airplane_mode(napi_env env, napi_callback_info info)
1203 {
1204 const size_t paramOfPromise = ARGS_ONE;
1205 const size_t paramOfCallback = ARGS_TWO;
1206
1207 size_t argc = ARGS_TWO;
1208 napi_value args[ARGS_TWO] = {nullptr};
1209 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1210 if (argc != paramOfCallback && argc != paramOfPromise) {
1211 SETTING_LOG_ERROR("settingsnapi : %{public}s, wrong number of arguments, expect 1 or 2 but get %{public}zd",
1212 __func__, argc);
1213 return wrap_void_to_js(env);
1214 }
1215
1216 SETTING_LOG_INFO("settingsnapi : napi_enable_airplane_mode arg count is %{public}zd", argc);
1217 SETTING_LOG_INFO("settingsnapi : napi_enable_airplane_mode start create aysnc call back info");
1218 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1219 .env = env,
1220 .asyncWork = nullptr,
1221 .deferred = nullptr,
1222 .callbackRef = nullptr,
1223 .dataAbilityHelper = nullptr,
1224 .key = "",
1225 .value = "",
1226 .uri = "",
1227 .status = 0,
1228 };
1229 SETTING_LOG_INFO("settingsnapi : after create aysnc call back info");
1230
1231 napi_valuetype valueType;
1232 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType));
1233 NAPI_ASSERT(env, valueType == napi_boolean, "Wrong argument[0], type. Boolean expected");
1234
1235 napi_value resource = nullptr;
1236 NAPI_CALL(env, napi_create_string_utf8(env, "enableAirplaneMode", NAPI_AUTO_LENGTH, &resource));
1237
1238 if (argc == paramOfCallback) {
1239 SETTING_LOG_INFO("%{public}s, asyncCallback.", __func__);
1240
1241 napi_create_reference(env, args[PARAM1], 1, &asyncCallbackInfo->callbackRef);
1242 napi_create_async_work(
1243 env,
1244 nullptr,
1245 resource,
1246 [](napi_env env, void* data) {},
1247 [](napi_env env, napi_status status, void* data) {
1248 if (data == nullptr) {
1249 SETTING_LOG_INFO("settingsnapi : callback async end data is null");
1250 return;
1251 }
1252 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1253
1254 napi_value callback = nullptr;
1255 napi_value undefined;
1256 napi_get_undefined(env, &undefined);
1257
1258 napi_value result[PARAM2] = {0};
1259
1260 // create error code
1261 napi_value error = nullptr;
1262 napi_create_object(env, &error);
1263 int unSupportCode = 801;
1264 napi_value errCode = nullptr;
1265 napi_create_int32(env, unSupportCode, &errCode);
1266 napi_set_named_property(env, error, "code", errCode);
1267 result[0] = error;
1268 napi_get_undefined(env, &result[1]);
1269
1270 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
1271 napi_value callResult;
1272 napi_call_function(env, undefined, callback, PARAM2, result, &callResult);
1273 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
1274
1275 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
1276 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1277 delete asyncCallbackInfo;
1278 SETTING_LOG_INFO("settingsnapi : callback change callback complete");
1279 },
1280 (void*)asyncCallbackInfo,
1281 &asyncCallbackInfo->asyncWork
1282 );
1283 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1284 return wrap_void_to_js(env);
1285 } else {
1286 SETTING_LOG_INFO("%{public}s, promise.", __func__);
1287 napi_deferred deferred;
1288 napi_value promise;
1289 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1290 asyncCallbackInfo->deferred = deferred;
1291
1292 napi_create_async_work(
1293 env,
1294 nullptr,
1295 resource,
1296 [](napi_env env, void *data) {},
1297 [](napi_env env, napi_status status, void *data) {
1298 SETTING_LOG_INFO("%{public}s, promise complete", __func__);
1299 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1300
1301 napi_value result;
1302 napi_value error = nullptr;
1303 napi_create_object(env, &error);
1304 int unSupportCode = 801;
1305 napi_value errCode = nullptr;
1306 napi_create_int32(env, unSupportCode, &errCode);
1307 napi_set_named_property(env, error, "code", errCode);
1308 result = error;
1309
1310 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1311 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1312 delete asyncCallbackInfo;
1313 },
1314 (void *)asyncCallbackInfo,
1315 &asyncCallbackInfo->asyncWork);
1316 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1317 return promise;
1318 }
1319 }
1320
1321 /**
1322 * @brief canShowFloating NAPI implementation.
1323 * @param env the environment that the Node-API call is invoked under
1324 * @param info the callback info passed into the callback function
1325 * @return napi_value the return value from NAPI C++ to JS for the module.
1326 */
napi_can_show_floating(napi_env env,napi_callback_info info)1327 napi_value napi_can_show_floating(napi_env env, napi_callback_info info)
1328 {
1329 const size_t paramOfPromise = PARAM0;
1330 const size_t paramOfCallback = PARAM1;
1331
1332 size_t argc = PARAM1;
1333 napi_value args[PARAM1] = {nullptr};
1334 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
1335 if (argc != paramOfCallback && argc != paramOfPromise) {
1336 SETTING_LOG_ERROR("settingsnapi : %{public}s, wrong number of arguments, expect 0 or 1 but get %{public}zd",
1337 __func__, argc);
1338 return wrap_void_to_js(env);
1339 }
1340
1341 SETTING_LOG_INFO("settingsnapi : napi_enable_airplane_mode arg count is %{public}zd", argc);
1342 SETTING_LOG_INFO("settingsnapi : napi_enable_airplane_mode start create aysnc call back info");
1343 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
1344 .env = env,
1345 .asyncWork = nullptr,
1346 .deferred = nullptr,
1347 .callbackRef = nullptr,
1348 .dataAbilityHelper = nullptr,
1349 .key = "",
1350 .value = "",
1351 .uri = "",
1352 .status = 0,
1353 };
1354 SETTING_LOG_INFO("settingsnapi : after create aysnc call back info");
1355
1356 napi_value resource = nullptr;
1357 NAPI_CALL(env, napi_create_string_utf8(env, "enableAirplaneMode", NAPI_AUTO_LENGTH, &resource));
1358
1359 if (argc == paramOfCallback) {
1360 SETTING_LOG_INFO("%{public}s, asyncCallback.", __func__);
1361
1362 napi_create_reference(env, args[PARAM0], 1, &asyncCallbackInfo->callbackRef);
1363 napi_create_async_work(
1364 env,
1365 nullptr,
1366 resource,
1367 [](napi_env env, void* data) {},
1368 [](napi_env env, napi_status status, void* data) {
1369 if (data == nullptr) {
1370 SETTING_LOG_INFO("settingsnapi : callback async end data is null");
1371 return;
1372 }
1373 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1374
1375 napi_value callback = nullptr;
1376 napi_value undefined;
1377 napi_get_undefined(env, &undefined);
1378
1379 napi_value result[PARAM2] = {0};
1380
1381 // create error code
1382 napi_value error = nullptr;
1383 napi_create_object(env, &error);
1384 int unSupportCode = 801;
1385 napi_value errCode = nullptr;
1386 napi_create_int32(env, unSupportCode, &errCode);
1387 napi_set_named_property(env, error, "code", errCode);
1388 result[0] = error;
1389 result[1] = wrap_bool_to_js(env, false);
1390
1391 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
1392 napi_value callResult;
1393 napi_call_function(env, undefined, callback, PARAM2, result, &callResult);
1394 SETTING_LOG_INFO("settingsnapi : callback aysnc end called");
1395
1396 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
1397 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1398 delete asyncCallbackInfo;
1399 SETTING_LOG_INFO("settingsnapi : callback change callback complete");
1400 },
1401 (void*)asyncCallbackInfo,
1402 &asyncCallbackInfo->asyncWork
1403 );
1404 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1405 return wrap_void_to_js(env);
1406 } else {
1407 SETTING_LOG_INFO("%{public}s, promise.", __func__);
1408 napi_deferred deferred;
1409 napi_value promise;
1410 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1411 asyncCallbackInfo->deferred = deferred;
1412
1413 napi_create_async_work(
1414 env,
1415 nullptr,
1416 resource,
1417 [](napi_env env, void *data) {},
1418 [](napi_env env, napi_status status, void *data) {
1419 SETTING_LOG_INFO("%{public}s, promise complete", __func__);
1420 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
1421
1422 napi_value result;
1423 napi_value error = nullptr;
1424 napi_create_object(env, &error);
1425 int unSupportCode = 801;
1426 napi_value errCode = nullptr;
1427 napi_create_int32(env, unSupportCode, &errCode);
1428 napi_set_named_property(env, error, "code", errCode);
1429 result = error;
1430
1431 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1432 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1433 delete asyncCallbackInfo;
1434 },
1435 (void *)asyncCallbackInfo,
1436 &asyncCallbackInfo->asyncWork);
1437 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1438 return promise;
1439 }
1440 }
1441 } // namespace Settings
1442 } // namespace OHOS
1443