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