1 /*
2 * Copyright (c) 2021-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 "napi_distributed_account.h"
17 #include <map>
18 #include <string>
19 #include <unistd.h>
20 #include "account_log_wrapper.h"
21 #include "account_permission_manager.h"
22 #include "js_native_api.h"
23 #include "js_native_api_types.h"
24 #include "napi_account_common.h"
25 #include "napi/native_api.h"
26 #include "napi/native_common.h"
27 #include "napi/native_node_api.h"
28 #include "node_api.h"
29 #include "ohos_account_kits.h"
30 #include "napi_account_error.h"
31 #include "napi_common.h"
32
33 using namespace OHOS::AccountSA;
34
35 namespace OHOS {
36 namespace AccountJsKit {
37 constexpr std::int32_t PARAM_ZERO = 0;
38 constexpr std::int32_t PARAM_ONE = 1;
39 constexpr std::int32_t PARAM_TWO = 2;
40 constexpr std::int32_t ARGS_SIZE_ONE = 1;
41 constexpr std::int32_t ARGS_SIZE_TWO = 2;
42 constexpr std::int32_t ARGS_SIZE_THREE = 3;
43 constexpr int RESULT_COUNT = 2;
44 const std::string DISTRIBUTED_ACCOUNT_CLASS_NAME = "DistributedAccountAbility";
45 const std::string PROPERTY_KEY_NAME = "name";
46 const std::string PROPERTY_KEY_ID = "id";
47 const std::string PROPERTY_KEY_EVENT = "event";
48 const std::string PROPERTY_KEY_NICKNAME = "nickname";
49 const std::string PROPERTY_KEY_AVATAR = "avatar";
50 const std::string PROPERTY_KEY_SCALABLE = "scalableData";
51 const std::string PROPERTY_KEY_STATUS = "status";
52
53 static thread_local napi_ref distributedAccountRef_ = nullptr;
54
DistributedAccountAsyncContext(napi_env napiEnv)55 DistributedAccountAsyncContext::DistributedAccountAsyncContext(napi_env napiEnv) : env(napiEnv)
56 {}
57
~DistributedAccountAsyncContext()58 DistributedAccountAsyncContext::~DistributedAccountAsyncContext()
59 {
60 if (callbackRef != nullptr) {
61 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, callbackRef));
62 callbackRef = nullptr;
63 }
64 }
65
DistributedAccountStatusConstructor(napi_env env)66 napi_value DistributedAccountStatusConstructor(napi_env env)
67 {
68 napi_value distributedAccountStatus = nullptr;
69 napi_value status1 = nullptr;
70 napi_value status2 = nullptr;
71 NAPI_CALL(env, napi_create_object(env, &distributedAccountStatus));
72 NAPI_CALL(env, napi_create_int32(env, static_cast<int32_t>(OHOS_ACCOUNT_STATE::ACCOUNT_STATE_UNBOUND), &status1));
73 NAPI_CALL(env, napi_create_int32(env, static_cast<int32_t>(OHOS_ACCOUNT_STATE::ACCOUNT_STATE_LOGIN), &status2));
74 NAPI_CALL(env, napi_set_named_property(env, distributedAccountStatus, "NOT_LOGGED_IN", status1));
75 NAPI_CALL(env, napi_set_named_property(env, distributedAccountStatus, "LOGGED_IN", status2));
76 return distributedAccountStatus;
77 }
78
ParseQueryOhosAccountInfoAsyncContext(napi_env env,napi_callback_info cbInfo,DistributedAccountAsyncContext * asyncContext)79 bool ParseQueryOhosAccountInfoAsyncContext(
80 napi_env env, napi_callback_info cbInfo, DistributedAccountAsyncContext *asyncContext)
81 {
82 size_t argc = ARGS_SIZE_ONE;
83 napi_value argv[ARGS_SIZE_ONE] = {nullptr};
84 NAPI_CALL_BASE(env, napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr), false);
85 if (argc >= ARGS_SIZE_ONE) {
86 if (!GetCallbackProperty(env, argv[PARAM_ZERO], asyncContext->callbackRef, 1)) {
87 ACCOUNT_LOGE("Get callbackRef failed.");
88 std::string errMsg = "Parameter error. The type of \"callback\" must be function";
89 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
90 return false;
91 }
92 }
93 return true;
94 }
95
GetAccountInfo(napi_env env,napi_value object,DistributedAccountAsyncContext * asyncContext)96 static bool GetAccountInfo(napi_env env, napi_value object, DistributedAccountAsyncContext *asyncContext)
97 {
98 if (!GetStringPropertyByKey(env, object, PROPERTY_KEY_NAME, asyncContext->ohosAccountInfo.name_)) {
99 ACCOUNT_LOGE("Failed to get DistributedInfo's %{public}s property", PROPERTY_KEY_NAME.c_str());
100 std::string errMsg = "Parameter error. The type of " + PROPERTY_KEY_NAME + " must be string";
101 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
102 return false;
103 }
104 if (!GetStringPropertyByKey(env, object, PROPERTY_KEY_ID, asyncContext->ohosAccountInfo.uid_)) {
105 ACCOUNT_LOGE("Failed to get DistributedInfo's %{public}s property", PROPERTY_KEY_ID.c_str());
106 std::string errMsg = "Parameter error. The type of " + PROPERTY_KEY_ID + " must be string";
107 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
108 return false;
109 }
110 if (!GetOptionalStringPropertyByKey(env, object, PROPERTY_KEY_NICKNAME, asyncContext->ohosAccountInfo.nickname_)) {
111 ACCOUNT_LOGE("Failed to get DistributedInfo's %{public}s property", PROPERTY_KEY_NICKNAME.c_str());
112 std::string errMsg = "Parameter error. The type of " + PROPERTY_KEY_NICKNAME + " must be string";
113 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
114 return false;
115 }
116 if (!GetOptionalStringPropertyByKey(env, object, PROPERTY_KEY_AVATAR, asyncContext->ohosAccountInfo.avatar_)) {
117 ACCOUNT_LOGE("Failed to get DistributedInfo's %{public}s property", PROPERTY_KEY_AVATAR.c_str());
118 std::string errMsg = "Parameter error. The type of " + PROPERTY_KEY_AVATAR + " must be string";
119 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
120 return false;
121 }
122 bool hasProp = false;
123 napi_has_named_property(env, object, "scalableData", &hasProp);
124 AAFwk::WantParams params;
125 if (hasProp) {
126 napi_value value = nullptr;
127 napi_get_named_property(env, object, "scalableData", &value);
128 napi_valuetype valuetype = napi_undefined;
129 NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false);
130 if ((valuetype == napi_undefined) || (valuetype == napi_null)) {
131 ACCOUNT_LOGI("the scalableData is undefined or null");
132 } else {
133 if (!AppExecFwk::UnwrapWantParams(env, value, params)) {
134 ACCOUNT_LOGE("Failed to get DistributedInfo's %{public}s property", PROPERTY_KEY_SCALABLE.c_str());
135 std::string errMsg = "Parameter error. The type of " + PROPERTY_KEY_SCALABLE + " must be object";
136 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
137 return false;
138 }
139 }
140 }
141 asyncContext->ohosAccountInfo.scalableData_.SetParams(params);
142 return true;
143 }
144
ParseInfoAndEvent(napi_env env,napi_value argv,DistributedAccountAsyncContext * asyncContext)145 static bool ParseInfoAndEvent(napi_env env, napi_value argv, DistributedAccountAsyncContext *asyncContext)
146 {
147 napi_valuetype valueType = napi_undefined;
148 NAPI_CALL_BASE(env, napi_typeof(env, argv, &valueType), false);
149 if (valueType != napi_object) {
150 ACCOUNT_LOGE("DistributedInfo is not an object.");
151 std::string errMsg = "Parameter error. The type of \"accountInfo\" must be DistributedInfo";
152 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
153 return false;
154 }
155 if (!GetAccountInfo(env, argv, asyncContext)) {
156 return false;
157 }
158 if (!GetStringPropertyByKey(env, argv, PROPERTY_KEY_EVENT, asyncContext->event)) {
159 ACCOUNT_LOGE("Failed to get DistributedInfo's %{public}s property", PROPERTY_KEY_EVENT.c_str());
160 std::string errMsg = "Parameter error. The type of " + PROPERTY_KEY_EVENT + " must be string";
161 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
162 return false;
163 }
164 return true;
165 }
166
ParseUpdateOhosAccountInfoAsyncContext(napi_env env,napi_callback_info cbInfo,DistributedAccountAsyncContext * asyncContext)167 bool ParseUpdateOhosAccountInfoAsyncContext(
168 napi_env env, napi_callback_info cbInfo, DistributedAccountAsyncContext *asyncContext)
169 {
170 size_t argc = ARGS_SIZE_TWO;
171 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
172 NAPI_CALL_BASE(env, napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr), false);
173 if (argc < ARGS_SIZE_ONE) {
174 ACCOUNT_LOGE("The number of parameters should be at least 1.");
175 std::string errMsg = "Parameter error. The number of parameters should be at least 1";
176 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
177 return false;
178 }
179 if (argc >= ARGS_SIZE_TWO) {
180 if (!GetCallbackProperty(env, argv[PARAM_ONE], asyncContext->callbackRef, 1)) {
181 ACCOUNT_LOGE("Get callbackRef failed.");
182 std::string errMsg = "Parameter error. The type of \"callback\" must be function";
183 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
184 return false;
185 }
186 }
187 return ParseInfoAndEvent(env, argv[PARAM_ZERO], asyncContext);
188 }
189
ProcessCallbackOrPromise(napi_env env,const DistributedAccountAsyncContext * asyncContext,napi_value err,napi_value data)190 void ProcessCallbackOrPromise(
191 napi_env env, const DistributedAccountAsyncContext *asyncContext, napi_value err, napi_value data)
192 {
193 if (asyncContext->deferred != nullptr) {
194 if (asyncContext->errCode == ERR_OK) {
195 napi_resolve_deferred(env, asyncContext->deferred, data);
196 } else {
197 napi_reject_deferred(env, asyncContext->deferred, err);
198 }
199 } else {
200 napi_value args[RESULT_COUNT] = { err, data };
201 napi_value callback = nullptr;
202 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
203 napi_value returnVal = nullptr;
204 napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &returnVal);
205 }
206 }
207
ProcessSetNamedProperty(napi_env env,const DistributedAccountAsyncContext * asyncContext)208 void ProcessSetNamedProperty(napi_env env, const DistributedAccountAsyncContext *asyncContext)
209 {
210 napi_value result[RESULT_COUNT] = {0};
211 if (asyncContext->errCode == ERR_OK) {
212 if (asyncContext->throwErr) {
213 napi_get_null(env, &result[0]);
214 } else {
215 napi_get_undefined(env, &result[0]);
216 }
217 napi_create_object(env, &result[1]);
218 napi_value value = nullptr;
219 napi_create_string_utf8(env, asyncContext->ohosAccountInfo.name_.c_str(),
220 asyncContext->ohosAccountInfo.name_.size(), &value);
221 napi_set_named_property(env, result[1], PROPERTY_KEY_NAME.c_str(), value);
222 napi_create_string_utf8(env, asyncContext->ohosAccountInfo.uid_.c_str(),
223 asyncContext->ohosAccountInfo.uid_.size(), &value);
224 napi_set_named_property(env, result[1], PROPERTY_KEY_ID.c_str(), value);
225 napi_create_string_utf8(env, asyncContext->event.c_str(), asyncContext->event.size(), &value);
226 napi_set_named_property(env, result[1], PROPERTY_KEY_EVENT.c_str(), value);
227 napi_create_string_utf8(env, asyncContext->ohosAccountInfo.nickname_.c_str(),
228 asyncContext->ohosAccountInfo.nickname_.size(), &value);
229 napi_set_named_property(env, result[1], PROPERTY_KEY_NICKNAME.c_str(), value);
230 napi_create_string_utf8(env, asyncContext->ohosAccountInfo.avatar_.c_str(),
231 asyncContext->ohosAccountInfo.avatar_.size(), &value);
232 napi_set_named_property(env, result[1], PROPERTY_KEY_AVATAR.c_str(), value);
233 napi_create_int32(env, asyncContext->ohosAccountInfo.status_, &value);
234 napi_set_named_property(env, result[1], PROPERTY_KEY_STATUS.c_str(), value);
235 napi_value scalable = nullptr;
236 napi_create_object(env, &scalable);
237 scalable = AppExecFwk::WrapWantParams(env, (asyncContext->ohosAccountInfo.scalableData_).GetParams());
238 napi_set_named_property(env, result[1], PROPERTY_KEY_SCALABLE.c_str(), scalable);
239 } else {
240 if (asyncContext->throwErr) {
241 result[0] = GenerateBusinessError(env, asyncContext->errCode);
242 napi_get_null(env, &result[1]);
243 } else {
244 napi_value message = nullptr;
245 napi_create_string_utf8(env, "query ohos account info failed", NAPI_AUTO_LENGTH, &message);
246 napi_create_error(env, nullptr, message, &result[0]);
247 napi_get_undefined(env, &result[1]);
248 }
249 }
250 ProcessCallbackOrPromise(env, asyncContext, result[0], result[1]);
251 }
252
Init(napi_env env,napi_value exports)253 napi_value NapiDistributedAccount::Init(napi_env env, napi_value exports)
254 {
255 napi_property_descriptor descriptor[] = {
256 DECLARE_NAPI_FUNCTION("getDistributedAccountAbility", GetDistributedAccountAbility),
257 DECLARE_NAPI_PROPERTY("DistributedAccountStatus", DistributedAccountStatusConstructor(env)),
258 };
259 napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor);
260
261 napi_property_descriptor properties[] = {
262 DECLARE_NAPI_FUNCTION("queryOsAccountDistributedInfo", QueryOsAccountDistributedInfo),
263 DECLARE_NAPI_FUNCTION("getOsAccountDistributedInfo", GetOsAccountDistributedInfo),
264 DECLARE_NAPI_FUNCTION("updateOsAccountDistributedInfo", UpdateOsAccountDistributedInfo),
265 DECLARE_NAPI_FUNCTION("setOsAccountDistributedInfo", SetOsAccountDistributedInfo),
266 DECLARE_NAPI_FUNCTION("getOsAccountDistributedInfoByLocalId", GetOsAccountDistributedInfoByLocalId),
267 DECLARE_NAPI_FUNCTION("setOsAccountDistributedInfoByLocalId", SetOsAccountDistributedInfoByLocalId),
268 DECLARE_NAPI_FUNCTION("setCurrentOsAccountDistributedInfo", SetCurrentOsAccountDistributedInfo),
269 };
270 napi_value cons = nullptr;
271 napi_define_class(env, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), DISTRIBUTED_ACCOUNT_CLASS_NAME.size(),
272 JsConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons);
273 napi_create_reference(env, cons, 1, &distributedAccountRef_);
274 napi_set_named_property(env, exports, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), cons);
275
276 return exports;
277 }
278
JsConstructor(napi_env env,napi_callback_info cbinfo)279 napi_value NapiDistributedAccount::JsConstructor(napi_env env, napi_callback_info cbinfo)
280 {
281 napi_value thisVar = nullptr;
282 napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr);
283 return thisVar;
284 }
285
GetDistributedAccountAbility(napi_env env,napi_callback_info cbInfo)286 napi_value NapiDistributedAccount::GetDistributedAccountAbility(napi_env env, napi_callback_info cbInfo)
287 {
288 napi_value instance = nullptr;
289 napi_value cons = nullptr;
290 if (napi_get_reference_value(env, distributedAccountRef_, &cons) != napi_ok) {
291 return nullptr;
292 }
293
294 if (napi_new_instance(env, cons, 0, nullptr, &instance) != napi_ok) {
295 return nullptr;
296 }
297
298 return instance;
299 }
300
QueryOsAccountDistributedInfo(napi_env env,napi_callback_info cbInfo)301 napi_value NapiDistributedAccount::QueryOsAccountDistributedInfo(napi_env env, napi_callback_info cbInfo)
302 {
303 return QueryOhosAccountInfo(env, cbInfo, false);
304 }
305
GetOsAccountDistributedInfo(napi_env env,napi_callback_info cbInfo)306 napi_value NapiDistributedAccount::GetOsAccountDistributedInfo(napi_env env, napi_callback_info cbInfo)
307 {
308 return QueryOhosAccountInfo(env, cbInfo, true);
309 }
310
QueryOhosAccountInfoExecuteCB(napi_env env,void * data)311 static void QueryOhosAccountInfoExecuteCB(napi_env env, void *data)
312 {
313 DistributedAccountAsyncContext *asyncContext = reinterpret_cast<DistributedAccountAsyncContext *>(data);
314 if (!asyncContext->throwErr) {
315 std::pair<bool, OhosAccountInfo> accountInfo = OhosAccountKits::GetInstance().QueryOhosAccountInfo();
316 if (accountInfo.first) {
317 asyncContext->ohosAccountInfo.name_ = accountInfo.second.name_;
318 asyncContext->ohosAccountInfo.uid_ = accountInfo.second.uid_;
319 asyncContext->ohosAccountInfo.status_ = accountInfo.second.status_;
320 asyncContext->errCode = napi_ok;
321 } else {
322 asyncContext->errCode = napi_generic_failure;
323 }
324 } else if (!asyncContext->withLocalId) {
325 asyncContext->errCode = OhosAccountKits::GetInstance().GetOhosAccountInfo(asyncContext->ohosAccountInfo);
326 } else {
327 asyncContext->errCode = OhosAccountKits::GetInstance().GetOhosAccountInfoByUserId(
328 asyncContext->localId, asyncContext->ohosAccountInfo);
329 }
330 }
331
QueryOhosAccountInfoCompletedCB(napi_env env,napi_status status,void * data)332 static void QueryOhosAccountInfoCompletedCB(napi_env env, napi_status status, void *data)
333 {
334 DistributedAccountAsyncContext *asyncContext = reinterpret_cast<DistributedAccountAsyncContext *>(data);
335 ProcessSetNamedProperty(env, asyncContext);
336 napi_delete_async_work(env, asyncContext->work);
337 delete asyncContext;
338 }
339
QueryOhosAccountInfo(napi_env env,napi_callback_info cbInfo,bool throwErr)340 napi_value NapiDistributedAccount::QueryOhosAccountInfo(napi_env env, napi_callback_info cbInfo, bool throwErr)
341 {
342 auto *asyncContext = new (std::nothrow) DistributedAccountAsyncContext(env);
343 if (asyncContext == nullptr) {
344 ACCOUNT_LOGE("insufficient memory for asyncContext!");
345 return nullptr;
346 }
347 std::unique_ptr<DistributedAccountAsyncContext> contextPtr(asyncContext);
348 asyncContext->throwErr = throwErr;
349 asyncContext->withLocalId = false;
350 if (!ParseQueryOhosAccountInfoAsyncContext(env, cbInfo, asyncContext) && throwErr) {
351 return nullptr;
352 }
353 napi_value result = nullptr;
354 if (asyncContext->callbackRef == nullptr) {
355 NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
356 }
357 napi_value resource = nullptr;
358 NAPI_CALL(env, napi_create_string_utf8(env, "QueryOhosAccountInfo", NAPI_AUTO_LENGTH, &resource));
359 NAPI_CALL(env, napi_create_async_work(env,
360 nullptr,
361 resource,
362 QueryOhosAccountInfoExecuteCB,
363 QueryOhosAccountInfoCompletedCB,
364 reinterpret_cast<void *>(asyncContext), &asyncContext->work));
365 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_default));
366 contextPtr.release();
367 return result;
368 }
369
UpdateOsAccountDistributedInfo(napi_env env,napi_callback_info cbInfo)370 napi_value NapiDistributedAccount::UpdateOsAccountDistributedInfo(napi_env env, napi_callback_info cbInfo)
371 {
372 return UpdateOhosAccountInfo(env, cbInfo, false);
373 }
374
SetOsAccountDistributedInfo(napi_env env,napi_callback_info cbInfo)375 napi_value NapiDistributedAccount::SetOsAccountDistributedInfo(napi_env env, napi_callback_info cbInfo)
376 {
377 return UpdateOhosAccountInfo(env, cbInfo, true);
378 }
379
SetCurrentOsAccountDistributedInfo(napi_env env,napi_callback_info cbInfo)380 napi_value NapiDistributedAccount::SetCurrentOsAccountDistributedInfo(napi_env env, napi_callback_info cbInfo)
381 {
382 if (AccountPermissionManager::CheckSystemApp(false) != ERR_OK) {
383 AccountNapiThrow(env, ERR_JS_IS_NOT_SYSTEM_APP);
384 return nullptr;
385 }
386 return UpdateOhosAccountInfo(env, cbInfo, true);
387 }
388
UpdateOhosAccountInfoExecuteCB(napi_env env,void * data)389 static void UpdateOhosAccountInfoExecuteCB(napi_env env, void *data)
390 {
391 DistributedAccountAsyncContext *context = reinterpret_cast<DistributedAccountAsyncContext *>(data);
392 if (!context->throwErr) {
393 context->errCode = OhosAccountKits::GetInstance().UpdateOhosAccountInfo(context->ohosAccountInfo.name_,
394 context->ohosAccountInfo.uid_, context->event) ? napi_ok: napi_generic_failure;
395 } else if (context->withLocalId) {
396 context->errCode = OhosAccountKits::GetInstance().SetOhosAccountInfoByUserId(
397 context->localId, context->ohosAccountInfo, context->event);
398 } else {
399 context->errCode = OhosAccountKits::GetInstance().SetOhosAccountInfo(context->ohosAccountInfo, context->event);
400 }
401 }
402
UpdateOhosAccountInfoCompletedCB(napi_env env,napi_status status,void * data)403 static void UpdateOhosAccountInfoCompletedCB(napi_env env, napi_status status, void *data)
404 {
405 DistributedAccountAsyncContext *asyncContext = reinterpret_cast<DistributedAccountAsyncContext *>(data);
406 napi_value result[RESULT_COUNT] = {0};
407 if (asyncContext->errCode == ERR_OK) {
408 if (asyncContext->throwErr) {
409 napi_get_null(env, &result[0]);
410 napi_get_null(env, &result[1]);
411 } else {
412 napi_get_undefined(env, &result[1]);
413 }
414 } else if (asyncContext->throwErr) {
415 result[0] = GenerateBusinessError(env, asyncContext->errCode);
416 } else {
417 napi_value message = nullptr;
418 napi_create_string_utf8(env, "Update distributed account info failed", NAPI_AUTO_LENGTH, &message);
419 napi_create_error(env, nullptr, message, &result[0]);
420 }
421 ProcessCallbackOrPromise(env, asyncContext, result[0], result[1]);
422 napi_delete_async_work(env, asyncContext->work);
423 delete asyncContext;
424 }
425
ParseSetOsAccountDistributedInfoByLocalId(napi_env env,napi_callback_info cbInfo,DistributedAccountAsyncContext * asyncContext)426 static bool ParseSetOsAccountDistributedInfoByLocalId(napi_env env, napi_callback_info cbInfo,
427 DistributedAccountAsyncContext *asyncContext)
428 {
429 size_t argc = ARGS_SIZE_THREE;
430 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
431 NAPI_CALL_BASE(env, napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr), false);
432 if (argc < ARGS_SIZE_TWO) {
433 ACCOUNT_LOGE("The number of parameters should be at least 2.");
434 std::string errMsg = "Parameter error. The number of parameters should be at least 2";
435 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
436 return false;
437 }
438 if (argc >= ARGS_SIZE_THREE) {
439 if (!GetCallbackProperty(env, argv[PARAM_TWO], asyncContext->callbackRef, 1)) {
440 ACCOUNT_LOGE("Get callbackRef failed.");
441 std::string errMsg = "Parameter error. The type of \"callback\" must be function";
442 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
443 return false;
444 }
445 }
446 if (!GetIntProperty(env, argv[PARAM_ZERO], asyncContext->localId)) {
447 ACCOUNT_LOGE("Get localId failed.");
448 std::string errMsg = "Parameter error. The type of \"localId\" must be number";
449 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
450 return false;
451 }
452 return ParseInfoAndEvent(env, argv[PARAM_ONE], asyncContext);
453 }
454
SetOsAccountDistributedInfoByLocalId(napi_env env,napi_callback_info cbInfo)455 napi_value NapiDistributedAccount::SetOsAccountDistributedInfoByLocalId(napi_env env, napi_callback_info cbInfo)
456 {
457 auto *asyncContext = new (std::nothrow) DistributedAccountAsyncContext(env);
458 if (asyncContext == nullptr) {
459 ACCOUNT_LOGE("Insufficient memory for asyncContext!");
460 return nullptr;
461 }
462 std::unique_ptr<DistributedAccountAsyncContext> contextPtr(asyncContext);
463 asyncContext->throwErr = true;
464 asyncContext->withLocalId = true;
465 if (!ParseSetOsAccountDistributedInfoByLocalId(env, cbInfo, asyncContext)) {
466 return nullptr;
467 }
468 napi_value result = nullptr;
469 if (asyncContext->callbackRef == nullptr) {
470 NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
471 }
472 napi_value resource = nullptr;
473 NAPI_CALL(env, napi_create_string_utf8(env, "SetOsAccountDistributedInfoByLocalId", NAPI_AUTO_LENGTH, &resource));
474 NAPI_CALL(env, napi_create_async_work(env,
475 nullptr,
476 resource,
477 UpdateOhosAccountInfoExecuteCB,
478 UpdateOhosAccountInfoCompletedCB,
479 reinterpret_cast<void *>(asyncContext), &asyncContext->work));
480 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_default));
481 contextPtr.release();
482 return result;
483 }
484
ParseGetOsAccountDistributedInfoByLocalId(napi_env env,napi_callback_info cbInfo,DistributedAccountAsyncContext * asyncContext)485 static bool ParseGetOsAccountDistributedInfoByLocalId(napi_env env, napi_callback_info cbInfo,
486 DistributedAccountAsyncContext *asyncContext)
487 {
488 size_t argc = ARGS_SIZE_TWO;
489 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
490 NAPI_CALL_BASE(env, napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr), false);
491 if (argc < ARGS_SIZE_ONE) {
492 ACCOUNT_LOGE("The number of parameters should be at least 1.");
493 std::string errMsg = "Parameter error. The number of parameters should be at least 1";
494 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
495 return false;
496 }
497 if (argc >= ARGS_SIZE_TWO) {
498 if (!GetCallbackProperty(env, argv[PARAM_ONE], asyncContext->callbackRef, 1)) {
499 ACCOUNT_LOGE("Get callbackRef failed.");
500 std::string errMsg = "Parameter error. The type of \"callback\" must be function";
501 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
502 return false;
503 }
504 }
505 if (!GetIntProperty(env, argv[PARAM_ZERO], asyncContext->localId)) {
506 ACCOUNT_LOGE("Get localId failed.");
507 std::string errMsg = "Parameter error. The type of \"localId\" must be number";
508 AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, asyncContext->throwErr);
509 return false;
510 }
511 return true;
512 }
513
GetOsAccountDistributedInfoByLocalId(napi_env env,napi_callback_info cbInfo)514 napi_value NapiDistributedAccount::GetOsAccountDistributedInfoByLocalId(napi_env env, napi_callback_info cbInfo)
515 {
516 auto *asyncContext = new (std::nothrow) DistributedAccountAsyncContext(env);
517 if (asyncContext == nullptr) {
518 ACCOUNT_LOGE("Insufficient memory for asyncContext.");
519 return nullptr;
520 }
521 std::unique_ptr<DistributedAccountAsyncContext> contextPtr(asyncContext);
522 asyncContext->throwErr = true;
523 asyncContext->withLocalId = true;
524 if (!ParseGetOsAccountDistributedInfoByLocalId(env, cbInfo, asyncContext)) {
525 return nullptr;
526 }
527 napi_value result = nullptr;
528 if (asyncContext->callbackRef == nullptr) {
529 NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
530 }
531 napi_value resource = nullptr;
532 NAPI_CALL(env, napi_create_string_utf8(env, "GetOsAccountDistributedInfoByLocalId", NAPI_AUTO_LENGTH, &resource));
533 NAPI_CALL(env, napi_create_async_work(env,
534 nullptr,
535 resource,
536 QueryOhosAccountInfoExecuteCB,
537 QueryOhosAccountInfoCompletedCB,
538 reinterpret_cast<void *>(asyncContext), &asyncContext->work));
539 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_default));
540 contextPtr.release();
541 return result;
542 }
543
UpdateOhosAccountInfo(napi_env env,napi_callback_info cbInfo,bool throwErr)544 napi_value NapiDistributedAccount::UpdateOhosAccountInfo(napi_env env, napi_callback_info cbInfo, bool throwErr)
545 {
546 auto *asyncContext = new (std::nothrow) DistributedAccountAsyncContext(env);
547 if (asyncContext == nullptr) {
548 ACCOUNT_LOGE("insufficient memory for asyncContext!");
549 return nullptr;
550 }
551 asyncContext->throwErr = throwErr;
552 std::unique_ptr<DistributedAccountAsyncContext> contextPtr(asyncContext);
553 if (!ParseUpdateOhosAccountInfoAsyncContext(env, cbInfo, asyncContext) && throwErr) {
554 return nullptr;
555 }
556 napi_value result = nullptr;
557 if (asyncContext->callbackRef == nullptr) {
558 NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
559 }
560 napi_value resource = nullptr;
561 NAPI_CALL(env, napi_create_string_utf8(env, "UpdateOhosAccountInfo", NAPI_AUTO_LENGTH, &resource));
562 NAPI_CALL(env, napi_create_async_work(env,
563 nullptr,
564 resource,
565 UpdateOhosAccountInfoExecuteCB,
566 UpdateOhosAccountInfoCompletedCB,
567 reinterpret_cast<void *>(asyncContext), &asyncContext->work));
568 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_default));
569 contextPtr.release();
570 return result;
571 }
572 } // namespace AccountJsKit
573 } // namespace OHOS
574
575 EXTERN_C_START
576 /*
577 * function for module exports
578 */
Init(napi_env env,napi_value exports)579 static napi_value Init(napi_env env, napi_value exports)
580 {
581 return OHOS::AccountJsKit::NapiDistributedAccount::Init(env, exports);
582 }
583 EXTERN_C_END
584
585 /*
586 * module define
587 */
588 static napi_module _module = {
589 .nm_version = 1,
590 .nm_flags = 0,
591 .nm_filename = nullptr,
592 .nm_register_func = Init,
593 .nm_modname = "account.distributedAccount",
594 .nm_priv = ((void*)0),
595 .reserved = {0}
596 };
597 /*
598 * module register
599 */
Register()600 extern "C" __attribute__((constructor)) void Register()
601 {
602 napi_module_register(&_module);
603 }
604