• 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 
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 "logger.h"
26 #include "napi_queue.h"
27 
28 using namespace OHOS::Rdb;
29 using namespace OHOS::CloudData;
30 using namespace OHOS::AppDataMgrJsKit;
JsConfig()31 JsConfig::JsConfig()
32 {
33 }
34 
~JsConfig()35 JsConfig::~JsConfig()
36 {
37 }
38 
39 /*
40  * [JS API Prototype]
41  * [AsyncCallback]
42  *      enableCloud(accountId: string, switches: {[bundleName: string]: boolean}, callback: AsyncCallback<void>): void;
43  * [Promise]
44  *      enableCloud(accountId: string, switches: {[bundleName: string]: boolean}): Promise<void>;
45  */
EnableCloud(napi_env env,napi_callback_info info)46 napi_value JsConfig::EnableCloud(napi_env env, napi_callback_info info)
47 {
48     struct EnableCloudContext : public ContextBase {
49         std::string accountId;
50         std::map<std::string, bool> tempSwitches;
51         std::map<std::string, int32_t> switches;
52     };
53     auto ctxt = std::make_shared<EnableCloudContext>();
54     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
55         // required 2 arguments :: <accountId> <switches>
56         ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
57         // 0 is the index of argument accountId, 1 is the index of argument switches
58         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
59         ASSERT_BUSINESS_ERR(
60             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of accountId must be string.");
61         status = JSUtils::Convert2Value(env, argv[1], ctxt->tempSwitches);
62         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT,
63             "The type of switches must be {[bundleName: string]: boolean}.");
64         for (auto item : ctxt->tempSwitches) {
65             ctxt->switches[item.first] = item.second ? CloudService::Switch::SWITCH_ON
66                                                      : CloudService::Switch::SWITCH_OFF;
67         }
68     });
69 
70     ASSERT_NULL(!ctxt->isThrowError, "EnableCloud exit");
71 
72     auto execute = [ctxt]() {
73         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
74         if (proxy == nullptr) {
75             if (state != CloudService::SERVER_UNAVAILABLE) {
76                 state = CloudService::NOT_SUPPORT;
77             }
78             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
79                                ? napi_ok
80                                : napi_generic_failure;
81             return;
82         }
83         int32_t cStatus = proxy->EnableCloud(ctxt->accountId, ctxt->switches);
84         LOG_DEBUG("EnableCloud return %{public}d", cStatus);
85         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
86                            ? napi_ok
87                            : napi_generic_failure;
88     };
89     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
90 }
91 
92 /*
93  * [JS API Prototype]
94  * [AsyncCallback]
95  *      disableCloud(accountId: string, callback: AsyncCallback<void>): void;
96  * [Promise]
97  *      disableCloud(accountId: string): Promise<void>;
98  */
DisableCloud(napi_env env,napi_callback_info info)99 napi_value JsConfig::DisableCloud(napi_env env, napi_callback_info info)
100 {
101     struct DisableCloudContext : public ContextBase {
102         std::string accountId;
103     };
104     auto ctxt = std::make_shared<DisableCloudContext>();
105     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
106         // required 1 arguments :: <accountId>
107         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
108         // 0 is the index of argument accountId
109         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
110         ASSERT_BUSINESS_ERR(
111             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of accountId must be string.");
112     });
113 
114     ASSERT_NULL(!ctxt->isThrowError, "DisableCloud exit");
115 
116     auto execute = [ctxt]() {
117         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
118         if (proxy == nullptr) {
119             if (state != CloudService::SERVER_UNAVAILABLE) {
120                 state = CloudService::NOT_SUPPORT;
121             }
122             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
123                                ? napi_ok
124                                : napi_generic_failure;
125             return;
126         }
127         int32_t cStatus = proxy->DisableCloud(ctxt->accountId);
128         LOG_DEBUG("DisableCloud return %{public}d", cStatus);
129         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
130                            ? napi_ok
131                            : napi_generic_failure;
132     };
133     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
134 }
135 
136 /*
137  * [JS API Prototype]
138  * [AsyncCallback]
139  *      changeAppCloudSwitch(accountId: string, bundleName: string, status :boolean,
140  *      callback: AsyncCallback<void>): void;
141  * [Promise]
142  *      changeAppCloudSwitch(accountId: string, bundleName: string, status :boolean): Promise<void>;
143  */
144 
ChangeAppCloudSwitch(napi_env env,napi_callback_info info)145 napi_value JsConfig::ChangeAppCloudSwitch(napi_env env, napi_callback_info info)
146 {
147     struct ChangeAppSwitchContext : public ContextBase {
148         std::string accountId;
149         std::string bundleName;
150         CloudService::Switch state;
151     };
152     auto ctxt = std::make_shared<ChangeAppSwitchContext>();
153     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
154         // required 3 arguments :: <accountId> <bundleName> <state>
155         ASSERT_BUSINESS_ERR(ctxt, argc >= 3, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
156         // 0 is the index of argument accountId, 1 is the index of argument bundleName, 2 is the index of argument state
157         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
158         ASSERT_BUSINESS_ERR(
159             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of accountId must be string.");
160         status = JSUtils::Convert2Value(env, argv[1], ctxt->bundleName);
161         ASSERT_BUSINESS_ERR(
162             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of bundleName must be string.");
163         bool state = false;
164         // 2 is the index of argument state
165         status = JSUtils::Convert2Value(env, argv[2], state);
166         ASSERT_BUSINESS_ERR(
167             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of status must be boolean.");
168         ctxt->state = state ? CloudService::Switch::SWITCH_ON : CloudService::Switch::SWITCH_OFF;
169     });
170 
171     ASSERT_NULL(!ctxt->isThrowError, "ChangeAppCloudSwitch exit");
172 
173     auto execute = [ctxt]() {
174         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
175         if (proxy == nullptr) {
176             if (state != CloudService::SERVER_UNAVAILABLE) {
177                 state = CloudService::NOT_SUPPORT;
178             }
179             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
180                                ? napi_ok
181                                : napi_generic_failure;
182             return;
183         }
184         int32_t cStatus = proxy->ChangeAppSwitch(ctxt->accountId, ctxt->bundleName, ctxt->state);
185         LOG_DEBUG("ChangeAppCloudSwitch return %{public}d", cStatus);
186         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
187                            ? napi_ok
188                            : napi_generic_failure;
189     };
190     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
191 }
192 
193 /*
194  * [JS API Prototype]
195  * [AsyncCallback]
196  *      clean(accountId: string, appActions: {[bundleName: string]: Action}, callback: AsyncCallback<void>): void;
197  * [Promise]
198  *      clean(accountId: string, appActions: {[bundleName: string]: Action}): Promise<void>;
199  */
Clean(napi_env env,napi_callback_info info)200 napi_value JsConfig::Clean(napi_env env, napi_callback_info info)
201 {
202     struct CleanContext : public ContextBase {
203         std::string accountId;
204         std::map<std::string, int32_t> appActions;
205     };
206     auto ctxt = std::make_shared<CleanContext>();
207     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
208         // required 2 arguments :: <accountId> <appActions>
209         ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
210         // 0 is the index of argument accountId, 1 is the index of argument
211         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
212         ASSERT_BUSINESS_ERR(
213             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of accountId must be string.");
214         status = JSUtils::Convert2Value(env, argv[1], ctxt->appActions);
215         ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT,
216             "The type of actions must be {[bundleName: string]: int32_t}.");
217         for (auto item : ctxt->appActions) {
218             ASSERT_BUSINESS_ERR(ctxt, ValidSubscribeType(item.second), Status::INVALID_ARGUMENT,
219                 "Action in map appActions is incorrect.");
220         }
221     });
222 
223     ASSERT_NULL(!ctxt->isThrowError, "Clean exit");
224 
225     auto execute = [ctxt]() {
226         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
227         if (proxy == nullptr) {
228             if (state != CloudService::SERVER_UNAVAILABLE) {
229                 state = CloudService::NOT_SUPPORT;
230             }
231             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
232                                ? napi_ok
233                                : napi_generic_failure;
234             return;
235         }
236         int32_t cStatus = proxy->Clean(ctxt->accountId, ctxt->appActions);
237         LOG_DEBUG("Clean return %{public}d", cStatus);
238         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
239                            ? napi_ok
240                            : napi_generic_failure;
241     };
242     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
243 }
244 
245 /*
246  * [JS API Prototype]
247  * [AsyncCallback]
248  *      notifyDataChange(accountId: string, bundleName: string, callback: AsyncCallback<void>): void;
249  * [Promise]
250  *      notifyDataChange(accountId: string, bundleName: string): Promise<void>;
251  */
NotifyDataChange(napi_env env,napi_callback_info info)252 napi_value JsConfig::NotifyDataChange(napi_env env, napi_callback_info info)
253 {
254     struct ChangeAppSwitchContext : public ContextBase {
255         std::string accountId;
256         std::string bundleName;
257     };
258     auto ctxt = std::make_shared<ChangeAppSwitchContext>();
259     ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) {
260         // required 2 arguments :: <accountId> <bundleName>
261         ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
262         // 0 is the index of argument accountId, 1 is the index of argument bundleName
263         int status = JSUtils::Convert2Value(env, argv[0], ctxt->accountId);
264         ASSERT_BUSINESS_ERR(
265             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of accountId must be string.");
266         status = JSUtils::Convert2Value(env, argv[1], ctxt->bundleName);
267         ASSERT_BUSINESS_ERR(
268             ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of bundleName must be string.");
269     });
270 
271     ASSERT_NULL(!ctxt->isThrowError, "NotifyDataChange exit");
272 
273     auto execute = [ctxt]() {
274         auto [state, proxy] = CloudManager::GetInstance().GetCloudService();
275         if (proxy == nullptr) {
276             if (state != CloudService::SERVER_UNAVAILABLE) {
277                 state = CloudService::NOT_SUPPORT;
278             }
279             ctxt->status = (GenerateNapiError(state, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
280                                ? napi_ok
281                                : napi_generic_failure;
282             return;
283         }
284         int32_t cStatus = proxy->NotifyDataChange(ctxt->accountId, ctxt->bundleName);
285         LOG_DEBUG("NotifyDataChange return %{public}d", cStatus);
286         ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS)
287                            ? napi_ok
288                            : napi_generic_failure;
289     };
290     return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute);
291 }
292 
New(napi_env env,napi_callback_info info)293 napi_value JsConfig::New(napi_env env, napi_callback_info info)
294 {
295     napi_value self = nullptr;
296     size_t argc = ARGC_MAX;
297     napi_value argv[ARGC_MAX] = { 0 };
298     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
299     if (self == nullptr) {
300         napi_new_instance(env, JSUtils::GetClass(env, "ohos.cloudData", "Config"), argc, argv, &self);
301         return self;
302     }
303 
304     auto finalize = [](napi_env env, void *data, void *hint) {
305         LOG_DEBUG("cloudConfig finalize.");
306         auto *config = reinterpret_cast<JsConfig *>(data);
307         ASSERT_VOID(config != nullptr, "finalize null!");
308         delete config;
309     };
310     JsConfig *cloudConfig = new (std::nothrow) JsConfig();
311     ASSERT_ERR(env, cloudConfig != nullptr, Status::INVALID_ARGUMENT, "no memory for cloudConfig.");
312     napi_status status = napi_wrap(env, self, cloudConfig, finalize, nullptr, nullptr);
313     if (status != napi_ok) {
314         LOG_ERROR("JsConfig::Initialize napi_wrap failed! code:%{public}d!", status);
315         finalize(env, cloudConfig, nullptr);
316         return nullptr;
317     }
318     return self;
319 }
320 
InitConfig(napi_env env,napi_value exports)321 napi_value JsConfig::InitConfig(napi_env env, napi_value exports)
322 {
323     auto lambda = []() -> std::vector<napi_property_descriptor> {
324         std::vector<napi_property_descriptor> properties = {
325             DECLARE_NAPI_STATIC_FUNCTION("enableCloud", JsConfig::EnableCloud),
326             DECLARE_NAPI_STATIC_FUNCTION("disableCloud", JsConfig::DisableCloud),
327             DECLARE_NAPI_STATIC_FUNCTION("changeAppCloudSwitch", JsConfig::ChangeAppCloudSwitch),
328             DECLARE_NAPI_STATIC_FUNCTION("clear", JsConfig::Clean),
329             DECLARE_NAPI_STATIC_FUNCTION("clean", JsConfig::Clean),
330             DECLARE_NAPI_STATIC_FUNCTION("notifyDataChange", JsConfig::NotifyDataChange),
331         };
332         return properties;
333     };
334     auto jsCtor = JSUtils::DefineClass(env, "ohos.data.cloudData", "Config", lambda, JsConfig::New);
335     NAPI_CALL(env, napi_set_named_property(env, exports, "Config", jsCtor));
336     return exports;
337 }