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