1 /*
2 * Copyright (c) 2021-2022 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_form_host.h"
17
18 #include <cinttypes>
19 #include <regex>
20 #include <typeinfo>
21 #include <uv.h>
22 #include <vector>
23 #include <iostream>
24 #include <string>
25
26 #include "form_info.h"
27 #include "form_callback_interface.h"
28 #include "form_host_client.h"
29 #include "form_mgr.h"
30 #include "form_mgr_errors.h"
31 #include "hilog_wrapper.h"
32 #include "napi_form_util.h"
33 #include "napi/native_api.h"
34 #include "napi/native_node_api.h"
35 #include "napi_common_util.h"
36 #include "napi_common_want.h"
37 #include "runtime.h"
38
39 namespace OHOS {
40 namespace AbilityRuntime {
41 using namespace OHOS;
42 using namespace OHOS::AAFwk;
43 using namespace OHOS::AppExecFwk;
44
45 namespace {
46 constexpr size_t ARGS_SIZE_ONE = 1;
47 constexpr size_t ARGS_SIZE_TWO = 2;
48 constexpr size_t ARGS_SIZE_THREE = 3;
49 constexpr int REF_COUNT = 1;
50 constexpr int CALLBACK_FLG = 1;
51 constexpr int PROMISE_FLG = 2;
52 // NANOSECONDS mean 10^9 nano second
53 constexpr int64_t NANOSECONDS = 1000000000;
54 // MICROSECONDS mean 10^6 millias second
55 constexpr int64_t MICROSECONDS = 1000000;
56 }
57
58 /**
59 * @brief Get a C++ string value from Node-API
60 *
61 * @param[in] env The environment that the Node-API call is invoked under
62 * @param[in] value This is an opaque pointer that is used to represent a JavaScript value
63 *
64 * @return Return a C++ string
65 */
GetStringFromNAPI(napi_env env,napi_value value)66 static std::string GetStringFromNAPI(napi_env env, napi_value value)
67 {
68 std::string result;
69 size_t size = 0;
70
71 if (napi_get_value_string_utf8(env, value, nullptr, 0, &size) != napi_ok) {
72 HILOG_ERROR("%{public}s, can not get string size", __func__);
73 return "";
74 }
75 result.reserve(size + 1);
76 result.resize(size);
77 if (napi_get_value_string_utf8(env, value, result.data(), (size + 1), &size) != napi_ok) {
78 HILOG_ERROR("%{public}s, can not get string value", __func__);
79 return "";
80 }
81 return result;
82 }
83
GetFormIds(napi_env env,napi_value value,ErrCode & errCode,std::vector<int64_t> & formIds)84 static napi_value GetFormIds(napi_env env, napi_value value, ErrCode &errCode, std::vector<int64_t> &formIds)
85 {
86 errCode = ERR_INVALID_VALUE;
87
88 bool isArray;
89 NAPI_CALL(env, napi_is_array(env, value, &isArray));
90 if (!isArray) {
91 errCode = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR;
92 return nullptr;
93 }
94
95 uint32_t arrayLength = 0;
96 NAPI_CALL(env, napi_get_array_length(env, value, &arrayLength));
97
98 for (size_t i = 0; i < arrayLength; i++) {
99 napi_value napiFormId;
100 napi_get_element(env, value, i, &napiFormId);
101
102 // Check the value type of the arguments
103 napi_valuetype valueType = napi_undefined;
104 NAPI_CALL(env, napi_typeof(env, napiFormId, &valueType));
105 if (valueType != napi_string) {
106 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
107 return nullptr;
108 }
109
110 std::string strFormId = GetStringFromNAPI(env, napiFormId);
111 int64_t formIdValue;
112 if (!ConvertStringToInt64(strFormId, formIdValue)) {
113 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
114 return nullptr;
115 }
116
117 formIds.push_back(formIdValue);
118 }
119
120 errCode = ERR_OK;
121 return nullptr;
122 }
123
124
125 /**
126 * @brief Call native kit function: NotifyVisibleForms
127 *
128 * @param[in] env The environment that the Node-API call is invoked under
129 * @param[out] asyncCallbackInfo Reference, callback info via Node-API
130 *
131 * @return void
132 */
InnerNotifyVisibleForms(napi_env env,AsyncNotifyVisibleFormsCallbackInfo * const asyncCallbackInfo)133 static void InnerNotifyVisibleForms(napi_env env, AsyncNotifyVisibleFormsCallbackInfo* const asyncCallbackInfo)
134 {
135 HILOG_DEBUG("%{public}s called.", __func__);
136 asyncCallbackInfo->result = FormMgr::GetInstance().NotifyWhetherVisibleForms(asyncCallbackInfo->formIds,
137 FormHostClient::GetInstance(), Constants::FORM_VISIBLE);
138 HILOG_DEBUG("%{public}s, end", __func__);
139 }
140
141 /**
142 * @brief The implementation of Node-API interface: notifyVisibleForms
143 *
144 * @param[in] env The environment that the Node-API call is invoked under
145 * @param[out] info An opaque datatype that is passed to a callback function
146 *
147 * @return This is an opaque pointer that is used to represent a JavaScript value
148 */
NAPI_NotifyVisibleForms(napi_env env,napi_callback_info info)149 napi_value NAPI_NotifyVisibleForms(napi_env env, napi_callback_info info)
150 {
151 HILOG_INFO("%{public}s called.", __func__);
152
153 // Check the number of the arguments
154 size_t argc = ARGS_SIZE_TWO;
155 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
156 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
157 if (argc > ARGS_SIZE_TWO) {
158 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
159 return nullptr;
160 }
161 HILOG_INFO("%{public}s, argc = [%{public}zu]", __func__, argc);
162
163 bool isArray;
164 NAPI_CALL(env, napi_is_array(env, argv[0], &isArray));
165 if (!isArray) {
166 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
167 AsyncErrMsgCallbackInfo {
168 .env = env,
169 .asyncWork = nullptr,
170 .deferred = nullptr,
171 .callback = nullptr,
172 .callbackValue = argv[1],
173 .code = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR,
174 .type = 0
175 };
176 if (argc == ARGS_SIZE_TWO) {
177 asyncErrorInfo->type = CALLBACK_FLG;
178 } else {
179 asyncErrorInfo->type = PROMISE_FLG;
180 }
181 return RetErrMsg(asyncErrorInfo);
182 }
183
184 uint32_t arrayLength = 0;
185 NAPI_CALL(env, napi_get_array_length(env, argv[0], &arrayLength));
186 if (arrayLength == 0) {
187 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
188 AsyncErrMsgCallbackInfo {
189 .env = env,
190 .asyncWork = nullptr,
191 .deferred = nullptr,
192 .callback = nullptr,
193 .callbackValue = argv[1],
194 .code = ERR_APPEXECFWK_FORM_FORM_ID_ARRAY_ERR,
195 .type = 0
196 };
197
198 if (argc == ARGS_SIZE_TWO) {
199 asyncErrorInfo->type = CALLBACK_FLG;
200 } else {
201 asyncErrorInfo->type = PROMISE_FLG;
202 }
203 return RetErrMsg(asyncErrorInfo);
204 }
205
206 std::vector<int64_t> formIds;
207 formIds.clear();
208 napi_valuetype valueType;
209 for (size_t i = 0; i < arrayLength; i++) {
210 napi_value napiFormId;
211 napi_get_element(env, argv[0], i, &napiFormId);
212
213 // Check the value type of the arguments
214 valueType = napi_undefined;
215 NAPI_CALL(env, napi_typeof(env, napiFormId, &valueType));
216 if (valueType != napi_string) {
217 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
218 AsyncErrMsgCallbackInfo {
219 .env = env,
220 .asyncWork = nullptr,
221 .deferred = nullptr,
222 .callback = nullptr,
223 .callbackValue = argv[1],
224 .code = ERR_APPEXECFWK_FORM_INVALID_FORM_ID,
225 .type = 0
226 };
227
228 if (argc == ARGS_SIZE_TWO) {
229 asyncErrorInfo->type = CALLBACK_FLG;
230 } else {
231 asyncErrorInfo->type = PROMISE_FLG;
232 }
233 return RetErrMsg(asyncErrorInfo);
234 }
235
236 std::string strFormId = GetStringFromNAPI(env, napiFormId);
237 int64_t formIdValue;
238 if (!ConvertStringToInt64(strFormId, formIdValue)) {
239 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
240 AsyncErrMsgCallbackInfo {
241 .env = env,
242 .asyncWork = nullptr,
243 .deferred = nullptr,
244 .callback = nullptr,
245 .callbackValue = argv[1],
246 .code = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR,
247 .type = 0
248 };
249
250 if (argc == ARGS_SIZE_TWO) {
251 asyncErrorInfo->type = CALLBACK_FLG;
252 } else {
253 asyncErrorInfo->type = PROMISE_FLG;
254 }
255 return RetErrMsg(asyncErrorInfo);
256 }
257
258 formIds.push_back(formIdValue);
259 }
260
261 AsyncNotifyVisibleFormsCallbackInfo *asyncCallbackInfo = new
262 AsyncNotifyVisibleFormsCallbackInfo {
263 .env = env,
264 .asyncWork = nullptr,
265 .deferred = nullptr,
266 .callback = nullptr,
267 .formIds = formIds,
268 .result = 1,
269 };
270 std::unique_ptr<AsyncNotifyVisibleFormsCallbackInfo> callbackPtr {asyncCallbackInfo};
271
272 if (argc == ARGS_SIZE_TWO) {
273 HILOG_INFO("%{public}s, asyncCallback.", __func__);
274
275 // Check the value type of the arguments
276 valueType = napi_undefined;
277 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
278 NAPI_ASSERT(env, valueType == napi_function, "The arguments[1] type of notifyVisibleForms is incorrect,"
279 "expected type is function.");
280
281 napi_create_reference(env, argv[1], REF_COUNT, &asyncCallbackInfo->callback);
282
283 napi_value resourceName;
284 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
285 napi_create_async_work(
286 env,
287 nullptr,
288 resourceName,
289 [](napi_env env, void *data) {
290 HILOG_INFO("%{public}s, napi_create_async_work running", __func__);
291
292 AsyncNotifyVisibleFormsCallbackInfo *asyncCallbackInfo =
293 (AsyncNotifyVisibleFormsCallbackInfo *)data;
294
295 InnerNotifyVisibleForms(env, asyncCallbackInfo);
296 },
297 [](napi_env env, napi_status status, void *data) {
298 AsyncNotifyVisibleFormsCallbackInfo *asyncCallbackInfo =
299 (AsyncNotifyVisibleFormsCallbackInfo *)data;
300
301 HILOG_INFO("%{public}s, napi_create_async_work complete", __func__);
302
303 if (asyncCallbackInfo->callback != nullptr) {
304 napi_value result[ARGS_SIZE_TWO] = {0};
305 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, result);
306 napi_value callback;
307 napi_value undefined;
308 napi_get_undefined(env, &undefined);
309 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
310 napi_value callResult;
311 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
312 napi_delete_reference(env, asyncCallbackInfo->callback);
313 }
314 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
315 delete asyncCallbackInfo;
316 },
317 (void *)asyncCallbackInfo,
318 &asyncCallbackInfo->asyncWork);
319 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
320 callbackPtr.release();
321 return NapiGetResult(env, 1);
322 } else {
323 HILOG_INFO("%{public}s, promise.", __func__);
324 napi_deferred deferred;
325 napi_value promise;
326 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
327 asyncCallbackInfo->deferred = deferred;
328
329 napi_value resourceName;
330 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
331 napi_create_async_work(
332 env,
333 nullptr,
334 resourceName,
335 [](napi_env env, void *data) {
336 HILOG_INFO("%{public}s, promise running", __func__);
337
338 AsyncNotifyVisibleFormsCallbackInfo *asyncCallbackInfo =
339 (AsyncNotifyVisibleFormsCallbackInfo *)data;
340
341 InnerNotifyVisibleForms(env, asyncCallbackInfo);
342 },
343 [](napi_env env, napi_status status, void *data) {
344 HILOG_INFO("%{public}s, promise complete", __func__);
345
346 AsyncNotifyVisibleFormsCallbackInfo *asyncCallbackInfo =
347 (AsyncNotifyVisibleFormsCallbackInfo *)data;
348
349 napi_value result;
350 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
351 if (asyncCallbackInfo->result == ERR_OK) {
352 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
353 } else {
354 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
355 }
356 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
357 delete asyncCallbackInfo;
358 },
359 (void *)asyncCallbackInfo,
360 &asyncCallbackInfo->asyncWork);
361 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
362 callbackPtr.release();
363 return promise;
364 }
365 }
366
367 /**
368 * @brief Call native kit function: NotifyInvisibleForms
369 *
370 * @param[in] env The environment that the Node-API call is invoked under
371 * @param[out] asyncCallbackInfo Reference, callback info via Node-API
372 *
373 * @return void
374 */
InnerNotifyInvisibleForms(napi_env env,AsyncNotifyInvisibleFormsCallbackInfo * const asyncCallbackInfo)375 static void InnerNotifyInvisibleForms(napi_env env, AsyncNotifyInvisibleFormsCallbackInfo* const asyncCallbackInfo)
376 {
377 HILOG_DEBUG("%{public}s called.", __func__);
378 asyncCallbackInfo->result = FormMgr::GetInstance().NotifyWhetherVisibleForms(asyncCallbackInfo->formIds,
379 FormHostClient::GetInstance(), Constants::FORM_INVISIBLE);
380 HILOG_DEBUG("%{public}s, end", __func__);
381 }
382
383 /**
384 * @brief The implementation of Node-API interface: notifyInvisibleForms
385 *
386 * @param[in] env The environment that the Node-API call is invoked under
387 * @param[out] info An opaque datatype that is passed to a callback function
388 *
389 * @return This is an opaque pointer that is used to represent a JavaScript value
390 */
NAPI_NotifyInvisibleForms(napi_env env,napi_callback_info info)391 napi_value NAPI_NotifyInvisibleForms(napi_env env, napi_callback_info info)
392 {
393 HILOG_INFO("%{public}s called.", __func__);
394
395 // Check the number of the arguments
396 size_t argc = ARGS_SIZE_TWO;
397 napi_value argv[ARGS_SIZE_TWO] = {nullptr};
398 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
399 if (argc > ARGS_SIZE_TWO) {
400 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
401 return nullptr;
402 }
403 HILOG_INFO("%{public}s, argc = [%{public}zu]", __func__, argc);
404
405 bool isArray;
406 NAPI_CALL(env, napi_is_array(env, argv[0], &isArray));
407 if (!isArray) {
408 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
409 AsyncErrMsgCallbackInfo {
410 .env = env,
411 .asyncWork = nullptr,
412 .deferred = nullptr,
413 .callback = nullptr,
414 .callbackValue = argv[1],
415 .code = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR,
416 .type = 0
417 };
418 if (argc == ARGS_SIZE_TWO) {
419 asyncErrorInfo->type = CALLBACK_FLG;
420 } else {
421 asyncErrorInfo->type = PROMISE_FLG;
422 }
423 return RetErrMsg(asyncErrorInfo);
424 }
425
426 uint32_t arrayLength = 0;
427 NAPI_CALL(env, napi_get_array_length(env, argv[0], &arrayLength));
428 if (arrayLength == 0) {
429 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
430 AsyncErrMsgCallbackInfo {
431 .env = env,
432 .asyncWork = nullptr,
433 .deferred = nullptr,
434 .callback = nullptr,
435 .callbackValue = argv[1],
436 .code = ERR_APPEXECFWK_FORM_FORM_ID_ARRAY_ERR,
437 .type = 0,
438 };
439
440 if (argc == ARGS_SIZE_TWO) {
441 asyncErrorInfo->type = CALLBACK_FLG;
442 } else {
443 asyncErrorInfo->type = PROMISE_FLG;
444 }
445 return RetErrMsg(asyncErrorInfo);
446 }
447
448 std::vector<int64_t> formIds;
449 formIds.clear();
450 napi_valuetype valueType;
451 for (size_t i = 0; i < arrayLength; i++) {
452 napi_value napiFormId;
453 napi_get_element(env, argv[0], i, &napiFormId);
454
455 // Check the value type of the arguments
456 valueType = napi_undefined;
457 NAPI_CALL(env, napi_typeof(env, napiFormId, &valueType));
458 if (valueType != napi_string) {
459 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
460 AsyncErrMsgCallbackInfo {
461 .env = env,
462 .asyncWork = nullptr,
463 .deferred = nullptr,
464 .callback = nullptr,
465 .callbackValue = argv[1],
466 .code = ERR_APPEXECFWK_FORM_INVALID_FORM_ID,
467 .type = 0,
468 };
469
470 if (argc == ARGS_SIZE_TWO) {
471 asyncErrorInfo->type = CALLBACK_FLG;
472 } else {
473 asyncErrorInfo->type = PROMISE_FLG;
474 }
475 return RetErrMsg(asyncErrorInfo);
476 }
477
478 std::string strFormId = GetStringFromNAPI(env, napiFormId);
479 int64_t formIdValue;
480 if (!ConvertStringToInt64(strFormId, formIdValue)) {
481 AsyncErrMsgCallbackInfo *asyncErrorInfo = new
482 AsyncErrMsgCallbackInfo {
483 .env = env,
484 .asyncWork = nullptr,
485 .deferred = nullptr,
486 .callback = nullptr,
487 .callbackValue = argv[1],
488 .code = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR,
489 .type = 0,
490 };
491
492 if (argc == ARGS_SIZE_TWO) {
493 asyncErrorInfo->type = CALLBACK_FLG;
494 } else {
495 asyncErrorInfo->type = PROMISE_FLG;
496 }
497 return RetErrMsg(asyncErrorInfo);
498 }
499
500 formIds.push_back(formIdValue);
501 }
502
503 AsyncNotifyInvisibleFormsCallbackInfo *asyncCallbackInfo = new
504 AsyncNotifyInvisibleFormsCallbackInfo {
505 .env = env,
506 .asyncWork = nullptr,
507 .deferred = nullptr,
508 .callback = nullptr,
509 .formIds = formIds,
510 .result = 1,
511 };
512 std::unique_ptr<AsyncNotifyInvisibleFormsCallbackInfo> callbackPtr {asyncCallbackInfo};
513
514 if (argc == ARGS_SIZE_TWO) {
515 HILOG_INFO("%{public}s, asyncCallback.", __func__);
516
517 // Check the value type of the arguments
518 valueType = napi_undefined;
519 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
520 NAPI_ASSERT(env, valueType == napi_function, "The arguments[1] type of notifyInvisibleForms is incorrect,"
521 "expected type is function.");
522
523 napi_create_reference(env, argv[1], REF_COUNT, &asyncCallbackInfo->callback);
524
525 napi_value resourceName;
526 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
527 napi_create_async_work(
528 env,
529 nullptr,
530 resourceName,
531 [](napi_env env, void *data) {
532 HILOG_INFO("%{public}s, napi_create_async_work running", __func__);
533
534 AsyncNotifyInvisibleFormsCallbackInfo *asyncCallbackInfo =
535 (AsyncNotifyInvisibleFormsCallbackInfo *)data;
536
537 InnerNotifyInvisibleForms(env, asyncCallbackInfo);
538 },
539 [](napi_env env, napi_status status, void *data) {
540 AsyncNotifyInvisibleFormsCallbackInfo *asyncCallbackInfo =
541 (AsyncNotifyInvisibleFormsCallbackInfo *)data;
542
543 HILOG_INFO("%{public}s, napi_create_async_work complete", __func__);
544
545 if (asyncCallbackInfo->callback != nullptr) {
546 napi_value result[ARGS_SIZE_TWO] = {0};
547 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, result);
548 napi_value callback;
549 napi_value undefined;
550 napi_get_undefined(env, &undefined);
551 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
552 napi_value callResult;
553 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
554 napi_delete_reference(env, asyncCallbackInfo->callback);
555 }
556 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
557 delete asyncCallbackInfo;
558 },
559 (void *)asyncCallbackInfo,
560 &asyncCallbackInfo->asyncWork);
561 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
562 callbackPtr.release();
563 return NapiGetResult(env, 1);
564 } else {
565 HILOG_INFO("%{public}s, promise.", __func__);
566 napi_deferred deferred;
567 napi_value promise;
568 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
569 asyncCallbackInfo->deferred = deferred;
570
571 napi_value resourceName;
572 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
573 napi_create_async_work(
574 env,
575 nullptr,
576 resourceName,
577 [](napi_env env, void *data) {
578 HILOG_INFO("%{public}s, promise running", __func__);
579
580 AsyncNotifyInvisibleFormsCallbackInfo *asyncCallbackInfo =
581 (AsyncNotifyInvisibleFormsCallbackInfo *)data;
582
583 InnerNotifyInvisibleForms(env, asyncCallbackInfo);
584 },
585 [](napi_env env, napi_status status, void *data) {
586 HILOG_INFO("%{public}s, promise complete", __func__);
587
588 AsyncNotifyInvisibleFormsCallbackInfo *asyncCallbackInfo =
589 (AsyncNotifyInvisibleFormsCallbackInfo *)data;
590
591 napi_value result;
592 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
593 if (asyncCallbackInfo->result == ERR_OK) {
594 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
595 } else {
596 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
597 }
598 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
599 delete asyncCallbackInfo;
600 },
601 (void *)asyncCallbackInfo,
602 &asyncCallbackInfo->asyncWork);
603 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
604 callbackPtr.release();
605 return promise;
606 }
607 }
608
InnerDeleteInvalidForms(napi_env env,AsyncDeleteInvalidFormsCallbackInfo * const asyncCallbackInfo)609 static void InnerDeleteInvalidForms(napi_env env, AsyncDeleteInvalidFormsCallbackInfo *const asyncCallbackInfo)
610 {
611 HILOG_DEBUG("%{public}s called.", __func__);
612
613 ErrCode ret = FormMgr::GetInstance().DeleteInvalidForms(asyncCallbackInfo->formIds,
614 FormHostClient::GetInstance(), asyncCallbackInfo->numFormsDeleted);
615 asyncCallbackInfo->result = ret;
616 if (ret != ERR_OK) {
617 asyncCallbackInfo->numFormsDeleted = 0;
618 }
619 HILOG_DEBUG("%{public}s, end", __func__);
620 }
621
DeleteInvalidFormsCallback(napi_env env,AsyncDeleteInvalidFormsCallbackInfo * const asyncCallbackInfo)622 napi_value DeleteInvalidFormsCallback(napi_env env, AsyncDeleteInvalidFormsCallbackInfo *const asyncCallbackInfo)
623 {
624 HILOG_INFO("%{public}s, asyncCallback.", __func__);
625 napi_value resourceName;
626 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
627 napi_create_async_work(
628 env,
629 nullptr,
630 resourceName,
631 [](napi_env env, void *data) {
632 HILOG_INFO("%{public}s, napi_create_async_work running", __func__);
633 auto *asyncCallbackInfo = (AsyncDeleteInvalidFormsCallbackInfo *) data;
634 InnerDeleteInvalidForms(env, asyncCallbackInfo);
635 },
636 [](napi_env env, napi_status status, void *data) {
637 HILOG_INFO("%{public}s, napi_create_async_work complete", __func__);
638 auto *asyncCallbackInfo = (AsyncDeleteInvalidFormsCallbackInfo *) data;
639
640 if (asyncCallbackInfo->callback != nullptr) {
641 napi_value callback;
642 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
643 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
644 if (asyncCallbackInfo->result == ERR_OK) {
645 napi_create_int32(env, asyncCallbackInfo->numFormsDeleted, &callbackValues[1]);
646 }
647
648 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
649 napi_value callResult;
650 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
651 napi_delete_reference(env, asyncCallbackInfo->callback);
652 }
653 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
654 delete asyncCallbackInfo;
655 },
656 (void *) asyncCallbackInfo,
657 &asyncCallbackInfo->asyncWork);
658 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
659 return NapiGetResult(env, 1);
660 }
661
DeleteInvalidFormsPromise(napi_env env,AsyncDeleteInvalidFormsCallbackInfo * const asyncCallbackInfo)662 napi_value DeleteInvalidFormsPromise(napi_env env, AsyncDeleteInvalidFormsCallbackInfo *const asyncCallbackInfo)
663 {
664 HILOG_INFO("%{public}s, promise.", __func__);
665 napi_deferred deferred;
666 napi_value promise;
667 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
668 asyncCallbackInfo->deferred = deferred;
669
670 napi_value resourceName;
671 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
672 napi_create_async_work(
673 env,
674 nullptr,
675 resourceName,
676 [](napi_env env, void *data) {
677 HILOG_INFO("%{public}s, promise runnning", __func__);
678 auto *asyncCallbackInfo = (AsyncDeleteInvalidFormsCallbackInfo *) data;
679 InnerDeleteInvalidForms(env, asyncCallbackInfo);
680 },
681 [](napi_env env, napi_status status, void *data) {
682 HILOG_INFO("%{public}s, promise complete", __func__);
683 auto *asyncCallbackInfo = (AsyncDeleteInvalidFormsCallbackInfo *) data;
684 if (asyncCallbackInfo->result != ERR_OK) {
685 napi_value result;
686 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
687 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
688 } else {
689 napi_value result;
690 napi_create_int32(env, asyncCallbackInfo->numFormsDeleted, &result);
691 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
692 }
693 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
694 delete asyncCallbackInfo;
695 },
696 (void *) asyncCallbackInfo,
697 &asyncCallbackInfo->asyncWork);
698 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
699 return promise;
700 }
701
702 /**
703 * @brief The implementation of Node-API interface: deleteInvalidForms
704 *
705 * @param[in] env The environment that the Node-API call is invoked under
706 * @param[out] info An opaque datatype that is passed to a callback function
707 *
708 * @return This is an opaque pointer that is used to represent a JavaScript value
709 */
NAPI_DeleteInvalidForms(napi_env env,napi_callback_info info)710 napi_value NAPI_DeleteInvalidForms(napi_env env, napi_callback_info info)
711 {
712 HILOG_INFO("%{public}s called.", __func__);
713
714 // Check the number of the arguments
715 size_t argc = ARGS_SIZE_TWO;
716 napi_value argv[ARGS_SIZE_TWO] = {nullptr, nullptr};
717 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
718 if (argc > ARGS_SIZE_TWO) {
719 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
720 return nullptr;
721 }
722
723 int32_t callbackType = (argc == ARGS_SIZE_TWO) ? CALLBACK_FLG : PROMISE_FLG;
724 bool isArray;
725 NAPI_CALL(env, napi_is_array(env, argv[0], &isArray));
726 if (!isArray) {
727 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR, callbackType, argv[1]));
728 }
729
730 uint32_t arrayLength = 0;
731 NAPI_CALL(env, napi_get_array_length(env, argv[0], &arrayLength));
732
733 std::vector<int64_t> formIds;
734 formIds.clear();
735 for (size_t i = 0; i < arrayLength; i++) {
736 napi_value napiFormId;
737 napi_get_element(env, argv[0], i, &napiFormId);
738
739 // Check the value type of the arguments
740 napi_valuetype valueType = napi_undefined;
741 NAPI_CALL(env, napi_typeof(env, napiFormId, &valueType));
742 if (valueType != napi_string) {
743 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_FORM_ID, callbackType, argv[1]));
744 }
745
746 std::string strFormId = GetStringFromNAPI(env, napiFormId);
747 int64_t formIdValue;
748 if (!ConvertStringToInt64(strFormId, formIdValue)) {
749 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR, callbackType, argv[1]));
750 }
751
752 formIds.push_back(formIdValue);
753 }
754
755 auto *asyncCallbackInfo = new (std::nothrow) AsyncDeleteInvalidFormsCallbackInfo {.env = env, .formIds = formIds, };
756 if (asyncCallbackInfo == nullptr) {
757 HILOG_ERROR("asyncCallbackInfo == nullptr.");
758 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackType, argv[1]));
759 }
760 std::unique_ptr<AsyncDeleteInvalidFormsCallbackInfo> callbackPtr {asyncCallbackInfo};
761
762 napi_value result;
763 if (argc == ARGS_SIZE_TWO) {
764 // Check the value type of the arguments
765 napi_valuetype valueType = napi_undefined;
766 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
767 NAPI_ASSERT(env, valueType == napi_function, "The type of args[1] is incorrect, expected type is function.");
768 napi_create_reference(env, argv[1], REF_COUNT, &asyncCallbackInfo->callback);
769 result = DeleteInvalidFormsCallback(env, asyncCallbackInfo);
770 } else {
771 result = DeleteInvalidFormsPromise(env, asyncCallbackInfo);
772 }
773 callbackPtr.release();
774 return result;
775 }
776
ParseFormStateInfo(napi_env env,FormStateInfo & stateInfo)777 napi_value ParseFormStateInfo(napi_env env, FormStateInfo &stateInfo)
778 {
779 napi_value formStateInfoObject = nullptr;
780 napi_create_object(env, &formStateInfoObject);
781 napi_value jsValue = WrapWant(env, stateInfo.want);
782 SetPropertyValueByPropertyName(env, formStateInfoObject, "want", jsValue);
783 napi_value formState = nullptr;
784 napi_create_int32(env, (int32_t) stateInfo.state, &formState);
785 SetPropertyValueByPropertyName(env, formStateInfoObject, "formState", formState);
786
787 return formStateInfoObject;
788 }
789
AcquireFormStateCallbackComplete(uv_work_t * work,int32_t status)790 void AcquireFormStateCallbackComplete(uv_work_t *work, int32_t status)
791 {
792 HILOG_INFO("%{public}s, onAcquireFormState back", __func__);
793 if (work == nullptr) {
794 HILOG_ERROR("work == nullptr.");
795 return;
796 }
797 auto *asyncCallbackInfo = static_cast<AsyncAcquireFormStateCallbackInfo *>(work->data);
798 if (asyncCallbackInfo == nullptr) {
799 HILOG_ERROR("asyncCallbackInfo == nullptr.");
800 delete work;
801 return;
802 }
803 napi_env env = asyncCallbackInfo->env;
804
805 if (asyncCallbackInfo->callback != nullptr) {
806 napi_value callback;
807 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
808 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
809 if (asyncCallbackInfo->result == ERR_OK) {
810 callbackValues[1] = ParseFormStateInfo(env, asyncCallbackInfo->stateInfo);
811 }
812
813 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
814 napi_value callResult;
815 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
816 napi_delete_reference(env, asyncCallbackInfo->callback);
817 }
818
819 delete asyncCallbackInfo;
820 asyncCallbackInfo = nullptr;
821 delete work;
822 work = nullptr;
823 HILOG_INFO("%{public}s, onAcquireFormState back done", __func__);
824 }
825
AcquireFormStatePromiseComplete(uv_work_t * work,int32_t status)826 void AcquireFormStatePromiseComplete(uv_work_t *work, int32_t status)
827 {
828 HILOG_INFO("%{public}s, onAcquireFormState back", __func__);
829 if (work == nullptr) {
830 HILOG_ERROR("%{public}s, work == nullptr.", __func__);
831 return;
832 }
833 auto *asyncCallbackInfo = static_cast<AsyncAcquireFormStateCallbackInfo *>(work->data);
834 if (asyncCallbackInfo == nullptr) {
835 HILOG_ERROR("asyncCallbackInfo == nullptr.");
836 delete work;
837 return;
838 }
839 napi_env env = asyncCallbackInfo->env;
840
841 if (asyncCallbackInfo->result != ERR_OK) {
842 napi_value result;
843 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
844 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
845 } else {
846 napi_value result = ParseFormStateInfo(env, asyncCallbackInfo->stateInfo);
847 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
848 }
849
850 delete asyncCallbackInfo;
851 asyncCallbackInfo = nullptr;
852 delete work;
853 work = nullptr;
854 HILOG_INFO("%{public}s, onAcquireFormState back done", __func__);
855 }
856
857 namespace {
858 class FormStateCallbackClient : public FormStateCallbackInterface {
859 public:
FormStateCallbackClient(AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)860 explicit FormStateCallbackClient(AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
861 {
862 asyncCallbackInfo_ = asyncCallbackInfo;
863 }
864
865 virtual ~FormStateCallbackClient() = default;
866
ProcessAcquireState(FormState state)867 void ProcessAcquireState(FormState state) override
868 {
869 if (asyncCallbackInfo_ == nullptr) {
870 return;
871 }
872 asyncCallbackInfo_->stateInfo.state = state;
873
874 uv_loop_s *loop = nullptr;
875 napi_get_uv_event_loop(asyncCallbackInfo_->env, &loop);
876 if (loop == nullptr) {
877 HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
878 return;
879 }
880
881 auto *work = new (std::nothrow) uv_work_t;
882 if (work == nullptr) {
883 HILOG_ERROR("%{public}s, work == nullptr.", __func__);
884 return;
885 }
886 work->data = asyncCallbackInfo_;
887
888 int32_t result = 0;
889 if (asyncCallbackInfo_->callbackType == CALLBACK_FLG) {
890 result = uv_queue_work(loop, work, [](uv_work_t *work) {}, AcquireFormStateCallbackComplete);
891 } else {
892 result = uv_queue_work(loop, work, [](uv_work_t *work) {}, AcquireFormStatePromiseComplete);
893 }
894 // When uv_queue_work returns 0, asyncCallbackInfo_ and work will be freed in the callback function.
895 if (result != 0) {
896 delete asyncCallbackInfo_;
897 asyncCallbackInfo_ = nullptr;
898 delete work;
899 work = nullptr;
900 }
901 }
902
903 private:
904 AsyncAcquireFormStateCallbackInfo *asyncCallbackInfo_ = nullptr;
905 };
906
907 class FormUninstallCallbackClient : public std::enable_shared_from_this<FormUninstallCallbackClient>
908 {
909 public:
FormUninstallCallbackClient(napi_env env,napi_ref callbackRef)910 FormUninstallCallbackClient(napi_env env, napi_ref callbackRef) : callbackRef_(callbackRef), env_(env)
911 {
912 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
913 }
914
~FormUninstallCallbackClient()915 virtual ~FormUninstallCallbackClient()
916 {
917 napi_delete_reference(env_, callbackRef_);
918 }
919
ProcessFormUninstall(const int64_t formId)920 void ProcessFormUninstall(const int64_t formId)
921 {
922 if (handler_ == nullptr) {
923 HILOG_INFO("handler is nullptr");
924 return;
925 }
926 handler_->PostSyncTask([thisWeakPtr = weak_from_this(), formId]() {
927 auto sharedThis = thisWeakPtr.lock();
928 if (sharedThis == nullptr) {
929 HILOG_ERROR("sharedThis is nullptr.");
930 return;
931 }
932 HILOG_DEBUG("task complete formId: form: %{public}" PRId64 ".", formId);
933 std::string formIdString = std::to_string(formId);
934 napi_value callbackValues;
935 napi_create_string_utf8(sharedThis->env_, formIdString.c_str(), NAPI_AUTO_LENGTH, &callbackValues);
936 napi_value callResult;
937 napi_value myCallback = nullptr;
938 napi_get_reference_value(sharedThis->env_, sharedThis->callbackRef_, &myCallback);
939 if (myCallback != nullptr) {
940 napi_call_function(sharedThis->env_, nullptr, myCallback, ARGS_SIZE_ONE, &callbackValues, &callResult);
941 }
942 });
943 }
944
IsStrictEqual(napi_value callback)945 bool IsStrictEqual(napi_value callback)
946 {
947 bool isEqual = false;
948 napi_value myCallback = nullptr;
949 napi_get_reference_value(env_, callbackRef_, &myCallback);
950 napi_strict_equals(env_, myCallback, callback, &isEqual);
951 HILOG_INFO("isStrictEqual: %{public}d", isEqual);
952 return isEqual;
953 }
954
955 private:
956 std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
957 napi_ref callbackRef_ {};
958 napi_env env_;
959 };
960
961 std::map<napi_ref, std::shared_ptr<FormUninstallCallbackClient>> g_formUninstallCallbackMap {};
962 std::mutex formUninstallCallbackMapMutex_;
963
FormUninstallCallback(const std::vector<int64_t> & formIds)964 void FormUninstallCallback(const std::vector<int64_t> &formIds)
965 {
966 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
967 for (auto &iter : g_formUninstallCallbackMap) {
968 for (int64_t formId : formIds) {
969 iter.second->ProcessFormUninstall(formId);
970 }
971 }
972 }
973
AddFormUninstallCallback(napi_env env,napi_value callback)974 bool AddFormUninstallCallback(napi_env env, napi_value callback)
975 {
976 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
977 for (auto &iter : g_formUninstallCallbackMap) {
978 if (iter.second->IsStrictEqual(callback)) {
979 HILOG_ERROR("found equal callback");
980 return false;
981 }
982 }
983
984 napi_ref callbackRef;
985 napi_create_reference(env, callback, REF_COUNT, &callbackRef);
986 std::shared_ptr<FormUninstallCallbackClient> callbackClient = std::make_shared<FormUninstallCallbackClient>(env,
987 callbackRef);
988
989 auto ret = g_formUninstallCallbackMap.emplace(callbackRef, callbackClient);
990 if (!ret.second) {
991 HILOG_ERROR("failed to emplace callback");
992 return false;
993 }
994 return true;
995 }
996
DelFormUninstallCallback(napi_value callback)997 bool DelFormUninstallCallback(napi_value callback)
998 {
999 int32_t count = 0;
1000 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
1001 for (auto iter = g_formUninstallCallbackMap.begin(); iter != g_formUninstallCallbackMap.end();) {
1002 if (iter->second->IsStrictEqual(callback)) {
1003 HILOG_INFO("found equal callback");
1004 iter = g_formUninstallCallbackMap.erase(iter);
1005 count++;
1006 } else {
1007 iter++;
1008 }
1009 }
1010 HILOG_INFO("%{public}d form uninstall callback deleted.", count);
1011 return true;
1012 }
1013
ClearFormUninstallCallback()1014 bool ClearFormUninstallCallback()
1015 {
1016 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
1017 g_formUninstallCallbackMap.clear();
1018 return true;
1019 }
1020 }
1021
InnerAcquireFormState(napi_env env,AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)1022 static void InnerAcquireFormState(napi_env env, AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
1023 {
1024 HILOG_DEBUG("%{public}s called.", __func__);
1025 std::shared_ptr<FormStateCallbackInterface> formStateCallback = std::make_shared<FormStateCallbackClient>(
1026 asyncCallbackInfo);
1027 FormHostClient::GetInstance()->AddFormState(formStateCallback, asyncCallbackInfo->want);
1028
1029 asyncCallbackInfo->result = FormMgr::GetInstance().AcquireFormState(asyncCallbackInfo->want,
1030 FormHostClient::GetInstance(), asyncCallbackInfo->stateInfo);
1031 HILOG_DEBUG("%{public}s, end", __func__);
1032 }
1033
AcquireFormStateCallback(napi_env env,AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)1034 napi_value AcquireFormStateCallback(napi_env env, AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
1035 {
1036 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1037 napi_value resourceName;
1038 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1039 napi_create_async_work(
1040 env,
1041 nullptr,
1042 resourceName,
1043 [](napi_env env, void *data) {
1044 HILOG_INFO("%{public}s, napi_create_async_work running", __func__);
1045 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
1046 InnerAcquireFormState(env, asyncCallbackInfo);
1047 },
1048 [](napi_env env, napi_status status, void *data) {
1049 HILOG_INFO("%{public}s, napi_create_async_work complete", __func__);
1050 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
1051 // asyncCallbackInfo will be freed in OnAcquireState, so save the member variable asyncWork.
1052 napi_async_work asyncWork = asyncCallbackInfo->asyncWork;
1053 // When the result is not ERR_OK, OnAcquireState will be called here,
1054 // else OnAcquireState will be called after the form state is acquired.
1055 if (asyncCallbackInfo->result != ERR_OK) {
1056 FormHostClient::GetInstance()->OnAcquireState(FormState::UNKNOWN, asyncCallbackInfo->want);
1057 }
1058 napi_delete_async_work(env, asyncWork);
1059 },
1060 (void *) asyncCallbackInfo,
1061 &asyncCallbackInfo->asyncWork);
1062 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1063 return NapiGetResult(env, 1);
1064 }
1065
AcquireFormStatePromise(napi_env env,AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)1066 napi_value AcquireFormStatePromise(napi_env env, AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
1067 {
1068 HILOG_INFO("%{public}s, promise.", __func__);
1069 napi_deferred deferred;
1070 napi_value promise;
1071 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1072 asyncCallbackInfo->deferred = deferred;
1073
1074 napi_value resourceName;
1075 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1076 napi_create_async_work(
1077 env,
1078 nullptr,
1079 resourceName,
1080 [](napi_env env, void *data) {
1081 HILOG_INFO("%{public}s, promise runnning", __func__);
1082 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
1083 InnerAcquireFormState(env, asyncCallbackInfo);
1084 },
1085 [](napi_env env, napi_status status, void *data) {
1086 HILOG_INFO("%{public}s, promise complete", __func__);
1087 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
1088 // asyncCallbackInfo will be freed in OnAcquireState, so save the member variable asyncWork.
1089 napi_async_work asyncWork = asyncCallbackInfo->asyncWork;
1090 // When the result is not ERR_OK, OnAcquireState will be called here,
1091 // else OnAcquireState will be called after the form state is acquired.
1092 if (asyncCallbackInfo->result != ERR_OK) {
1093 FormHostClient::GetInstance()->OnAcquireState(FormState::UNKNOWN, asyncCallbackInfo->want);
1094 }
1095 napi_delete_async_work(env, asyncWork);
1096 },
1097 (void *) asyncCallbackInfo,
1098 &asyncCallbackInfo->asyncWork);
1099 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1100 return promise;
1101 }
1102
1103 /**
1104 * @brief The implementation of Node-API interface: acquireFormState
1105 *
1106 * @param[in] env The environment that the Node-API call is invoked under
1107 * @param[out] info An opaque datatype that is passed to a callback function
1108 *
1109 * @return This is an opaque pointer that is used to represent a JavaScript value
1110 */
NAPI_AcquireFormState(napi_env env,napi_callback_info info)1111 napi_value NAPI_AcquireFormState(napi_env env, napi_callback_info info)
1112 {
1113 HILOG_INFO("%{public}s called.", __func__);
1114
1115 // Check the number of the arguments
1116 size_t argc = ARGS_SIZE_TWO;
1117 napi_value argv[ARGS_SIZE_TWO] = {nullptr, nullptr};
1118 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
1119 if (argc > ARGS_SIZE_TWO) {
1120 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1121 return nullptr;
1122 }
1123 HILOG_INFO("%{public}s, argc = [%{public}zu]", __func__, argc);
1124
1125 int32_t callbackType = (argc == ARGS_SIZE_TWO) ? CALLBACK_FLG : PROMISE_FLG;
1126 napi_valuetype valueType = napi_undefined;
1127 NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
1128 if (valueType != napi_object) {
1129 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[1]));
1130 }
1131
1132 auto *asyncCallbackInfo = new (std::nothrow) AsyncAcquireFormStateCallbackInfo {
1133 .env = env,
1134 .asyncWork = nullptr,
1135 .deferred = nullptr,
1136 .callback = nullptr,
1137 .want = {},
1138 .stateInfo = {},
1139 .callbackType = callbackType,
1140 .result = ERR_OK,
1141 };
1142 if (asyncCallbackInfo == nullptr) {
1143 HILOG_ERROR("asyncCallbackInfo == nullptr.");
1144 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackType, argv[1]));
1145 }
1146 std::unique_ptr<AsyncAcquireFormStateCallbackInfo> callbackPtr {asyncCallbackInfo};
1147
1148 bool parseResult = UnwrapWant(env, argv[0], asyncCallbackInfo->want);
1149 if (!parseResult) {
1150 HILOG_ERROR("%{public}s, failed to parse want.", __func__);
1151 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[1]));
1152 }
1153
1154 napi_value result;
1155 if (argc == ARGS_SIZE_TWO) {
1156 // Check the value type of the arguments
1157 valueType = napi_undefined;
1158 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1159 NAPI_ASSERT(env, valueType == napi_function,
1160 "The arguments[1] type of acquireFormState is incorrect, expected type is function.");
1161 napi_create_reference(env, argv[1], REF_COUNT, &asyncCallbackInfo->callback);
1162 result = AcquireFormStateCallback(env, asyncCallbackInfo);
1163 } else {
1164 result = AcquireFormStatePromise(env, asyncCallbackInfo);
1165 }
1166 callbackPtr.release();
1167 return result;
1168 }
1169
1170 /**
1171 * @brief The implementation of Node-API interface: on
1172 *
1173 * @param[in] env The environment that the Node-API call is invoked under
1174 * @param[out] info An opaque datatype that is passed to a callback function
1175 *
1176 * @return This is an opaque pointer that is used to represent a JavaScript value
1177 */
NAPI_RegisterFormUninstallObserver(napi_env env,napi_callback_info info)1178 napi_value NAPI_RegisterFormUninstallObserver(napi_env env, napi_callback_info info)
1179 {
1180 HILOG_INFO("%{public}s called.", __func__);
1181
1182 // Check the number of the arguments
1183 size_t argc = ARGS_SIZE_TWO;
1184 napi_value argv[ARGS_SIZE_TWO] = {nullptr, nullptr};
1185 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
1186 if (argc != ARGS_SIZE_TWO) {
1187 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1188 return nullptr;
1189 }
1190 HILOG_INFO("%{public}s, argc = [%{public}zu]", __func__, argc);
1191
1192 napi_valuetype valueType = napi_undefined;
1193 NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
1194 if (valueType != napi_string) {
1195 HILOG_ERROR("The type of args[0] is incorrect, expected type is string.");
1196 return nullptr;
1197 }
1198 std::string type;
1199 if (!UnwrapStringFromJS2(env, argv[0], type)) {
1200 HILOG_ERROR("failed to get args[0].");
1201 return nullptr;
1202 }
1203
1204 if (type != "formUninstall") {
1205 HILOG_ERROR("args[0] should be formUninstall.");
1206 return nullptr;
1207 }
1208
1209 valueType = napi_undefined;
1210 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1211 if (valueType != napi_function) {
1212 HILOG_ERROR("The type of args[1] is incorrect, expected type is function.");
1213 return nullptr;
1214 }
1215
1216 FormHostClient::GetInstance()->RegisterUninstallCallback(FormUninstallCallback);
1217 AddFormUninstallCallback(env, argv[1]);
1218 return nullptr;
1219 }
1220
1221 /**
1222 * @brief The implementation of Node-API interface: off
1223 *
1224 * @param[in] env The environment that the Node-API call is invoked under
1225 * @param[out] info An opaque datatype that is passed to a callback function
1226 *
1227 * @return This is an opaque pointer that is used to represent a JavaScript value
1228 */
NAPI_UnregisterFormUninstallObserver(napi_env env,napi_callback_info info)1229 napi_value NAPI_UnregisterFormUninstallObserver(napi_env env, napi_callback_info info)
1230 {
1231 HILOG_INFO("%{public}s called.", __func__);
1232
1233 // Check the number of the arguments
1234 size_t argc = ARGS_SIZE_TWO;
1235 napi_value argv[ARGS_SIZE_TWO] = {nullptr, nullptr};
1236 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
1237 if (argc > ARGS_SIZE_TWO) {
1238 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1239 return nullptr;
1240 }
1241 HILOG_INFO("%{public}s, argc = [%{public}zu]", __func__, argc);
1242
1243 napi_valuetype valueType = napi_undefined;
1244 NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
1245 if (valueType != napi_string) {
1246 HILOG_ERROR("The type of args[0] is incorrect, expected type is string.");
1247 return nullptr;
1248 }
1249 std::string type;
1250 if (!UnwrapStringFromJS2(env, argv[0], type)) {
1251 HILOG_ERROR("failed to get args[0].");
1252 return nullptr;
1253 }
1254
1255 if (type != "formUninstall") {
1256 HILOG_ERROR("args[0] should be formUninstall.");
1257 return nullptr;
1258 }
1259
1260 if (argc == ARGS_SIZE_TWO) {
1261 valueType = napi_undefined;
1262 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1263 if (valueType != napi_function) {
1264 HILOG_ERROR("The type of args[1] is incorrect, expected type is function.");
1265 return nullptr;
1266 }
1267 DelFormUninstallCallback(argv[1]);
1268 return nullptr;
1269 } else {
1270 ClearFormUninstallCallback();
1271 return nullptr;
1272 }
1273 }
1274
InnerNotifyFormsVisible(napi_env env,AsyncNotifyFormsVisibleCallbackInfo * const asyncCallbackInfo)1275 static void InnerNotifyFormsVisible(napi_env env, AsyncNotifyFormsVisibleCallbackInfo *const asyncCallbackInfo)
1276 {
1277 HILOG_DEBUG("%{public}s called.", __func__);
1278
1279 asyncCallbackInfo->result = FormMgr::GetInstance().NotifyFormsVisible(asyncCallbackInfo->formIds,
1280 asyncCallbackInfo->isVisible, FormHostClient::GetInstance());
1281 HILOG_DEBUG("%{public}s, end", __func__);
1282 }
1283
NotifyFormsVisibleCallback(napi_env env,AsyncNotifyFormsVisibleCallbackInfo * const asyncCallbackInfo)1284 napi_value NotifyFormsVisibleCallback(napi_env env, AsyncNotifyFormsVisibleCallbackInfo *const asyncCallbackInfo)
1285 {
1286 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1287 napi_value resourceName;
1288 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1289 napi_create_async_work(
1290 env,
1291 nullptr,
1292 resourceName,
1293 [](napi_env env, void *data) {
1294 HILOG_INFO("%{public}s, napi_create_async_work running", __func__);
1295 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
1296 InnerNotifyFormsVisible(env, asyncCallbackInfo);
1297 },
1298 [](napi_env env, napi_status status, void *data) {
1299 HILOG_INFO("%{public}s, napi_create_async_work complete", __func__);
1300 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
1301
1302 if (asyncCallbackInfo->callback != nullptr) {
1303 napi_value callback;
1304 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
1305 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
1306
1307 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
1308 napi_value callResult;
1309 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
1310 napi_delete_reference(env, asyncCallbackInfo->callback);
1311 }
1312 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1313 delete asyncCallbackInfo;
1314 },
1315 (void *) asyncCallbackInfo,
1316 &asyncCallbackInfo->asyncWork);
1317 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1318 return NapiGetResult(env, 1);
1319 }
1320
NotifyFormsVisiblePromise(napi_env env,AsyncNotifyFormsVisibleCallbackInfo * const asyncCallbackInfo)1321 napi_value NotifyFormsVisiblePromise(napi_env env, AsyncNotifyFormsVisibleCallbackInfo *const asyncCallbackInfo)
1322 {
1323 HILOG_INFO("%{public}s, promise.", __func__);
1324 napi_deferred deferred;
1325 napi_value promise;
1326 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1327 asyncCallbackInfo->deferred = deferred;
1328
1329 napi_value resourceName;
1330 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1331 napi_create_async_work(
1332 env,
1333 nullptr,
1334 resourceName,
1335 [](napi_env env, void *data) {
1336 HILOG_INFO("%{public}s, promise runnning", __func__);
1337 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
1338 InnerNotifyFormsVisible(env, asyncCallbackInfo);
1339 },
1340 [](napi_env env, napi_status status, void *data) {
1341 HILOG_INFO("%{public}s, promise complete", __func__);
1342 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
1343 napi_value result;
1344 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
1345 if (asyncCallbackInfo->result == ERR_OK) {
1346 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
1347 } else {
1348 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
1349 }
1350 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1351 delete asyncCallbackInfo;
1352 },
1353 (void *) asyncCallbackInfo,
1354 &asyncCallbackInfo->asyncWork);
1355 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1356 return promise;
1357 }
1358
1359 /**
1360 * @brief The implementation of Node-API interface: notifyFormsVisible
1361 *
1362 * @param[in] env The environment that the Node-API call is invoked under
1363 * @param[out] info An opaque datatype that is passed to a callback function
1364 *
1365 * @return This is an opaque pointer that is used to represent a JavaScript value
1366 */
NAPI_NotifyFormsVisible(napi_env env,napi_callback_info info)1367 napi_value NAPI_NotifyFormsVisible(napi_env env, napi_callback_info info)
1368 {
1369 HILOG_INFO("%{public}s called.", __func__);
1370
1371 // Check the number of the arguments
1372 size_t argc = ARGS_SIZE_THREE;
1373 napi_value argv[ARGS_SIZE_THREE] = {nullptr, nullptr, nullptr};
1374 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
1375 if (argc > ARGS_SIZE_THREE || argc < ARGS_SIZE_TWO) {
1376 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1377 return nullptr;
1378 }
1379
1380 int32_t callbackType = (argc == ARGS_SIZE_THREE) ? CALLBACK_FLG : PROMISE_FLG;
1381
1382 ErrCode errCode;
1383 std::vector<int64_t> formIds {};
1384 GetFormIds(env, argv[0], errCode, formIds);
1385 if (errCode != ERR_OK) {
1386 return RetErrMsg(InitErrMsg(env, errCode, callbackType, argv[ARGS_SIZE_TWO]));
1387 }
1388
1389 napi_valuetype valueType = napi_undefined;
1390 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1391 if (valueType != napi_boolean) {
1392 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[ARGS_SIZE_TWO]));
1393 }
1394
1395 auto *asyncCallbackInfo = new (std::nothrow) AsyncNotifyFormsVisibleCallbackInfo {
1396 .env = env,
1397 .asyncWork = nullptr,
1398 .deferred = nullptr,
1399 .callback = nullptr,
1400 .formIds = formIds,
1401 .isVisible = false,
1402 };
1403 if (asyncCallbackInfo == nullptr) {
1404 HILOG_ERROR("asyncCallbackInfo == nullptr.");
1405 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackType, argv[1]));
1406 }
1407 std::unique_ptr<AsyncNotifyFormsVisibleCallbackInfo> callbackPtr {asyncCallbackInfo};
1408
1409 napi_get_value_bool(env, argv[1], &asyncCallbackInfo->isVisible);
1410
1411 napi_value result;
1412 if (argc == ARGS_SIZE_THREE) {
1413 // Check the value type of the arguments
1414 valueType = napi_undefined;
1415 NAPI_CALL(env, napi_typeof(env, argv[ARGS_SIZE_TWO], &valueType));
1416 NAPI_ASSERT(env, valueType == napi_function, "The type of arg 2 is incorrect, expected type is function.");
1417 napi_create_reference(env, argv[ARGS_SIZE_TWO], REF_COUNT, &asyncCallbackInfo->callback);
1418 result = NotifyFormsVisibleCallback(env, asyncCallbackInfo);
1419 } else {
1420 result = NotifyFormsVisiblePromise(env, asyncCallbackInfo);
1421 }
1422
1423 callbackPtr.release();
1424 return result;
1425 }
1426
InnerNotifyFormsEnableUpdate(napi_env env,AsyncNotifyFormsEnableUpdateCallbackInfo * const asyncCallbackInfo)1427 static void InnerNotifyFormsEnableUpdate(napi_env env,
1428 AsyncNotifyFormsEnableUpdateCallbackInfo *const asyncCallbackInfo)
1429 {
1430 HILOG_DEBUG("%{public}s called.", __func__);
1431
1432 asyncCallbackInfo->result = FormMgr::GetInstance().NotifyFormsEnableUpdate(asyncCallbackInfo->formIds,
1433 asyncCallbackInfo->isEnableUpdate, FormHostClient::GetInstance());
1434 HILOG_DEBUG("%{public}s, end", __func__);
1435 }
1436
NotifyFormsEnableUpdateCallback(napi_env env,AsyncNotifyFormsEnableUpdateCallbackInfo * const asyncCallbackInfo)1437 napi_value NotifyFormsEnableUpdateCallback(napi_env env,
1438 AsyncNotifyFormsEnableUpdateCallbackInfo *const asyncCallbackInfo)
1439 {
1440 HILOG_INFO("%{public}s, asyncCallback.", __func__);
1441 napi_value resourceName;
1442 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1443 napi_create_async_work(
1444 env,
1445 nullptr,
1446 resourceName,
1447 [](napi_env env, void *data) {
1448 HILOG_INFO("%{public}s, napi_create_async_work running", __func__);
1449 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
1450 InnerNotifyFormsEnableUpdate(env, asyncCallbackInfo);
1451 },
1452 [](napi_env env, napi_status status, void *data) {
1453 HILOG_INFO("%{public}s, napi_create_async_work complete", __func__);
1454 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
1455
1456 if (asyncCallbackInfo->callback != nullptr) {
1457 napi_value callback;
1458 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
1459 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
1460
1461 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
1462 napi_value callResult;
1463 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
1464 napi_delete_reference(env, asyncCallbackInfo->callback);
1465 }
1466 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1467 delete asyncCallbackInfo;
1468 },
1469 (void *) asyncCallbackInfo,
1470 &asyncCallbackInfo->asyncWork);
1471 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1472 return NapiGetResult(env, 1);
1473 }
1474
NotifyFormsEnableUpdatePromise(napi_env env,AsyncNotifyFormsEnableUpdateCallbackInfo * const asyncCallbackInfo)1475 napi_value NotifyFormsEnableUpdatePromise(napi_env env,
1476 AsyncNotifyFormsEnableUpdateCallbackInfo *const asyncCallbackInfo)
1477 {
1478 HILOG_INFO("%{public}s, promise.", __func__);
1479 napi_deferred deferred;
1480 napi_value promise;
1481 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1482 asyncCallbackInfo->deferred = deferred;
1483
1484 napi_value resourceName;
1485 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1486 napi_create_async_work(
1487 env,
1488 nullptr,
1489 resourceName,
1490 [](napi_env env, void *data) {
1491 HILOG_INFO("%{public}s, promise runnning", __func__);
1492 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
1493 InnerNotifyFormsEnableUpdate(env, asyncCallbackInfo);
1494 },
1495 [](napi_env env, napi_status status, void *data) {
1496 HILOG_INFO("%{public}s, promise complete", __func__);
1497 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
1498 napi_value result;
1499 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
1500 if (asyncCallbackInfo->result == ERR_OK) {
1501 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
1502 } else {
1503 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
1504 }
1505 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1506 delete asyncCallbackInfo;
1507 },
1508 (void *) asyncCallbackInfo,
1509 &asyncCallbackInfo->asyncWork);
1510 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1511 return promise;
1512 }
1513
1514 /**
1515 * @brief The implementation of Node-API interface: notifyFormsEnableUpdate
1516 *
1517 * @param[in] env The environment that the Node-API call is invoked under
1518 * @param[out] info An opaque datatype that is passed to a callback function
1519 *
1520 * @return This is an opaque pointer that is used to represent a JavaScript value
1521 */
NAPI_NotifyFormsEnableUpdate(napi_env env,napi_callback_info info)1522 napi_value NAPI_NotifyFormsEnableUpdate(napi_env env, napi_callback_info info)
1523 {
1524 HILOG_INFO("%{public}s called.", __func__);
1525
1526 // Check the number of the arguments
1527 size_t argc = ARGS_SIZE_THREE;
1528 napi_value argv[ARGS_SIZE_THREE] = {nullptr, nullptr, nullptr};
1529 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
1530 if (argc > ARGS_SIZE_THREE || argc < ARGS_SIZE_TWO) {
1531 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1532 return nullptr;
1533 }
1534
1535 int32_t callbackType = (argc == ARGS_SIZE_THREE) ? CALLBACK_FLG : PROMISE_FLG;
1536
1537 ErrCode errCode;
1538 std::vector<int64_t> formIds {};
1539 GetFormIds(env, argv[0], errCode, formIds);
1540 if (errCode != ERR_OK) {
1541 return RetErrMsg(InitErrMsg(env, errCode, callbackType, argv[ARGS_SIZE_TWO]));
1542 }
1543
1544 napi_valuetype valueType = napi_undefined;
1545 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1546 if (valueType != napi_boolean) {
1547 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[ARGS_SIZE_TWO]));
1548 }
1549
1550 auto *asyncCallbackInfo = new (std::nothrow) AsyncNotifyFormsEnableUpdateCallbackInfo {
1551 .env = env,
1552 .asyncWork = nullptr,
1553 .deferred = nullptr,
1554 .callback = nullptr,
1555 .formIds = formIds,
1556 .isEnableUpdate = false,
1557 };
1558 if (asyncCallbackInfo == nullptr) {
1559 HILOG_ERROR("asyncCallbackInfo == nullptr.");
1560 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackType, argv[1]));
1561 }
1562 std::unique_ptr<AsyncNotifyFormsEnableUpdateCallbackInfo> callbackPtr {asyncCallbackInfo};
1563
1564 napi_get_value_bool(env, argv[1], &asyncCallbackInfo->isEnableUpdate);
1565
1566 napi_value result;
1567 if (argc == ARGS_SIZE_THREE) {
1568 // Check the value type of the arguments
1569 valueType = napi_undefined;
1570 NAPI_CALL(env, napi_typeof(env, argv[ARGS_SIZE_TWO], &valueType));
1571 NAPI_ASSERT(env, valueType == napi_function, "The type of arg 2 is incorrect, expected type is function.");
1572 napi_create_reference(env, argv[ARGS_SIZE_TWO], REF_COUNT, &asyncCallbackInfo->callback);
1573 result = NotifyFormsEnableUpdateCallback(env, asyncCallbackInfo);
1574 } else {
1575 result = NotifyFormsEnableUpdatePromise(env, asyncCallbackInfo);
1576 }
1577 callbackPtr.release();
1578 return result;
1579 }
1580
SystemTimeMillis()1581 int64_t SystemTimeMillis() noexcept
1582 {
1583 struct timespec t;
1584 t.tv_sec = 0;
1585 t.tv_nsec = 0;
1586 clock_gettime(CLOCK_MONOTONIC, &t);
1587 return static_cast<int64_t>(((t.tv_sec) * NANOSECONDS + t.tv_nsec) / MICROSECONDS);
1588 }
1589
1590 class ShareFormCallBackClient : public ShareFormCallBack,
1591 public std::enable_shared_from_this<ShareFormCallBackClient> {
1592 public:
ShareFormCallBackClient(ShareFormTask && task)1593 explicit ShareFormCallBackClient(ShareFormTask &&task) : task_(std::move(task))
1594 {
1595 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
1596 }
1597
1598 virtual ~ShareFormCallBackClient() = default;
1599
ProcessShareFormResponse(int32_t result)1600 void ProcessShareFormResponse(int32_t result) override
1601 {
1602 if (handler_) {
1603 handler_->PostSyncTask([client = shared_from_this(), result] () {
1604 client->task_(result);
1605 });
1606 }
1607 }
1608
1609 private:
1610 ShareFormTask task_;
1611 std::shared_ptr<AppExecFwk::EventHandler> handler_;
1612 };
1613
Finalizer(NativeEngine * engine,void * data,void * hint)1614 void NapiFormHost::Finalizer(NativeEngine *engine, void *data, void *hint)
1615 {
1616 HILOG_DEBUG("NapiFormHost::Finalizer is called");
1617 std::unique_ptr<NapiFormHost>(static_cast<NapiFormHost*>(data));
1618 }
1619
ShareForm(NativeEngine * engine,NativeCallbackInfo * info)1620 NativeValue* NapiFormHost::ShareForm(NativeEngine *engine, NativeCallbackInfo *info)
1621 {
1622 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1623 return (me != nullptr) ? me->OnShareForm(*engine, *info) : nullptr;
1624 }
1625
DisableFormsUpdate(NativeEngine * engine,NativeCallbackInfo * info)1626 NativeValue* NapiFormHost::DisableFormsUpdate(NativeEngine *engine, NativeCallbackInfo *info)
1627 {
1628 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1629 return (me != nullptr) ? me->OnDisableFormsUpdate(*engine, *info) : nullptr;
1630 }
1631
IsSystemReady(NativeEngine * engine,NativeCallbackInfo * info)1632 NativeValue* NapiFormHost::IsSystemReady(NativeEngine *engine, NativeCallbackInfo *info)
1633 {
1634 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1635 return (me != nullptr) ? me->OnIsSystemReady(*engine, *info) : nullptr;
1636 }
1637
GetAllFormsInfo(NativeEngine * engine,NativeCallbackInfo * info)1638 NativeValue* NapiFormHost::GetAllFormsInfo(NativeEngine *engine, NativeCallbackInfo *info)
1639 {
1640 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1641 return (me != nullptr) ? me->OnGetAllFormsInfo(*engine, *info) : nullptr;
1642 }
1643
GetFormsInfo(NativeEngine * engine,NativeCallbackInfo * info)1644 NativeValue* NapiFormHost::GetFormsInfo(NativeEngine *engine, NativeCallbackInfo *info)
1645 {
1646 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1647 return (me != nullptr) ? me->OnGetFormsInfo(*engine, *info) : nullptr;
1648 }
1649
DeleteForm(NativeEngine * engine,NativeCallbackInfo * info)1650 NativeValue* NapiFormHost::DeleteForm(NativeEngine *engine, NativeCallbackInfo *info)
1651 {
1652 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1653 return (me != nullptr) ? me->OnDeleteForm(*engine, *info) : nullptr;
1654 }
1655
ReleaseForm(NativeEngine * engine,NativeCallbackInfo * info)1656 NativeValue* NapiFormHost::ReleaseForm(NativeEngine *engine, NativeCallbackInfo *info)
1657 {
1658 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1659 return (me != nullptr) ? me->OnReleaseForm(*engine, *info) : nullptr;
1660 }
1661
RequestForm(NativeEngine * engine,NativeCallbackInfo * info)1662 NativeValue* NapiFormHost::RequestForm(NativeEngine *engine, NativeCallbackInfo *info)
1663 {
1664 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1665 return (me != nullptr) ? me->OnRequestForm(*engine, *info) : nullptr;
1666 }
1667
CastTempForm(NativeEngine * engine,NativeCallbackInfo * info)1668 NativeValue* NapiFormHost::CastTempForm(NativeEngine *engine, NativeCallbackInfo *info)
1669 {
1670 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1671 return (me != nullptr) ? me->OnCastTempForm(*engine, *info) : nullptr;
1672 }
1673
EnableFormsUpdate(NativeEngine * engine,NativeCallbackInfo * info)1674 NativeValue* NapiFormHost::EnableFormsUpdate(NativeEngine *engine, NativeCallbackInfo *info)
1675 {
1676 NapiFormHost *me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
1677 return (me != nullptr) ? me->OnEnableFormsUpdate(*engine, *info) : nullptr;
1678 }
1679
OnShareForm(NativeEngine & engine,NativeCallbackInfo & info)1680 NativeValue* NapiFormHost::OnShareForm(NativeEngine &engine, NativeCallbackInfo &info)
1681 {
1682 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1683 int32_t errCode = ERR_OK;
1684 if (info.argc > ARGS_SIZE_THREE || info.argc < ARGS_SIZE_TWO) {
1685 HILOG_ERROR("wrong number of arguments.");
1686 errCode = ERR_ADD_INVALID_PARAM;
1687 }
1688
1689 std::string strFormId =
1690 GetStringFromNAPI(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[0]));
1691 std::string remoteDeviceId =
1692 GetStringFromNAPI(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[1]));
1693 // The promise form has only two parameters
1694 decltype(info.argc) unwrapArgc = 2;
1695
1696 int64_t formId = 0;
1697 if (!ConvertStringToInt64(strFormId, formId)) {
1698 HILOG_ERROR("convert string formId to int64 failed.");
1699 errCode = ERR_COMMON;
1700 }
1701 if (formId == 0 || remoteDeviceId.empty()) {
1702 errCode = ERR_COMMON;
1703 }
1704
1705 NativeValue *lastParam = (info.argc <= unwrapArgc) ? nullptr : info.argv[unwrapArgc];
1706 NativeValue *result = nullptr;
1707
1708 std::unique_ptr<AbilityRuntime::AsyncTask> uasyncTask =
1709 AbilityRuntime::CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, nullptr, &result);
1710 std::shared_ptr<AbilityRuntime::AsyncTask> asyncTask = std::move(uasyncTask);
1711
1712 ShareFormTask task = [&engine, asyncTask](int32_t code) {
1713 HILOG_DEBUG("task complete code: %{public}d", code);
1714 if (code == ERR_OK) {
1715 asyncTask->Resolve(engine, engine.CreateUndefined());
1716 } else {
1717 auto retCode = QueryRetCode(code);
1718 auto retMsg = QueryRetMsg(retCode);
1719 asyncTask->Reject(engine, AbilityRuntime::CreateJsError(engine, retCode, retMsg));
1720 }
1721 };
1722
1723 if (errCode != ERR_OK) {
1724 asyncTask->Reject(engine, AbilityRuntime::CreateJsError(engine, errCode, "Invalidate params."));
1725 } else {
1726 InnerShareForm(engine, asyncTask, std::move(task), formId, remoteDeviceId);
1727 }
1728
1729 return result;
1730 }
1731
OnDisableFormsUpdate(NativeEngine & engine,NativeCallbackInfo & info)1732 NativeValue* NapiFormHost::OnDisableFormsUpdate(NativeEngine &engine, NativeCallbackInfo &info)
1733 {
1734 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1735 int32_t errCode = ERR_OK;
1736 if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
1737 HILOG_ERROR("wrong number of arguments!");
1738 return engine.CreateUndefined();
1739 }
1740
1741 if (!(info.argv[PARAM0]->IsArray())) {
1742 HILOG_ERROR("input params is not array!");
1743 errCode = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR;
1744 }
1745 std::vector<string> strFormIdList;
1746 if (!GetStringsValue(engine, info.argv[PARAM0], strFormIdList)) {
1747 HILOG_ERROR("conversion string failed!");
1748 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1749 }
1750 if (strFormIdList.empty()) {
1751 HILOG_ERROR("formId list is empty!");
1752 errCode = ERR_APPEXECFWK_FORM_FORM_ID_ARRAY_ERR;
1753 }
1754 std::vector<int64_t> iFormIds;
1755 for (size_t i = 0; i < strFormIdList.size(); i++) {
1756 int64_t formIdValue;
1757 if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
1758 HILOG_ERROR("conversion int failed!");
1759 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1760 } else {
1761 iFormIds.push_back(formIdValue);
1762 }
1763 }
1764
1765 auto complete = [formIds = iFormIds, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
1766 if (errCode != ERR_OK) {
1767 auto code = QueryRetCode(errCode);
1768 task.Reject(engine, CreateJsError(engine, code, QueryRetMsg(code)));
1769 return;
1770 }
1771 auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), false);
1772 if (ret != ERR_OK) {
1773 auto retCode = QueryRetCode(ret);
1774 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1775 return;
1776 }
1777 task.Resolve(engine, CreateJsValue(engine, ret));
1778 };
1779
1780 auto callback = (info.argc == ARGS_ONE) ? nullptr : info.argv[PARAM1];
1781 NativeValue *result = nullptr;
1782 AsyncTask::Schedule("NapiFormHost::OnDisableFormsUpdate",
1783 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
1784 return result;
1785 }
1786
OnIsSystemReady(NativeEngine & engine,const NativeCallbackInfo & info)1787 NativeValue* NapiFormHost::OnIsSystemReady(NativeEngine &engine, const NativeCallbackInfo &info)
1788 {
1789 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1790 if (info.argc > ARGS_ONE || info.argc < ARGS_ZERO) {
1791 HILOG_ERROR("wrong number of arguments.");
1792 return engine.CreateUndefined();
1793 }
1794
1795 auto complete = [](NativeEngine &engine, AsyncTask &task, int32_t status) {
1796 // Use original logic.
1797 // Use the error code to return whether the function executed successfully.
1798 auto ret = FormMgr::GetInstance().CheckFMSReady() ? 0 : 1;
1799 if (ret == ERR_OK) {
1800 task.Resolve(engine, engine.CreateUndefined());
1801 } else {
1802 auto retCode = QueryRetCode(ret);
1803 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1804 }
1805 };
1806
1807 auto callback = (info.argc == ARGS_ZERO) ? nullptr : info.argv[PARAM0];
1808 NativeValue *result = nullptr;
1809 AsyncTask::Schedule("NapiFormHost::OnIsSystemReady",
1810 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
1811 return result;
1812 }
1813
OnGetAllFormsInfo(NativeEngine & engine,const NativeCallbackInfo & info)1814 NativeValue* NapiFormHost::OnGetAllFormsInfo(NativeEngine &engine, const NativeCallbackInfo &info)
1815 {
1816 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1817 if (info.argc > ARGS_ONE || info.argc < ARGS_ZERO) {
1818 HILOG_ERROR("wrong number of arguments!");
1819 return engine.CreateUndefined();
1820 }
1821
1822 auto complete = [](NativeEngine &engine, AsyncTask &task, int32_t status) {
1823 std::vector<FormInfo> formInfos;
1824 auto ret = FormMgr::GetInstance().GetAllFormsInfo(formInfos);
1825 if (ret != ERR_OK) {
1826 auto retCode = QueryRetCode(ret);
1827 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1828 return;
1829 }
1830 task.Resolve(engine, CreateFormInfos(engine, formInfos));
1831 };
1832
1833 auto callback = (info.argc == ARGS_ZERO) ? nullptr : info.argv[PARAM0];
1834 NativeValue *result = nullptr;
1835 AsyncTask::Schedule("NapiFormHost::OnGetAllFormsInfo",
1836 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
1837 return result;
1838 }
1839
OnGetFormsInfo(NativeEngine & engine,NativeCallbackInfo & info)1840 NativeValue* NapiFormHost::OnGetFormsInfo(NativeEngine &engine, NativeCallbackInfo &info)
1841 {
1842 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1843 int32_t errCode = ERR_OK;
1844 if (info.argc > ARGS_THREE || info.argc < ARGS_ONE) {
1845 HILOG_ERROR("wrong number of arguments!");
1846 return engine.CreateUndefined();
1847 }
1848
1849 std::string bName("");
1850 if (!ConvertFromJsValue(engine, info.argv[PARAM0], bName)) {
1851 HILOG_ERROR("conversion failed!");
1852 errCode = ERR_APPEXECFWK_FORM_INVALID_BUNDLENAME;
1853 }
1854
1855 std::string mName("");
1856 bool bParam = false;
1857 bool flagCall = UnwrapGetFormsInfoParams(engine, info, mName, bParam);
1858 auto complete = [bName, mName, bParam, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
1859 std::string bundleName(bName);
1860 std::string moduleName(mName);
1861 std::vector<FormInfo> formInfos;
1862 if (errCode != ERR_OK) {
1863 auto retCode = QueryRetCode(errCode);
1864 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1865 return;
1866 }
1867 int ret = ERR_OK;
1868 if (!bParam) {
1869 ret = FormMgr::GetInstance().GetFormsInfoByApp(bundleName, formInfos);
1870 } else {
1871 ret = FormMgr::GetInstance().GetFormsInfoByModule(bundleName, moduleName, formInfos);
1872 }
1873
1874 if (ret != ERR_OK) {
1875 auto retCode = QueryRetCode(ret);
1876 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1877 return;
1878 }
1879 task.Resolve(engine, CreateFormInfos(engine, formInfos));
1880 };
1881
1882 NativeValue *result = nullptr;
1883 auto callback = flagCall ? ((info.argc == ARGS_TWO) ? info.argv[PARAM1] : info.argv[PARAM2]) : nullptr;
1884 AsyncTask::Schedule("NapiFormHost::OnGetFormsInfo",
1885 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
1886 return result;
1887 }
1888
OnDeleteForm(NativeEngine & engine,NativeCallbackInfo & info)1889 NativeValue* NapiFormHost::OnDeleteForm(NativeEngine &engine, NativeCallbackInfo &info)
1890 {
1891 HILOG_DEBUG("%{public}s called.", __func__);
1892
1893 int32_t errCode = ERR_OK;
1894 int64_t formId = 0;
1895 if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
1896 HILOG_ERROR("OnDeleteForm wrong number of arguments.");
1897 return engine.CreateUndefined();
1898 }
1899 if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
1900 HILOG_ERROR("input params is not string!");
1901 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
1902 } else {
1903 std::string strFormId;
1904 if (!ConvertFromJsValue(engine, info.argv[PARAM0], strFormId)) {
1905 HILOG_ERROR("conversion failed!");
1906 return engine.CreateUndefined();
1907 }
1908 if (!ConvertStringToInt64(strFormId, formId)) {
1909 HILOG_ERROR("OnDeleteForm convert string formId to int64 failed.");
1910 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1911 }
1912 }
1913 AsyncTask::CompleteCallback complete = [formId, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
1914 if (errCode != ERR_OK) {
1915 auto retCode = QueryRetCode(errCode);
1916 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1917 return;
1918 }
1919 auto ret = FormMgr::GetInstance().DeleteForm(formId, FormHostClient::GetInstance());
1920 if (ret == ERR_OK) {
1921 auto result = QueryRetCode(ret);
1922 task.Resolve(engine, CreateJsValue(engine, result));
1923 } else {
1924 auto retCode = QueryRetCode(ret);
1925 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1926 }
1927 };
1928
1929 NativeValue* lastParam = (info.argc == ARGS_ONE) ? nullptr : info.argv[PARAM1];
1930 NativeValue* result = nullptr;
1931 AsyncTask::Schedule("NapiFormHost::OnDeleteForm",
1932 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
1933 return result;
1934 }
1935
OnReleaseForm(NativeEngine & engine,NativeCallbackInfo & info)1936 NativeValue* NapiFormHost::OnReleaseForm(NativeEngine &engine, NativeCallbackInfo &info)
1937 {
1938 HILOG_DEBUG("%{public}s called.", __func__);
1939
1940 int32_t errCode = ERR_OK;
1941 int64_t formId = 0;
1942 bool isReleaseCache = false;
1943 if (info.argc > ARGS_THREE || info.argc < ARGS_ONE) {
1944 HILOG_ERROR("OnReleaseForm wrong number of arguments.");
1945 return engine.CreateUndefined();
1946 }
1947 if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
1948 HILOG_ERROR("input params is not string!");
1949 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
1950 } else {
1951 std::string strFormId;
1952 if (!ConvertFromJsValue(engine, info.argv[PARAM0], strFormId)) {
1953 HILOG_ERROR("conversion failed!");
1954 return engine.CreateUndefined();
1955 }
1956 if (!ConvertStringToInt64(strFormId, formId)) {
1957 HILOG_ERROR("OnReleaseForm convert string formId to int64 failed.");
1958 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1959 } else if ((info.argc == ARGS_TWO || info.argc == ARGS_THREE) &&
1960 info.argv[PARAM1]->TypeOf() != NATIVE_FUNCTION) {
1961 if (info.argv[PARAM1]->TypeOf() == NATIVE_BOOLEAN) {
1962 if (!ConvertFromJsValue(engine, info.argv[PARAM1], isReleaseCache)) {
1963 HILOG_ERROR("conversion bool failed!");
1964 return engine.CreateUndefined();
1965 }
1966 } else {
1967 HILOG_ERROR("promise second param type is illegal");
1968 errCode = ERR_APPEXECFWK_FORM_RELEASE_FLG_ERR;
1969 }
1970 }
1971 }
1972
1973 AsyncTask::CompleteCallback complete = [formId, errCode, isReleaseCache]
1974 (NativeEngine &engine, AsyncTask &task, int32_t status) {
1975 auto ret = ERR_COMMON;
1976 if (errCode != ERR_OK) {
1977 auto retCode = QueryRetCode(errCode);
1978 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1979 return ;
1980 }
1981 ret = FormMgr::GetInstance().ReleaseForm(formId, FormHostClient::GetInstance(), isReleaseCache);
1982 if (ret == ERR_OK) {
1983 auto result = QueryRetCode(ret);
1984 task.Resolve(engine, CreateJsValue(engine, result));
1985 } else {
1986 auto retCode = QueryRetCode(ret);
1987 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
1988 return;
1989 }
1990 };
1991
1992 NativeValue* lastParam = (info.argc == ARGS_ONE) ? nullptr :
1993 (info.argc == ARGS_TWO && info.argv[PARAM1]->TypeOf() != NATIVE_FUNCTION) ? nullptr :
1994 (info.argc == ARGS_THREE) ? info.argv[PARAM2] : info.argv[PARAM1];
1995 NativeValue* result = nullptr;
1996 AsyncTask::Schedule("NapiFormHost::OnReleaseForm",
1997 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
1998 return result;
1999 }
2000
OnRequestForm(NativeEngine & engine,NativeCallbackInfo & info)2001 NativeValue* NapiFormHost::OnRequestForm(NativeEngine &engine, NativeCallbackInfo &info)
2002 {
2003 HILOG_DEBUG("%{public}s called.", __func__);
2004
2005 int32_t errCode = ERR_OK;
2006 int64_t formId = 0;
2007 if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
2008 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
2009 return engine.CreateUndefined();
2010 }
2011 if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
2012 HILOG_ERROR("input params is not string!");
2013 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
2014 } else {
2015 std::string strFormId;
2016 if (!ConvertFromJsValue(engine, info.argv[PARAM0], strFormId)) {
2017 HILOG_ERROR("conversion failed!");
2018 return engine.CreateUndefined();
2019 }
2020 if (!ConvertStringToInt64(strFormId, formId)) {
2021 HILOG_ERROR("%{public}s, convert string formId to int64 failed.", __func__);
2022 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
2023 }
2024 }
2025 AsyncTask::CompleteCallback complete = [formId, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
2026 if (errCode != ERR_OK) {
2027 auto retCode = QueryRetCode(errCode);
2028 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
2029 return;
2030 }
2031 Want want;
2032 auto ret = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
2033 if (ret == ERR_OK) {
2034 auto result = QueryRetCode(ret);
2035 task.Resolve(engine, CreateJsValue(engine, result));
2036 } else {
2037 auto retCode = QueryRetCode(ret);
2038 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
2039 }
2040 };
2041
2042 NativeValue* lastParam = (info.argc == ARGS_ONE) ? nullptr : info.argv[PARAM1];
2043 NativeValue* result = nullptr;
2044 AsyncTask::Schedule("NapiFormHost::OnRequestForm",
2045 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
2046 return result;
2047 }
2048
OnCastTempForm(NativeEngine & engine,NativeCallbackInfo & info)2049 NativeValue* NapiFormHost::OnCastTempForm(NativeEngine &engine, NativeCallbackInfo &info)
2050 {
2051 HILOG_DEBUG("%{public}s called.", __func__);
2052
2053 int32_t errCode = ERR_OK;
2054 int64_t formId = 0;
2055 if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
2056 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
2057 return engine.CreateUndefined();
2058 }
2059 if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
2060 HILOG_ERROR("input params is not string!");
2061 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
2062 } else {
2063 std::string strFormId;
2064 if (!ConvertFromJsValue(engine, info.argv[PARAM0], strFormId)) {
2065 HILOG_ERROR("conversion failed!");
2066 return engine.CreateUndefined();
2067 }
2068 if (!ConvertStringToInt64(strFormId, formId)) {
2069 HILOG_ERROR("%{public}s, convert string formId to int64 failed.", __func__);
2070 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
2071 }
2072 }
2073 AsyncTask::CompleteCallback complete = [formId, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
2074 if (errCode != ERR_OK) {
2075 auto retCode = QueryRetCode(errCode);
2076 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
2077 return;
2078 }
2079 auto ret = FormMgr::GetInstance().CastTempForm(formId, FormHostClient::GetInstance());
2080 if (ret == ERR_OK) {
2081 auto result = QueryRetCode(ret);
2082 task.Resolve(engine, CreateJsValue(engine, result));
2083 } else {
2084 auto retCode = QueryRetCode(ret);
2085 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
2086 }
2087 };
2088
2089 NativeValue* lastParam = (info.argc == ARGS_ONE) ? nullptr : info.argv[PARAM1];
2090 NativeValue* result = nullptr;
2091 AsyncTask::Schedule("NapiFormHost::OnCastTempForm",
2092 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
2093 return result;
2094 }
2095
OnEnableFormsUpdate(NativeEngine & engine,NativeCallbackInfo & info)2096 NativeValue* NapiFormHost::OnEnableFormsUpdate(NativeEngine &engine, NativeCallbackInfo &info)
2097 {
2098 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
2099
2100 int32_t errCode = ERR_OK;
2101 std::vector<int64_t> iFormIds;
2102 if (info.argc > ARGS_TWO|| info.argc < ARGS_ONE) {
2103 HILOG_ERROR("wrong number of arguments!");
2104 return engine.CreateUndefined();
2105 }
2106 if (!(info.argv[PARAM0]->IsArray())) {
2107 HILOG_ERROR("input params0 is not array!");
2108 errCode = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR;
2109 } else {
2110 std::vector<string> strFormIdList;
2111 if (!GetStringsValue(engine, info.argv[PARAM0], strFormIdList)) {
2112 HILOG_ERROR("conversion string failed!");
2113 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
2114 }
2115 for (size_t i = 0; i < strFormIdList.size(); i++) {
2116 int64_t formIdValue;
2117 if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
2118 HILOG_ERROR("conversion int failed!");
2119 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
2120 } else {
2121 iFormIds.push_back(formIdValue);
2122 }
2123 }
2124 }
2125 auto complete = [iFormIds, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
2126 if (errCode != ERR_OK) {
2127 auto code = QueryRetCode(errCode);
2128 task.Reject(engine, CreateJsError(engine, code, QueryRetMsg(code)));
2129 return;
2130 }
2131 auto ret = FormMgr::GetInstance().LifecycleUpdate(iFormIds, FormHostClient::GetInstance(), true);
2132 if (ret == ERR_OK) {
2133 auto result = QueryRetCode(ret);
2134 task.Resolve(engine, CreateJsValue(engine, result));
2135 } else {
2136 auto retCode = QueryRetCode(ret);
2137 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
2138 }
2139 };
2140
2141 auto callback = (info.argc == ARGS_ONE) ? nullptr : info.argv[PARAM1];
2142 NativeValue *result = nullptr;
2143 AsyncTask::Schedule("NapiFormHost::OnEnableFormsUpdate",
2144 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
2145 return result;
2146 }
2147
GetStringsValue(NativeEngine & engine,NativeValue * object,std::vector<std::string> & strList)2148 bool NapiFormHost::GetStringsValue(NativeEngine &engine, NativeValue *object, std::vector<std::string> &strList)
2149 {
2150 auto array = ConvertNativeValueTo<NativeArray>(object);
2151 if (array == nullptr) {
2152 HILOG_ERROR("input params error");
2153 return false;
2154 }
2155
2156 for (uint32_t i = 0; i < array->GetLength(); i++) {
2157 std::string itemStr("");
2158 if ((array->GetElement(i))->TypeOf() != NATIVE_STRING) {
2159 HILOG_ERROR("GetElement is not string");
2160 return false;
2161 }
2162 if (!ConvertFromJsValue(engine, array->GetElement(i), itemStr)) {
2163 HILOG_ERROR("GetElement from to array [%{public}u] error", i);
2164 return false;
2165 }
2166 strList.push_back(itemStr);
2167 }
2168
2169 return true;
2170 }
2171
UnwrapGetFormsInfoParams(NativeEngine & engine,NativeCallbackInfo & info,std::string & moduleName,bool & bParam)2172 bool NapiFormHost::UnwrapGetFormsInfoParams(
2173 NativeEngine &engine, NativeCallbackInfo &info, std::string &moduleName, bool &bParam)
2174 {
2175 bool flagCall = true;
2176 if (info.argc == ARGS_ONE) {
2177 flagCall = false;
2178 bParam = false;
2179 } else if (info.argc == ARGS_TWO && info.argv[PARAM1]->TypeOf() != NATIVE_FUNCTION) {
2180 if (!ConvertFromJsValue(engine, info.argv[PARAM1], moduleName)) {
2181 HILOG_WARN("input params string error");
2182 }
2183 flagCall = false;
2184 bParam = true;
2185 } else if (info.argc == ARGS_TWO && info.argv[PARAM1]->TypeOf() == NATIVE_FUNCTION) {
2186 bParam = false;
2187 } else if (info.argc == ARGS_THREE) {
2188 if (!ConvertFromJsValue(engine, info.argv[PARAM1], moduleName)) {
2189 HILOG_WARN("input params string error");
2190 }
2191 bParam = true;
2192 }
2193
2194 return flagCall;
2195 }
2196
InnerShareForm(NativeEngine & engine,const std::shared_ptr<AbilityRuntime::AsyncTask> & asyncTask,ShareFormTask && task,int64_t formId,const std::string & remoteDeviceId)2197 void NapiFormHost::InnerShareForm(
2198 NativeEngine &engine,
2199 const std::shared_ptr<AbilityRuntime::AsyncTask> &asyncTask,
2200 ShareFormTask &&task,
2201 int64_t formId,
2202 const std::string &remoteDeviceId)
2203 {
2204 auto shareFormCallback = std::make_shared<ShareFormCallBackClient>(std::move(task));
2205 int64_t requestCode = SystemTimeMillis();
2206 FormHostClient::GetInstance()->AddShareFormCallback(shareFormCallback, requestCode);
2207
2208 ErrCode ret = FormMgr::GetInstance().ShareForm(
2209 formId, remoteDeviceId, FormHostClient::GetInstance(), requestCode);
2210 if (ret != ERR_OK) {
2211 HILOG_INFO("%{public}s, share form failed.", __func__);
2212 auto retCode = QueryRetCode(ret);
2213 auto retMsg = QueryRetMsg(retCode);
2214 asyncTask->Reject(engine, AbilityRuntime::CreateJsError(engine, retCode, retMsg));
2215 FormHostClient::GetInstance()->RemoveShareFormCallback(requestCode);
2216 }
2217 }
2218
NotifyFormsPrivacyProtected(NativeEngine * engine,NativeCallbackInfo * info)2219 NativeValue* NapiFormHost::NotifyFormsPrivacyProtected(NativeEngine *engine, NativeCallbackInfo *info)
2220 {
2221 NapiFormHost* me = OHOS::AbilityRuntime::CheckParamsAndGetThis<NapiFormHost>(engine, info);
2222 return (me != nullptr) ? me->OnNotifyFormsPrivacyProtected(*engine, *info) : nullptr;
2223 }
2224
OnNotifyFormsPrivacyProtected(NativeEngine & engine,NativeCallbackInfo & info)2225 NativeValue* NapiFormHost::OnNotifyFormsPrivacyProtected(NativeEngine &engine, NativeCallbackInfo &info)
2226 {
2227 HILOG_INFO("%{public}s is called", __func__);
2228 if (info.argc > ARGS_SIZE_THREE || info.argc < ARGS_SIZE_TWO) {
2229 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
2230 return nullptr;
2231 }
2232
2233 ErrCode errCode = ERR_OK;
2234 std::vector<int64_t> formIds {};
2235 GetFormIds(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[0]),
2236 errCode, formIds);
2237 if (errCode != ERR_OK) {
2238 HILOG_ERROR("get formIds faild, code is %{public}d", errCode);
2239 return nullptr;
2240 }
2241
2242 // The promise form has only two parameters
2243 decltype(info.argc) unwrapArgc = 2;
2244 bool isProtected = false;
2245
2246 if (!ConvertFromJsValue(engine, info.argv[1], isProtected)) {
2247 HILOG_ERROR("convert from Js value failed!");
2248 return nullptr;
2249 }
2250
2251 AsyncTask::CompleteCallback complete =
2252 [formIds, isProtected, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
2253 if (errCode != ERR_OK) {
2254 HILOG_ERROR("task reject, code is %{public}d", errCode);
2255 task.Reject(engine, CreateJsError(engine, errCode, QueryRetMsg(errCode)));
2256 return;
2257 }
2258
2259 auto ret = FormMgr::GetInstance().NotifyFormsPrivacyProtected(formIds,
2260 isProtected, FormHostClient::GetInstance());
2261 if (ret == ERR_OK) {
2262 task.Resolve(engine, engine.CreateUndefined());
2263 } else {
2264 HILOG_ERROR("task reject, result code is %{public}d", ret);
2265 auto retCode = QueryRetCode(ret);
2266 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
2267 }
2268 };
2269
2270 NativeValue *lastParam = (info.argc <= unwrapArgc) ? nullptr : info.argv[unwrapArgc];
2271 NativeValue *result = nullptr;
2272 AsyncTask::Schedule("NapiFormHost::OnNotifyFormsPrivacyProtected",
2273 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
2274 return result;
2275 }
2276 } // namespace AbilityRuntime
2277 } // namespace OHOS