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