• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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