• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2023 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 #define LOG_TAG "JSConfig"
16 #include "js_config.h"
17 
18 #include <cstddef>
19 #include <memory>
20 
21 #include "cloud_manager.h"
22 #include "cloud_service.h"
23 #include "js_cloud_utils.h"
24 #include "js_df_manager.h"
25 #include "js_error_utils.h"
26 #include "js_strategy_context.h"
27 #include "js_utils.h"
28 #include "logger.h"
29 #include "napi_queue.h"
30 
31 using namespace OHOS::Rdb;
32 using namespace OHOS::CloudData;
33 using namespace OHOS::AppDataMgrJsKit;
JsConfig()34 JsConfig::JsConfig()
35 {
36 }
37 
~JsConfig()38 JsConfig::~JsConfig()
39 {
40 }
41 
42 /*
43  * [JS API Prototype]
44  * [AsyncCallback]
45  *      enableCloud(accountId: string, switches: {[bundleName: string]: boolean}, callback: AsyncCallback<void>): void;
46  * [Promise]
47  *      enableCloud(accountId: string, switches: {[bundleName: string]: boolean}): Promise<void>;
48  */
EnableCloud(napi_env env,napi_callback_info info)49 napi_value JsConfig::EnableCloud(napi_env env, napi_callback_info info)
50 {
51     struct EnableCloudContext : public ContextBase {
52         std::string accountId;
53         std::map<std::string, bool> tempSwitches;
54         std::map<std::string, int32_t> switches;
55     };
56     auto ctxt = std::make_shared<EnableCloudContext>();
57     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
58         // required 2 arguments :: <accountId> <switches>
59         ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
60         // 0 is the index of argument accountId, 1 is the index of argument switches
61         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
62         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->accountId.empty(), Status::INVALID_ARGUMENT,
63             "The type of accountId must be string and not empty.");
64         status = JSUtils::Convert2Value(env, argv[1], ctxt->tempSwitches);
65         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT,
66             "The type of switches must be {[bundleName: string]: boolean}.");
67         for (auto item : ctxt->tempSwitches) {
68             ctxt->switches[item.first] = item.second ? CloudService::Switch::SWITCH_ON
69                                                      : CloudService::Switch::SWITCH_OFF;
70         }
71     });
72 
73     ASSERT_NULL(!ctxt->isThrowError, "EnableCloud exit");
74 
75     auto execute = [ctxt]() {
76         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
77         if (proxy == nullptr) {
78             if (state != CloudService::SERVER_UNAVAILABLE) {
79                 state = CloudService::NOT_SUPPORT;
80             }
81             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
82                                ? napi_ok
83                                : napi_generic_failure;
84             return;
85         }
86         int32_t cStatus = proxy->EnableCloud(ctxt->accountId, ctxt->switches);
87         LOG_DEBUG("EnableCloud return %{public}d", cStatus);
88         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
89                            ? napi_ok
90                            : napi_generic_failure;
91     };
92     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
93 }
94 
95 /*
96  * [JS API Prototype]
97  * [AsyncCallback]
98  *      disableCloud(accountId: string, callback: AsyncCallback<void>): void;
99  * [Promise]
100  *      disableCloud(accountId: string): Promise<void>;
101  */
DisableCloud(napi_env env,napi_callback_info info)102 napi_value JsConfig::DisableCloud(napi_env env, napi_callback_info info)
103 {
104     struct DisableCloudContext : public ContextBase {
105         std::string accountId;
106     };
107     auto ctxt = std::make_shared<DisableCloudContext>();
108     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
109         // required 1 arguments :: <accountId>
110         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
111         // 0 is the index of argument accountId
112         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
113         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->accountId.empty(), Status::INVALID_ARGUMENT,
114             "The type of accountId must be string and not empty.");
115     });
116 
117     ASSERT_NULL(!ctxt->isThrowError, "DisableCloud exit");
118 
119     auto execute = [ctxt]() {
120         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
121         if (proxy == nullptr) {
122             if (state != CloudService::SERVER_UNAVAILABLE) {
123                 state = CloudService::NOT_SUPPORT;
124             }
125             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
126                                ? napi_ok
127                                : napi_generic_failure;
128             return;
129         }
130         int32_t cStatus = proxy->DisableCloud(ctxt->accountId);
131         LOG_DEBUG("DisableCloud return %{public}d", cStatus);
132         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
133                            ? napi_ok
134                            : napi_generic_failure;
135     };
136     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
137 }
138 
139 /*
140  * [JS API Prototype]
141  * [AsyncCallback]
142  *      changeAppCloudSwitch(accountId: string, bundleName: string, status :boolean,
143  *      callback: AsyncCallback<void>): void;
144  * [Promise]
145  *      changeAppCloudSwitch(accountId: string, bundleName: string, status :boolean): Promise<void>;
146  */
147 
ChangeAppCloudSwitch(napi_env env,napi_callback_info info)148 napi_value JsConfig::ChangeAppCloudSwitch(napi_env env, napi_callback_info info)
149 {
150     struct ChangeAppSwitchContext : public ContextBase {
151         std::string accountId;
152         std::string bundleName;
153         CloudService::Switch state;
154     };
155     auto ctxt = std::make_shared<ChangeAppSwitchContext>();
156     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
157         // required 3 arguments :: <accountId> <bundleName> <state>
158         ASSERT_BUSINESS_ERR(ctxt, argc >= 3, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
159         // 0 is the index of argument accountId
160         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
161         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->accountId.empty(), Status::INVALID_ARGUMENT,
162             "The type of accountId must be string and not empty.");
163         // 1 is the index of argument bundleName
164         status = JSUtils::Convert2Value(env, argv[1], ctxt->bundleName);
165         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->bundleName.empty(), Status::INVALID_ARGUMENT,
166             "The type of bundleName must be string and not empty.");
167         bool state = false;
168         // 2 is the index of argument state
169         status = JSUtils::Convert2Value(env, argv[2], state);
170         ASSERT_BUSINESS_ERR(
171             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of status must be boolean.");
172         ctxt->state = state ? CloudService::Switch::SWITCH_ON : CloudService::Switch::SWITCH_OFF;
173     });
174 
175     ASSERT_NULL(!ctxt->isThrowError, "ChangeAppCloudSwitch exit");
176 
177     auto execute = [ctxt]() {
178         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
179         if (proxy == nullptr) {
180             if (state != CloudService::SERVER_UNAVAILABLE) {
181                 state = CloudService::NOT_SUPPORT;
182             }
183             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
184                                ? napi_ok
185                                : napi_generic_failure;
186             return;
187         }
188         int32_t cStatus = proxy->ChangeAppSwitch(ctxt->accountId, ctxt->bundleName, ctxt->state);
189         LOG_DEBUG("ChangeAppCloudSwitch return %{public}d", cStatus);
190         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
191                            ? napi_ok
192                            : napi_generic_failure;
193     };
194     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
195 }
196 
197 /*
198  * [JS API Prototype]
199  * [AsyncCallback]
200  *      clean(accountId: string, appActions: {[bundleName: string]: Action}, callback: AsyncCallback<void>): void;
201  * [Promise]
202  *      clean(accountId: string, appActions: {[bundleName: string]: Action}): Promise<void>;
203  */
Clean(napi_env env,napi_callback_info info)204 napi_value JsConfig::Clean(napi_env env, napi_callback_info info)
205 {
206     struct CleanContext : public ContextBase {
207         std::string accountId;
208         std::map<std::string, int32_t> appActions;
209     };
210     auto ctxt = std::make_shared<CleanContext>();
211     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
212         // required 2 arguments :: <accountId> <appActions>
213         ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
214         // 0 is the index of argument accountId, 1 is the index of argument
215         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
216         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->accountId.empty(), Status::INVALID_ARGUMENT,
217             "The type of accountId must be string and not empty.");
218         status = JSUtils::Convert2Value(env, argv[1], ctxt->appActions);
219         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT,
220             "The type of actions must be {[bundleName: string]: int32_t}.");
221         for (auto item : ctxt->appActions) {
222             ASSERT_BUSINESS_ERR(ctxt, ValidSubscribeType(item.second), Status::INVALID_ARGUMENT,
223                 "Action in map appActions is incorrect.");
224         }
225     });
226 
227     ASSERT_NULL(!ctxt->isThrowError, "Clean exit");
228 
229     auto execute = [ctxt]() {
230         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
231         if (proxy == nullptr) {
232             if (state != CloudService::SERVER_UNAVAILABLE) {
233                 state = CloudService::NOT_SUPPORT;
234             }
235             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
236                                ? napi_ok
237                                : napi_generic_failure;
238             return;
239         }
240         int32_t cStatus = proxy->Clean(ctxt->accountId, ctxt->appActions);
241         LOG_DEBUG("Clean return %{public}d", cStatus);
242         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
243                            ? napi_ok
244                            : napi_generic_failure;
245     };
246     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
247 }
248 
249 /*
250  * [JS API Prototype]
251  * [AsyncCallback]
252  *      notifyDataChange(accountId: string, bundleName: string, callback: AsyncCallback<void>): void;
253  *      notifyDataChange(extInfo: ExtraData, callback: AsyncCallback<void>): void;
254  *      notifyDataChange(extInfo: ExtraData, userId: number,callback: AsyncCallback<void>): void;
255  * [Promise]
256  *      notifyDataChange(accountId: string, bundleName: string): Promise<void>;
257  *      notifyDataChange(extInfo: ExtraData, userId?: number): Promise<void>;
258  */
259 struct ChangeAppSwitchContext : public ContextBase {
260     std::string accountId;
261     std::string bundleName;
262     int32_t userId = CloudService::INVALID_USER_ID;
263     bool notifyStatus = false;
264     OHOS::CloudData::JsConfig::ExtraData extInfo;
265 };
NotifyDataChange(napi_env env,napi_callback_info info)266 napi_value JsConfig::NotifyDataChange(napi_env env, napi_callback_info info)
267 {
268     auto ctxt = std::make_shared<ChangeAppSwitchContext>();
269     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
270         // required 2 arguments :: <accountId> <bundleName>
271         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
272         napi_valuetype type = napi_undefined;
273         if (argc > 1 && napi_typeof(env, argv[0], &type) == napi_ok && type != napi_object) {
274             // 0 is the index of argument accountId, 1 is the index of argument bundleName
275             int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
276             ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->accountId.empty(), Status::INVALID_ARGUMENT,
277                 "The type of accountId must be string and not empty.");
278             status = JSUtils::Convert2Value(env, argv[1], ctxt->bundleName);
279             ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->bundleName.empty(), Status::INVALID_ARGUMENT,
280                 "The type of bundleName must be string and not empty.");
281         } else {
282             int status = JSUtils::Convert2Value(env, argv[0], ctxt->extInfo);
283             ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && VerifyExtraData(ctxt->extInfo),
284                 Status::INVALID_ARGUMENT, "The type of extInfo must be Extradata and not empty.");
285             if (argc > 1) {
286                 status = JSUtils::Convert2ValueExt(env, argv[1], ctxt->userId);
287                 ASSERT_BUSINESS_ERR(
288                     ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of user must be number.");
289             }
290             ctxt->notifyStatus = true;
291         }
292     });
293 
294     ASSERT_NULL(!ctxt->isThrowError, "NotifyDataChange exit");
295 
296     auto execute = [ctxt]() {
297         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
298         if (proxy == nullptr) {
299             if (state != CloudService::SERVER_UNAVAILABLE) {
300                 state = CloudService::NOT_SUPPORT;
301             }
302             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
303                 ? napi_ok : napi_generic_failure;
304             return;
305         }
306         int32_t status;
307         if (ctxt->notifyStatus == true) {
308             status = proxy->NotifyDataChange(ctxt->extInfo.eventId, ctxt->extInfo.extraData, ctxt->userId);
309         } else {
310             status = proxy->NotifyDataChange(ctxt->accountId, ctxt->bundleName);
311         }
312         LOG_DEBUG("NotifyDataChange return %{public}d", status);
313         ctxt->status =
314             (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure;
315         if (status == Status::INVALID_ARGUMENT) {
316             ctxt->error += "The parameter required is a valid value.";
317         }
318     };
319     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
320 }
321 
322 /*
323  * [JS API Prototype]
324  * [Promise]
325  *      QueryStatistics(accountId: string, bundleName: string,
326  *      storeId?: number): Promise<Record<string, Array<StatisticInfo>>>;
327  */
QueryStatistics(napi_env env,napi_callback_info info)328 napi_value JsConfig::QueryStatistics(napi_env env, napi_callback_info info)
329 {
330     struct QueryStatisticsContext : public ContextBase {
331         std::string accountId;
332         std::string bundleName;
333         std::string storeId = "";
334         std::map<std::string, StatisticInfos> result;
335     };
336     auto ctxt = std::make_shared<QueryStatisticsContext>();
337     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
338         // required 2 arguments :: <accountId> <bundleName>
339         ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
340         // 0 is the index of argument accountId
341         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
342         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->accountId.empty(), Status::INVALID_ARGUMENT,
343             "The type of accountId must be string and not empty.");
344         // 1 is the index of argument bundleName
345         status = JSUtils::Convert2Value(env, argv[1], ctxt->bundleName);
346         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->bundleName.empty(), Status::INVALID_ARGUMENT,
347             "The type of bundleName must be string and not empty.");
348         // 2 is the index of argument storeId
349         if (argc > 2 && !JSUtils::IsNull(ctxt->env, argv[2])) {
350             // 2 is the index of argument storeId
351             status = JSUtils::Convert2Value(env, argv[2], ctxt->storeId);
352             ASSERT_BUSINESS_ERR(
353                 ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of storeId must be string.");
354         }
355     });
356 
357     ASSERT_NULL(!ctxt->isThrowError, "QueryStatistics exit");
358 
359     auto execute = [ctxt]() {
360         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
361         if (proxy == nullptr) {
362             if (state != CloudService::SERVER_UNAVAILABLE) {
363                 state = CloudService::NOT_SUPPORT;
364             }
365             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
366                                ? napi_ok
367                                : napi_generic_failure;
368             return;
369         }
370         auto [status, result] = proxy->QueryStatistics(ctxt->accountId, ctxt->bundleName, ctxt->storeId);
371         ctxt->status =
372             (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure;
373         ctxt->result = std::move(result);
374     };
375     auto output = [env, ctxt](napi_value &result) {
376         result = JSUtils::Convert2JSValue(env, ctxt->result);
377         ASSERT_VALUE(ctxt, result != nullptr, napi_generic_failure, "output failed");
378     };
379     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
380 }
381 
SetGlobalCloudStrategy(napi_env env,napi_callback_info info)382 napi_value JsConfig::SetGlobalCloudStrategy(napi_env env, napi_callback_info info)
383 {
384     auto ctxt = std::make_shared<CloudStrategyContext>();
385     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
386         // strategy 1 required parameter, param 1 Optional parameter
387         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
388         int32_t strategy = -1;
389         int status = JSUtils::Convert2ValueExt(env, argv[0], strategy);
390         ASSERT_BUSINESS_ERR(ctxt,
391             status == JSUtils::OK && strategy >= 0 && strategy < static_cast<int32_t>(Strategy::STRATEGY_BUTT),
392             Status::INVALID_ARGUMENT, "The type of strategy must be StrategyType.");
393         ctxt->strategy = static_cast<Strategy>(strategy);
394         // 'argv[1]' represents a vector<CommonType::Value> param or null
395         if (argc == 1 || JSUtils::IsNull(env, argv[1])) {
396             ctxt->SetDefault();
397         } else {
398             // 'argv[1]' represents a vector<CommonType::Value> param
399             status = JSUtils::Convert2Value(env, argv[1], ctxt->param);
400             ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT,
401                 "The type of param must be Array<commonType.ValueType>");
402             auto res = ctxt->CheckParam();
403             ASSERT_BUSINESS_ERR(ctxt, res.first == JSUtils::OK, Status::INVALID_ARGUMENT, res.second);
404         }
405     });
406     ASSERT_NULL(!ctxt->isThrowError, "SetGlobalCloudStrategy exit");
407     auto execute = [env, ctxt]() {
408         auto [status, proxy] = CloudManager::GetInstance().GetCloudService();
409         if (proxy == nullptr) {
410             if (status != CloudService::SERVER_UNAVAILABLE) {
411                 status = CloudService::NOT_SUPPORT;
412             }
413             ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
414                                ? napi_ok: napi_generic_failure;
415             return;
416         }
417         LOG_DEBUG("SetGlobalCloudStrategy execute.");
418 
419         auto res = proxy->SetGlobalCloudStrategy(ctxt->strategy, ctxt->param);
420         ctxt->status =
421             (GenerateNapiError(res, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure;
422     };
423     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
424 }
425 
New(napi_env env,napi_callback_info info)426 napi_value JsConfig::New(napi_env env, napi_callback_info info)
427 {
428     napi_value self = nullptr;
429     size_t argc = ARGC_MAX;
430     napi_value argv[ARGC_MAX] = { 0 };
431     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
432     if (self == nullptr) {
433         napi_new_instance(env, JSUtils::GetClass(env, "ohos.cloudData", "Config"), argc, argv, &self);
434         return self;
435     }
436 
437     auto finalize = [](napi_env env, void *data, void *hint) {
438         auto tid = JSDFManager::GetInstance().GetFreedTid(data);
439         if (tid != 0) {
440             LOG_ERROR("(T:%{public}d) freed! data:0x%016" PRIXPTR, tid, uintptr_t(data) & LOWER_24_BITS_MASK);
441         }
442         LOG_DEBUG("CloudConfig finalize.");
443         auto *config = reinterpret_cast<JsConfig *>(data);
444         ASSERT_VOID(config != nullptr, "finalize null!");
445         delete config;
446     };
447     JsConfig *cloudConfig = new (std::nothrow) JsConfig();
448     ASSERT_ERR(env, cloudConfig != nullptr, Status::INVALID_ARGUMENT, "no memory for cloudConfig.");
449     napi_status status = napi_wrap(env, self, cloudConfig, finalize, nullptr, nullptr);
450     if (status != napi_ok) {
451         LOG_ERROR("JsConfig::Initialize napi_wrap failed! code:%{public}d!", status);
452         finalize(env, cloudConfig, nullptr);
453         return nullptr;
454     }
455     JSDFManager::GetInstance().AddNewInfo(cloudConfig);
456     return self;
457 }
458 
QueryLastSyncInfo(napi_env env,napi_callback_info info)459 napi_value JsConfig::QueryLastSyncInfo(napi_env env, napi_callback_info info)
460 {
461     struct QueryLastSyncInfoContext : public ContextBase {
462         std::string accountId;
463         std::string bundleName;
464         std::string storeId;
465         QueryLastResults results;
466     };
467     auto ctxt = std::make_shared<QueryLastSyncInfoContext>();
468     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
469         // less required 2 arguments :: <accountId> <bundleName> , <storeId> is optional
470         ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
471         // 0 is the index of argument accountId
472         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
473         ASSERT_BUSINESS_ERR(
474             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of accountId must be string.");
475         // 1 is the index of argument bundleName
476         status = JSUtils::Convert2Value(env, argv[1], ctxt->bundleName);
477         ASSERT_BUSINESS_ERR(
478             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of bundleName must be string.");
479         // 2 is the index of argument storeId
480         if (argc > 2 && !JSUtils::IsNull(ctxt->env, argv[2])) {
481             // 2 is the index of argument storeId
482             status = JSUtils::Convert2Value(env, argv[2], ctxt->storeId);
483             ASSERT_BUSINESS_ERR(
484                 ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of storeId must be string.");
485         }
486     });
487 
488     ASSERT_NULL(!ctxt->isThrowError, "QueryLastSyncInfo exit");
489 
490     auto execute = [ctxt]() {
491         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
492         if (proxy == nullptr) {
493             if (state != CloudService::SERVER_UNAVAILABLE) {
494                 state = CloudService::NOT_SUPPORT;
495             }
496             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
497                                ? napi_ok
498                                : napi_generic_failure;
499             return;
500         }
501         auto [status, results] = proxy->QueryLastSyncInfo(ctxt->accountId, ctxt->bundleName, ctxt->storeId);
502         ctxt->status =
503             (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure;
504         ctxt->results = std::move(results);
505     };
506     auto output = [env, ctxt](napi_value &result) {
507         result = JSUtils::Convert2JSValue(env, ctxt->results);
508         ASSERT_VALUE(ctxt, result != nullptr, napi_generic_failure, "output failed");
509     };
510     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output);
511 }
512 
InitConfig(napi_env env,napi_value exports)513 napi_value JsConfig::InitConfig(napi_env env, napi_value exports)
514 {
515     auto lambda = []() -> std::vector<napi_property_descriptor> {
516         std::vector<napi_property_descriptor> properties = {
517             DECLARE_NAPI_STATIC_FUNCTION("enableCloud", JsConfig::EnableCloud),
518             DECLARE_NAPI_STATIC_FUNCTION("disableCloud", JsConfig::DisableCloud),
519             DECLARE_NAPI_STATIC_FUNCTION("changeAppCloudSwitch", JsConfig::ChangeAppCloudSwitch),
520             DECLARE_NAPI_STATIC_FUNCTION("clear", JsConfig::Clean),
521             DECLARE_NAPI_STATIC_FUNCTION("clean", JsConfig::Clean),
522             DECLARE_NAPI_STATIC_FUNCTION("notifyDataChange", JsConfig::NotifyDataChange),
523             DECLARE_NAPI_STATIC_FUNCTION("queryStatistics", JsConfig::QueryStatistics),
524             DECLARE_NAPI_STATIC_FUNCTION("setGlobalCloudStrategy", JsConfig::SetGlobalCloudStrategy),
525             DECLARE_NAPI_STATIC_FUNCTION("queryLastSyncInfo", JsConfig::QueryLastSyncInfo),
526         };
527         return properties;
528     };
529     auto jsCtor = JSUtils::DefineClass(env, "ohos.data.cloudData", "Config", lambda, JsConfig::New);
530     NAPI_CALL(env, napi_set_named_property(env, exports, "Config", jsCtor));
531     return exports;
532 }
533