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