1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_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 "fms_log_wrapper.h"
27 #include "form_info.h"
28 #include "form_callback_interface.h"
29 #include "form_host_client.h"
30 #include "form_mgr.h"
31 #include "form_mgr_errors.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 struct OnDeleteInvalidFormsS {
58 int result;
59 int32_t numFormsDeleted = 0;
60 std::vector<int64_t> iFormIds;
61 };
62 }
63
64 /**
65 * @brief Get a C++ string value from Node-API
66 *
67 * @param[in] env The environment that the Node-API call is invoked under
68 * @param[in] value This is an opaque pointer that is used to represent a JavaScript value
69 *
70 * @return Return a C++ string
71 */
GetStringFromNAPI(napi_env env,napi_value value)72 static std::string GetStringFromNAPI(napi_env env, napi_value value)
73 {
74 std::string result;
75 size_t size = 0;
76
77 if (napi_get_value_string_utf8(env, value, nullptr, 0, &size) != napi_ok) {
78 HILOG_ERROR("%{public}s, can not get string size", __func__);
79 return "";
80 }
81 result.reserve(size + 1);
82 result.resize(size);
83 if (napi_get_value_string_utf8(env, value, result.data(), (size + 1), &size) != napi_ok) {
84 HILOG_ERROR("%{public}s, can not get string value", __func__);
85 return "";
86 }
87 return result;
88 }
89
GetFormIds(napi_env env,napi_value value,ErrCode & errCode,std::vector<int64_t> & formIds)90 static napi_value GetFormIds(napi_env env, napi_value value, ErrCode &errCode, std::vector<int64_t> &formIds)
91 {
92 errCode = ERR_INVALID_VALUE;
93
94 bool isArray;
95 NAPI_CALL(env, napi_is_array(env, value, &isArray));
96 if (!isArray) {
97 errCode = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR;
98 return nullptr;
99 }
100
101 uint32_t arrayLength = 0;
102 NAPI_CALL(env, napi_get_array_length(env, value, &arrayLength));
103
104 for (size_t i = 0; i < arrayLength; i++) {
105 napi_value napiFormId;
106 napi_get_element(env, value, i, &napiFormId);
107
108 // Check the value type of the arguments
109 napi_valuetype valueType = napi_undefined;
110 NAPI_CALL(env, napi_typeof(env, napiFormId, &valueType));
111 if (valueType != napi_string) {
112 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
113 return nullptr;
114 }
115
116 std::string strFormId = GetStringFromNAPI(env, napiFormId);
117 int64_t formIdValue;
118 if (!ConvertStringToInt64(strFormId, formIdValue)) {
119 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
120 return nullptr;
121 }
122
123 formIds.push_back(formIdValue);
124 }
125
126 errCode = ERR_OK;
127 return nullptr;
128 }
129
ParseFormStateInfo(napi_env env,FormStateInfo & stateInfo)130 napi_value ParseFormStateInfo(napi_env env, FormStateInfo &stateInfo)
131 {
132 napi_value formStateInfoObject = nullptr;
133 napi_create_object(env, &formStateInfoObject);
134 napi_value jsValue = WrapWant(env, stateInfo.want);
135 SetPropertyValueByPropertyName(env, formStateInfoObject, "want", jsValue);
136 napi_value formState = nullptr;
137 napi_create_int32(env, (int32_t) stateInfo.state, &formState);
138 SetPropertyValueByPropertyName(env, formStateInfoObject, "formState", formState);
139
140 return formStateInfoObject;
141 }
142
AcquireFormStateCallbackComplete(uv_work_t * work,int32_t status)143 void AcquireFormStateCallbackComplete(uv_work_t *work, int32_t status)
144 {
145 HILOG_INFO("call");
146 if (work == nullptr) {
147 HILOG_ERROR("work == nullptr.");
148 return;
149 }
150 auto *asyncCallbackInfo = static_cast<AsyncAcquireFormStateCallbackInfo *>(work->data);
151 if (asyncCallbackInfo == nullptr) {
152 HILOG_ERROR("asyncCallbackInfo == nullptr.");
153 delete work;
154 return;
155 }
156 napi_env env = asyncCallbackInfo->env;
157
158 if (asyncCallbackInfo->callback != nullptr) {
159 napi_value callback;
160 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
161 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
162 if (asyncCallbackInfo->result == ERR_OK) {
163 callbackValues[1] = ParseFormStateInfo(env, asyncCallbackInfo->stateInfo);
164 }
165
166 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
167 napi_value callResult;
168 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
169 napi_delete_reference(env, asyncCallbackInfo->callback);
170 }
171
172 delete asyncCallbackInfo;
173 asyncCallbackInfo = nullptr;
174 delete work;
175 work = nullptr;
176 HILOG_INFO("end");
177 }
178
AcquireFormStatePromiseComplete(uv_work_t * work,int32_t status)179 void AcquireFormStatePromiseComplete(uv_work_t *work, int32_t status)
180 {
181 HILOG_INFO("onAcquireFormState back");
182 if (work == nullptr) {
183 HILOG_ERROR("%{public}s, work == nullptr.", __func__);
184 return;
185 }
186 auto *asyncCallbackInfo = static_cast<AsyncAcquireFormStateCallbackInfo *>(work->data);
187 if (asyncCallbackInfo == nullptr) {
188 HILOG_ERROR("asyncCallbackInfo == nullptr.");
189 delete work;
190 return;
191 }
192 napi_env env = asyncCallbackInfo->env;
193
194 if (asyncCallbackInfo->result != ERR_OK) {
195 napi_value result;
196 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
197 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
198 } else {
199 napi_value result = ParseFormStateInfo(env, asyncCallbackInfo->stateInfo);
200 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
201 }
202
203 delete asyncCallbackInfo;
204 asyncCallbackInfo = nullptr;
205 delete work;
206 work = nullptr;
207 HILOG_INFO("onAcquireFormState done");
208 }
209
210 namespace {
211 class FormStateCallbackClient : public FormStateCallbackInterface {
212 public:
FormStateCallbackClient(AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)213 explicit FormStateCallbackClient(AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
214 {
215 asyncCallbackInfo_ = asyncCallbackInfo;
216 }
217
218 virtual ~FormStateCallbackClient() = default;
219
ProcessAcquireState(FormState state)220 void ProcessAcquireState(FormState state) override
221 {
222 if (asyncCallbackInfo_ == nullptr) {
223 return;
224 }
225 asyncCallbackInfo_->stateInfo.state = state;
226
227 uv_loop_s *loop = nullptr;
228 napi_get_uv_event_loop(asyncCallbackInfo_->env, &loop);
229 if (loop == nullptr) {
230 HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
231 return;
232 }
233
234 auto *work = new (std::nothrow) uv_work_t;
235 if (work == nullptr) {
236 HILOG_ERROR("%{public}s, work == nullptr.", __func__);
237 return;
238 }
239 work->data = asyncCallbackInfo_;
240
241 int32_t result = 0;
242 if (asyncCallbackInfo_->callbackType == CALLBACK_FLG) {
243 result = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
244 AcquireFormStateCallbackComplete, uv_qos_default);
245 } else {
246 result = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {},
247 AcquireFormStatePromiseComplete, uv_qos_default);
248 }
249 // When uv_queue_work_with_qos returns 0, asyncCallbackInfo_ and work will be freed in the callback function.
250 if (result != 0) {
251 delete asyncCallbackInfo_;
252 asyncCallbackInfo_ = nullptr;
253 delete work;
254 work = nullptr;
255 }
256 }
257
258 private:
259 AsyncAcquireFormStateCallbackInfo *asyncCallbackInfo_ = nullptr;
260 };
261
262 class FormUninstallCallbackClient : public std::enable_shared_from_this<FormUninstallCallbackClient> {
263 public:
FormUninstallCallbackClient(napi_env env,napi_ref callbackRef)264 FormUninstallCallbackClient(napi_env env, napi_ref callbackRef) : callbackRef_(callbackRef), env_(env)
265 {
266 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
267 }
268
~FormUninstallCallbackClient()269 virtual ~FormUninstallCallbackClient()
270 {
271 napi_delete_reference(env_, callbackRef_);
272 }
273
ProcessFormUninstall(const int64_t formId)274 void ProcessFormUninstall(const int64_t formId)
275 {
276 if (handler_ == nullptr) {
277 HILOG_INFO("handler is null");
278 return;
279 }
280 handler_->PostSyncTask([thisWeakPtr = weak_from_this(), formId]() {
281 auto sharedThis = thisWeakPtr.lock();
282 if (sharedThis == nullptr) {
283 HILOG_ERROR("sharedThis is null.");
284 return;
285 }
286 HILOG_DEBUG("task end formId: form: %{public}" PRId64 ".", formId);
287 std::string formIdString = std::to_string(formId);
288 napi_value callbackValues;
289 napi_create_string_utf8(sharedThis->env_, formIdString.c_str(), NAPI_AUTO_LENGTH, &callbackValues);
290 napi_value callResult;
291 napi_value myCallback = nullptr;
292 napi_get_reference_value(sharedThis->env_, sharedThis->callbackRef_, &myCallback);
293 if (myCallback != nullptr) {
294 napi_call_function(sharedThis->env_, nullptr, myCallback, ARGS_SIZE_ONE, &callbackValues, &callResult);
295 }
296 });
297 }
298
IsStrictEqual(napi_value callback)299 bool IsStrictEqual(napi_value callback)
300 {
301 bool isEqual = false;
302 napi_value myCallback = nullptr;
303 napi_get_reference_value(env_, callbackRef_, &myCallback);
304 napi_strict_equals(env_, myCallback, callback, &isEqual);
305 HILOG_INFO("isStrictEqual:%{public}d", isEqual);
306 return isEqual;
307 }
308
309 private:
310 std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
311 napi_ref callbackRef_ {};
312 napi_env env_;
313 };
314
315 std::map<napi_ref, std::shared_ptr<FormUninstallCallbackClient>> g_formUninstallCallbackMap {};
316 std::mutex formUninstallCallbackMapMutex_;
317
FormUninstallCallback(const std::vector<int64_t> & formIds)318 void FormUninstallCallback(const std::vector<int64_t> &formIds)
319 {
320 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
321 for (auto &iter : g_formUninstallCallbackMap) {
322 for (int64_t formId : formIds) {
323 iter.second->ProcessFormUninstall(formId);
324 }
325 }
326 }
327
AddFormUninstallCallback(napi_env env,napi_value callback)328 bool AddFormUninstallCallback(napi_env env, napi_value callback)
329 {
330 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
331 for (auto &iter : g_formUninstallCallbackMap) {
332 if (iter.second->IsStrictEqual(callback)) {
333 HILOG_ERROR("found equal callback");
334 return false;
335 }
336 }
337
338 napi_ref callbackRef;
339 napi_create_reference(env, callback, REF_COUNT, &callbackRef);
340 std::shared_ptr<FormUninstallCallbackClient> callbackClient = std::make_shared<FormUninstallCallbackClient>(env,
341 callbackRef);
342
343 auto ret = g_formUninstallCallbackMap.emplace(callbackRef, callbackClient);
344 if (!ret.second) {
345 HILOG_ERROR("failed to emplace callback");
346 return false;
347 }
348 return true;
349 }
350
DelFormUninstallCallback(napi_value callback)351 bool DelFormUninstallCallback(napi_value callback)
352 {
353 int32_t count = 0;
354 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
355 for (auto iter = g_formUninstallCallbackMap.begin(); iter != g_formUninstallCallbackMap.end();) {
356 if (iter->second->IsStrictEqual(callback)) {
357 HILOG_INFO("equal callback");
358 iter = g_formUninstallCallbackMap.erase(iter);
359 count++;
360 } else {
361 iter++;
362 }
363 }
364 HILOG_INFO("%{public}d form uninstall callback deleted.", count);
365 return true;
366 }
367
ClearFormUninstallCallback()368 bool ClearFormUninstallCallback()
369 {
370 std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
371 g_formUninstallCallbackMap.clear();
372 return true;
373 }
374 }
375
InnerAcquireFormState(napi_env env,AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)376 static void InnerAcquireFormState(napi_env env, AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
377 {
378 HILOG_DEBUG("%{public}s called.", __func__);
379 std::shared_ptr<FormStateCallbackInterface> formStateCallback = std::make_shared<FormStateCallbackClient>(
380 asyncCallbackInfo);
381 FormHostClient::GetInstance()->AddFormState(formStateCallback, asyncCallbackInfo->want);
382
383 asyncCallbackInfo->result = FormMgr::GetInstance().AcquireFormState(asyncCallbackInfo->want,
384 FormHostClient::GetInstance(), asyncCallbackInfo->stateInfo);
385 HILOG_DEBUG("%{public}s, end", __func__);
386 }
387
AcquireFormStateCallback(napi_env env,AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)388 napi_value AcquireFormStateCallback(napi_env env, AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
389 {
390 HILOG_INFO("asyncCallback.");
391 napi_value resourceName;
392 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
393 napi_create_async_work(
394 env,
395 nullptr,
396 resourceName,
397 [](napi_env env, void *data) {
398 HILOG_INFO("napi_create_async_work running");
399 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
400 InnerAcquireFormState(env, asyncCallbackInfo);
401 },
402 [](napi_env env, napi_status status, void *data) {
403 HILOG_INFO("napi_create_async_work complete");
404 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
405 // asyncCallbackInfo will be freed in OnAcquireState, so save the member variable asyncWork.
406 napi_async_work asyncWork = asyncCallbackInfo->asyncWork;
407 // When the result is not ERR_OK, OnAcquireState will be called here,
408 // else OnAcquireState will be called after the form state is acquired.
409 if (asyncCallbackInfo->result != ERR_OK) {
410 FormHostClient::GetInstance()->OnAcquireState(FormState::UNKNOWN, asyncCallbackInfo->want);
411 }
412 napi_delete_async_work(env, asyncWork);
413 },
414 (void *) asyncCallbackInfo,
415 &asyncCallbackInfo->asyncWork);
416 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default));
417 return NapiGetResult(env, 1);
418 }
419
AcquireFormStatePromise(napi_env env,AsyncAcquireFormStateCallbackInfo * const asyncCallbackInfo)420 napi_value AcquireFormStatePromise(napi_env env, AsyncAcquireFormStateCallbackInfo *const asyncCallbackInfo)
421 {
422 HILOG_INFO("promise.");
423 napi_deferred deferred;
424 napi_value promise;
425 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
426 asyncCallbackInfo->deferred = deferred;
427
428 napi_value resourceName;
429 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
430 napi_create_async_work(
431 env,
432 nullptr,
433 resourceName,
434 [](napi_env env, void *data) {
435 HILOG_INFO("runnning");
436 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
437 InnerAcquireFormState(env, asyncCallbackInfo);
438 },
439 [](napi_env env, napi_status status, void *data) {
440 HILOG_INFO("complete");
441 auto *asyncCallbackInfo = (AsyncAcquireFormStateCallbackInfo *) data;
442 // asyncCallbackInfo will be freed in OnAcquireState, so save the member variable asyncWork.
443 napi_async_work asyncWork = asyncCallbackInfo->asyncWork;
444 // When the result is not ERR_OK, OnAcquireState will be called here,
445 // else OnAcquireState will be called after the form state is acquired.
446 if (asyncCallbackInfo->result != ERR_OK) {
447 FormHostClient::GetInstance()->OnAcquireState(FormState::UNKNOWN, asyncCallbackInfo->want);
448 }
449 napi_delete_async_work(env, asyncWork);
450 },
451 (void *) asyncCallbackInfo,
452 &asyncCallbackInfo->asyncWork);
453 napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default);
454 return promise;
455 }
456
457 /**
458 * @brief The implementation of Node-API interface: acquireFormState
459 *
460 * @param[in] env The environment that the Node-API call is invoked under
461 * @param[out] info An opaque datatype that is passed to a callback function
462 *
463 * @return This is an opaque pointer that is used to represent a JavaScript value
464 */
NAPI_AcquireFormState(napi_env env,napi_callback_info info)465 napi_value NAPI_AcquireFormState(napi_env env, napi_callback_info info)
466 {
467 HILOG_INFO("call");
468
469 // Check the number of the arguments
470 size_t argc = ARGS_SIZE_TWO;
471 napi_value argv[ARGS_SIZE_TWO] = {nullptr, nullptr};
472 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
473 if (argc > ARGS_SIZE_TWO) {
474 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
475 return nullptr;
476 }
477 HILOG_INFO("argc:[%{public}zu]", argc);
478
479 int32_t callbackType = (argc == ARGS_SIZE_TWO) ? CALLBACK_FLG : PROMISE_FLG;
480 napi_valuetype valueType = napi_undefined;
481 NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
482 if (valueType != napi_object) {
483 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[1]));
484 }
485
486 auto *asyncCallbackInfo = new (std::nothrow) AsyncAcquireFormStateCallbackInfo {
487 .env = env,
488 .asyncWork = nullptr,
489 .deferred = nullptr,
490 .callback = nullptr,
491 .want = {},
492 .stateInfo = {},
493 .callbackType = callbackType,
494 .result = ERR_OK,
495 };
496 if (asyncCallbackInfo == nullptr) {
497 HILOG_ERROR("asyncCallbackInfo == nullptr.");
498 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackType, argv[1]));
499 }
500 std::unique_ptr<AsyncAcquireFormStateCallbackInfo> callbackPtr {asyncCallbackInfo};
501
502 bool parseResult = UnwrapWant(env, argv[0], asyncCallbackInfo->want);
503 if (!parseResult) {
504 HILOG_ERROR("%{public}s, failed to parse want.", __func__);
505 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[1]));
506 }
507
508 napi_value result;
509 if (argc == ARGS_SIZE_TWO) {
510 // Check the value type of the arguments
511 valueType = napi_undefined;
512 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
513 NAPI_ASSERT(env, valueType == napi_function,
514 "The arguments[1] type of acquireFormState is incorrect, expected type is function.");
515 napi_create_reference(env, argv[1], REF_COUNT, &asyncCallbackInfo->callback);
516 result = AcquireFormStateCallback(env, asyncCallbackInfo);
517 } else {
518 result = AcquireFormStatePromise(env, asyncCallbackInfo);
519 }
520 callbackPtr.release();
521 return result;
522 }
523
524 /**
525 * @brief The implementation of Node-API interface: on
526 *
527 * @param[in] env The environment that the Node-API call is invoked under
528 * @param[out] info An opaque datatype that is passed to a callback function
529 *
530 * @return This is an opaque pointer that is used to represent a JavaScript value
531 */
NAPI_RegisterFormUninstallObserver(napi_env env,napi_callback_info info)532 napi_value NAPI_RegisterFormUninstallObserver(napi_env env, napi_callback_info info)
533 {
534 HILOG_INFO("call");
535
536 // Check the number of the arguments
537 size_t argc = ARGS_SIZE_TWO;
538 napi_value argv[ARGS_SIZE_TWO] = {nullptr, nullptr};
539 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
540 if (argc != ARGS_SIZE_TWO) {
541 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
542 return nullptr;
543 }
544 HILOG_INFO("argc:[%{public}zu]", argc);
545
546 napi_valuetype valueType = napi_undefined;
547 NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
548 if (valueType != napi_string) {
549 HILOG_ERROR("The type of args[0] is incorrect, expected type is string.");
550 return nullptr;
551 }
552 std::string type;
553 if (!UnwrapStringFromJS2(env, argv[0], type)) {
554 HILOG_ERROR("failed to get args[0].");
555 return nullptr;
556 }
557
558 if (type != "formUninstall") {
559 HILOG_ERROR("args[0] should be formUninstall.");
560 return nullptr;
561 }
562
563 valueType = napi_undefined;
564 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
565 if (valueType != napi_function) {
566 HILOG_ERROR("The type of args[1] is incorrect, expected type is function.");
567 return nullptr;
568 }
569
570 FormHostClient::GetInstance()->RegisterUninstallCallback(FormUninstallCallback);
571 AddFormUninstallCallback(env, argv[1]);
572 return nullptr;
573 }
574
575 /**
576 * @brief The implementation of Node-API interface: off
577 *
578 * @param[in] env The environment that the Node-API call is invoked under
579 * @param[out] info An opaque datatype that is passed to a callback function
580 *
581 * @return This is an opaque pointer that is used to represent a JavaScript value
582 */
NAPI_UnregisterFormUninstallObserver(napi_env env,napi_callback_info info)583 napi_value NAPI_UnregisterFormUninstallObserver(napi_env env, napi_callback_info info)
584 {
585 HILOG_INFO("call");
586
587 // Check the number of the arguments
588 size_t argc = ARGS_SIZE_TWO;
589 napi_value argv[ARGS_SIZE_TWO] = {nullptr, nullptr};
590 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
591 if (argc > ARGS_SIZE_TWO) {
592 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
593 return nullptr;
594 }
595 HILOG_INFO("argc:[%{public}zu]", argc);
596
597 napi_valuetype valueType = napi_undefined;
598 NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
599 if (valueType != napi_string) {
600 HILOG_ERROR("The type of args[0] is incorrect, expected type is string.");
601 return nullptr;
602 }
603 std::string type;
604 if (!UnwrapStringFromJS2(env, argv[0], type)) {
605 HILOG_ERROR("failed to get args[0].");
606 return nullptr;
607 }
608
609 if (type != "formUninstall") {
610 HILOG_ERROR("args[0] should be formUninstall.");
611 return nullptr;
612 }
613
614 if (argc == ARGS_SIZE_TWO) {
615 valueType = napi_undefined;
616 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
617 if (valueType != napi_function) {
618 HILOG_ERROR("The type of args[1] is incorrect, expected type is function.");
619 return nullptr;
620 }
621 DelFormUninstallCallback(argv[1]);
622 return nullptr;
623 } else {
624 ClearFormUninstallCallback();
625 return nullptr;
626 }
627 }
628
InnerNotifyFormsVisible(napi_env env,AsyncNotifyFormsVisibleCallbackInfo * const asyncCallbackInfo)629 static void InnerNotifyFormsVisible(napi_env env, AsyncNotifyFormsVisibleCallbackInfo *const asyncCallbackInfo)
630 {
631 HILOG_DEBUG("%{public}s called.", __func__);
632
633 asyncCallbackInfo->result = FormMgr::GetInstance().NotifyFormsVisible(asyncCallbackInfo->formIds,
634 asyncCallbackInfo->isVisible, FormHostClient::GetInstance());
635 HILOG_DEBUG("%{public}s, end", __func__);
636 }
637
NotifyFormsVisibleCallback(napi_env env,AsyncNotifyFormsVisibleCallbackInfo * const asyncCallbackInfo)638 napi_value NotifyFormsVisibleCallback(napi_env env, AsyncNotifyFormsVisibleCallbackInfo *const asyncCallbackInfo)
639 {
640 HILOG_INFO("start");
641 napi_value resourceName;
642 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
643 napi_create_async_work(
644 env,
645 nullptr,
646 resourceName,
647 [](napi_env env, void *data) {
648 HILOG_INFO("running");
649 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
650 InnerNotifyFormsVisible(env, asyncCallbackInfo);
651 },
652 [](napi_env env, napi_status status, void *data) {
653 HILOG_INFO("complete");
654 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
655
656 if (asyncCallbackInfo->callback != nullptr) {
657 napi_value callback;
658 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
659 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
660
661 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
662 napi_value callResult;
663 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
664 napi_delete_reference(env, asyncCallbackInfo->callback);
665 }
666 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
667 delete asyncCallbackInfo;
668 },
669 (void *) asyncCallbackInfo,
670 &asyncCallbackInfo->asyncWork);
671 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default));
672 return NapiGetResult(env, 1);
673 }
674
NotifyFormsVisiblePromise(napi_env env,AsyncNotifyFormsVisibleCallbackInfo * const asyncCallbackInfo)675 napi_value NotifyFormsVisiblePromise(napi_env env, AsyncNotifyFormsVisibleCallbackInfo *const asyncCallbackInfo)
676 {
677 HILOG_INFO("NotifyFormsVisiblePromise start");
678 napi_deferred deferred;
679 napi_value promise;
680 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
681 asyncCallbackInfo->deferred = deferred;
682
683 napi_value resourceName;
684 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
685 napi_create_async_work(
686 env,
687 nullptr,
688 resourceName,
689 [](napi_env env, void *data) {
690 HILOG_INFO("promise runnning");
691 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
692 InnerNotifyFormsVisible(env, asyncCallbackInfo);
693 },
694 [](napi_env env, napi_status status, void *data) {
695 HILOG_INFO("promise complete");
696 auto *asyncCallbackInfo = (AsyncNotifyFormsVisibleCallbackInfo *) data;
697 napi_value result;
698 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
699 if (asyncCallbackInfo->result == ERR_OK) {
700 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
701 } else {
702 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
703 }
704 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
705 delete asyncCallbackInfo;
706 },
707 (void *) asyncCallbackInfo,
708 &asyncCallbackInfo->asyncWork);
709 napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default);
710 return promise;
711 }
712
713 /**
714 * @brief The implementation of Node-API interface: notifyFormsVisible
715 *
716 * @param[in] env The environment that the Node-API call is invoked under
717 * @param[out] info An opaque datatype that is passed to a callback function
718 *
719 * @return This is an opaque pointer that is used to represent a JavaScript value
720 */
NAPI_NotifyFormsVisible(napi_env env,napi_callback_info info)721 napi_value NAPI_NotifyFormsVisible(napi_env env, napi_callback_info info)
722 {
723 HILOG_INFO("call");
724
725 // Check the number of the arguments
726 size_t argc = ARGS_SIZE_THREE;
727 napi_value argv[ARGS_SIZE_THREE] = {nullptr, nullptr, nullptr};
728 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
729 if (argc > ARGS_SIZE_THREE || argc < ARGS_SIZE_TWO) {
730 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
731 return nullptr;
732 }
733
734 int32_t callbackType = (argc == ARGS_SIZE_THREE) ? CALLBACK_FLG : PROMISE_FLG;
735
736 ErrCode errCode;
737 std::vector<int64_t> formIds {};
738 GetFormIds(env, argv[0], errCode, formIds);
739 if (errCode != ERR_OK) {
740 return RetErrMsg(InitErrMsg(env, errCode, callbackType, argv[ARGS_SIZE_TWO]));
741 }
742
743 napi_valuetype valueType = napi_undefined;
744 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
745 if (valueType != napi_boolean) {
746 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[ARGS_SIZE_TWO]));
747 }
748
749 auto *asyncCallbackInfo = new (std::nothrow) AsyncNotifyFormsVisibleCallbackInfo {
750 .env = env,
751 .asyncWork = nullptr,
752 .deferred = nullptr,
753 .callback = nullptr,
754 .formIds = formIds,
755 .isVisible = false,
756 };
757 if (asyncCallbackInfo == nullptr) {
758 HILOG_ERROR("asyncCallbackInfo == nullptr.");
759 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackType, argv[1]));
760 }
761 std::unique_ptr<AsyncNotifyFormsVisibleCallbackInfo> callbackPtr {asyncCallbackInfo};
762
763 napi_get_value_bool(env, argv[1], &asyncCallbackInfo->isVisible);
764
765 napi_value result;
766 if (argc == ARGS_SIZE_THREE) {
767 // Check the value type of the arguments
768 valueType = napi_undefined;
769 NAPI_CALL(env, napi_typeof(env, argv[ARGS_SIZE_TWO], &valueType));
770 NAPI_ASSERT(env, valueType == napi_function, "The type of arg 2 is incorrect, expected type is function.");
771 napi_create_reference(env, argv[ARGS_SIZE_TWO], REF_COUNT, &asyncCallbackInfo->callback);
772 result = NotifyFormsVisibleCallback(env, asyncCallbackInfo);
773 } else {
774 result = NotifyFormsVisiblePromise(env, asyncCallbackInfo);
775 }
776
777 callbackPtr.release();
778 return result;
779 }
780
InnerNotifyFormsEnableUpdate(napi_env env,AsyncNotifyFormsEnableUpdateCallbackInfo * const asyncCallbackInfo)781 static void InnerNotifyFormsEnableUpdate(napi_env env,
782 AsyncNotifyFormsEnableUpdateCallbackInfo *const asyncCallbackInfo)
783 {
784 HILOG_DEBUG("%{public}s called.", __func__);
785
786 asyncCallbackInfo->result = FormMgr::GetInstance().NotifyFormsEnableUpdate(asyncCallbackInfo->formIds,
787 asyncCallbackInfo->isEnableUpdate, FormHostClient::GetInstance());
788 HILOG_DEBUG("%{public}s, end", __func__);
789 }
790
NotifyFormsEnableUpdateCallback(napi_env env,AsyncNotifyFormsEnableUpdateCallbackInfo * const asyncCallbackInfo)791 napi_value NotifyFormsEnableUpdateCallback(napi_env env,
792 AsyncNotifyFormsEnableUpdateCallbackInfo *const asyncCallbackInfo)
793 {
794 HILOG_INFO("enter");
795 napi_value resourceName;
796 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
797 napi_create_async_work(
798 env,
799 nullptr,
800 resourceName,
801 [](napi_env env, void *data) {
802 HILOG_INFO("running");
803 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
804 InnerNotifyFormsEnableUpdate(env, asyncCallbackInfo);
805 },
806 [](napi_env env, napi_status status, void *data) {
807 HILOG_INFO("complete");
808 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
809
810 if (asyncCallbackInfo->callback != nullptr) {
811 napi_value callback;
812 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
813 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
814
815 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
816 napi_value callResult;
817 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
818 napi_delete_reference(env, asyncCallbackInfo->callback);
819 }
820 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
821 delete asyncCallbackInfo;
822 },
823 (void *) asyncCallbackInfo,
824 &asyncCallbackInfo->asyncWork);
825 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default));
826 return NapiGetResult(env, 1);
827 }
828
NotifyFormsEnableUpdatePromise(napi_env env,AsyncNotifyFormsEnableUpdateCallbackInfo * const asyncCallbackInfo)829 napi_value NotifyFormsEnableUpdatePromise(napi_env env,
830 AsyncNotifyFormsEnableUpdateCallbackInfo *const asyncCallbackInfo)
831 {
832 HILOG_INFO("enter");
833 napi_deferred deferred;
834 napi_value promise;
835 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
836 asyncCallbackInfo->deferred = deferred;
837
838 napi_value resourceName;
839 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
840 napi_create_async_work(
841 env,
842 nullptr,
843 resourceName,
844 [](napi_env env, void *data) {
845 HILOG_INFO("runnning");
846 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
847 InnerNotifyFormsEnableUpdate(env, asyncCallbackInfo);
848 },
849 [](napi_env env, napi_status status, void *data) {
850 HILOG_INFO("complete");
851 auto *asyncCallbackInfo = (AsyncNotifyFormsEnableUpdateCallbackInfo *) data;
852 napi_value result;
853 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
854 if (asyncCallbackInfo->result == ERR_OK) {
855 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
856 } else {
857 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
858 }
859 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
860 delete asyncCallbackInfo;
861 },
862 (void *) asyncCallbackInfo,
863 &asyncCallbackInfo->asyncWork);
864 napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default);
865 return promise;
866 }
867
868 /**
869 * @brief The implementation of Node-API interface: notifyFormsEnableUpdate
870 *
871 * @param[in] env The environment that the Node-API call is invoked under
872 * @param[out] info An opaque datatype that is passed to a callback function
873 *
874 * @return This is an opaque pointer that is used to represent a JavaScript value
875 */
NAPI_NotifyFormsEnableUpdate(napi_env env,napi_callback_info info)876 napi_value NAPI_NotifyFormsEnableUpdate(napi_env env, napi_callback_info info)
877 {
878 HILOG_INFO("call");
879
880 // Check the number of the arguments
881 size_t argc = ARGS_SIZE_THREE;
882 napi_value argv[ARGS_SIZE_THREE] = {nullptr, nullptr, nullptr};
883 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
884 if (argc > ARGS_SIZE_THREE || argc < ARGS_SIZE_TWO) {
885 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
886 return nullptr;
887 }
888
889 int32_t callbackType = (argc == ARGS_SIZE_THREE) ? CALLBACK_FLG : PROMISE_FLG;
890
891 ErrCode errCode;
892 std::vector<int64_t> formIds {};
893 GetFormIds(env, argv[0], errCode, formIds);
894 if (errCode != ERR_OK) {
895 return RetErrMsg(InitErrMsg(env, errCode, callbackType, argv[ARGS_SIZE_TWO]));
896 }
897
898 napi_valuetype valueType = napi_undefined;
899 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
900 if (valueType != napi_boolean) {
901 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_INVALID_PARAM, callbackType, argv[ARGS_SIZE_TWO]));
902 }
903
904 auto *asyncCallbackInfo = new (std::nothrow) AsyncNotifyFormsEnableUpdateCallbackInfo {
905 .env = env,
906 .asyncWork = nullptr,
907 .deferred = nullptr,
908 .callback = nullptr,
909 .formIds = formIds,
910 .isEnableUpdate = false,
911 };
912 if (asyncCallbackInfo == nullptr) {
913 HILOG_ERROR("asyncCallbackInfo == nullptr.");
914 return RetErrMsg(InitErrMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackType, argv[1]));
915 }
916 std::unique_ptr<AsyncNotifyFormsEnableUpdateCallbackInfo> callbackPtr {asyncCallbackInfo};
917
918 napi_get_value_bool(env, argv[1], &asyncCallbackInfo->isEnableUpdate);
919
920 napi_value result;
921 if (argc == ARGS_SIZE_THREE) {
922 // Check the value type of the arguments
923 valueType = napi_undefined;
924 NAPI_CALL(env, napi_typeof(env, argv[ARGS_SIZE_TWO], &valueType));
925 NAPI_ASSERT(env, valueType == napi_function, "The type of arg 2 is incorrect, expected type is function.");
926 napi_create_reference(env, argv[ARGS_SIZE_TWO], REF_COUNT, &asyncCallbackInfo->callback);
927 result = NotifyFormsEnableUpdateCallback(env, asyncCallbackInfo);
928 } else {
929 result = NotifyFormsEnableUpdatePromise(env, asyncCallbackInfo);
930 }
931 callbackPtr.release();
932 return result;
933 }
934
SystemTimeMillis()935 int64_t SystemTimeMillis() noexcept
936 {
937 struct timespec t;
938 t.tv_sec = 0;
939 t.tv_nsec = 0;
940 clock_gettime(CLOCK_MONOTONIC, &t);
941 return static_cast<int64_t>(((t.tv_sec) * NANOSECONDS + t.tv_nsec) / MICROSECONDS);
942 }
943
944 class ShareFormCallBackClient : public ShareFormCallBack,
945 public std::enable_shared_from_this<ShareFormCallBackClient> {
946 public:
ShareFormCallBackClient(ShareFormTask && task)947 explicit ShareFormCallBackClient(ShareFormTask &&task) : task_(std::move(task))
948 {
949 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
950 }
951
952 virtual ~ShareFormCallBackClient() = default;
953
ProcessShareFormResponse(int32_t result)954 void ProcessShareFormResponse(int32_t result) override
955 {
956 if (handler_) {
957 handler_->PostSyncTask([client = shared_from_this(), result] () {
958 client->task_(result);
959 });
960 }
961 }
962
963 private:
964 ShareFormTask task_;
965 std::shared_ptr<AppExecFwk::EventHandler> handler_;
966 };
967
Finalizer(napi_env env,void * data,void * hint)968 void NapiFormHost::Finalizer(napi_env env, void *data, void *hint)
969 {
970 HILOG_DEBUG("NapiFormHost::Finalizer is called");
971 std::unique_ptr<NapiFormHost>(static_cast<NapiFormHost*>(data));
972 }
973
ShareForm(napi_env env,napi_callback_info info)974 napi_value NapiFormHost::ShareForm(napi_env env, napi_callback_info info)
975 {
976 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnShareForm);
977 }
978
DisableFormsUpdate(napi_env env,napi_callback_info info)979 napi_value NapiFormHost::DisableFormsUpdate(napi_env env, napi_callback_info info)
980 {
981 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnDisableFormsUpdate);
982 }
983
IsSystemReady(napi_env env,napi_callback_info info)984 napi_value NapiFormHost::IsSystemReady(napi_env env, napi_callback_info info)
985 {
986 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnIsSystemReady);
987 }
988
GetAllFormsInfo(napi_env env,napi_callback_info info)989 napi_value NapiFormHost::GetAllFormsInfo(napi_env env, napi_callback_info info)
990 {
991 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnGetAllFormsInfo);
992 }
993
GetFormsInfo(napi_env env,napi_callback_info info)994 napi_value NapiFormHost::GetFormsInfo(napi_env env, napi_callback_info info)
995 {
996 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnGetFormsInfo);
997 }
998
DeleteForm(napi_env env,napi_callback_info info)999 napi_value NapiFormHost::DeleteForm(napi_env env, napi_callback_info info)
1000 {
1001 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnDeleteForm);
1002 }
1003
ReleaseForm(napi_env env,napi_callback_info info)1004 napi_value NapiFormHost::ReleaseForm(napi_env env, napi_callback_info info)
1005 {
1006 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnReleaseForm);
1007 }
1008
RequestForm(napi_env env,napi_callback_info info)1009 napi_value NapiFormHost::RequestForm(napi_env env, napi_callback_info info)
1010 {
1011 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnRequestForm);
1012 }
1013
CastTempForm(napi_env env,napi_callback_info info)1014 napi_value NapiFormHost::CastTempForm(napi_env env, napi_callback_info info)
1015 {
1016 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnCastTempForm);
1017 }
1018
EnableFormsUpdate(napi_env env,napi_callback_info info)1019 napi_value NapiFormHost::EnableFormsUpdate(napi_env env, napi_callback_info info)
1020 {
1021 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnEnableFormsUpdate);
1022 }
1023
DeleteInvalidForms(napi_env env,napi_callback_info info)1024 napi_value NapiFormHost::DeleteInvalidForms(napi_env env, napi_callback_info info)
1025 {
1026 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnDeleteInvalidForms);
1027 }
1028
NotifyVisibleForms(napi_env env,napi_callback_info info)1029 napi_value NapiFormHost::NotifyVisibleForms(napi_env env, napi_callback_info info)
1030 {
1031 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnNotifyVisibleForms);
1032 }
1033
NotifyInVisibleForms(napi_env env,napi_callback_info info)1034 napi_value NapiFormHost::NotifyInVisibleForms(napi_env env, napi_callback_info info)
1035 {
1036 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnNotifyInVisibleForms);
1037 }
1038
OnShareForm(napi_env env,size_t argc,napi_value * argv)1039 napi_value NapiFormHost::OnShareForm(napi_env env, size_t argc, napi_value* argv)
1040 {
1041 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1042 int32_t errCode = ERR_OK;
1043 if (argc > ARGS_SIZE_THREE || argc < ARGS_SIZE_TWO) {
1044 HILOG_ERROR("wrong number of arguments.");
1045 errCode = ERR_ADD_INVALID_PARAM;
1046 }
1047
1048 std::string strFormId =
1049 GetStringFromNAPI(env, argv[0]);
1050 std::string remoteDeviceId =
1051 GetStringFromNAPI(env, argv[1]);
1052 // The promise form has only two parameters
1053 decltype(argc) unwrapArgc = 2;
1054
1055 int64_t formId = 0;
1056 if (!ConvertStringToInt64(strFormId, formId)) {
1057 HILOG_ERROR("convert string formId to int64 failed.");
1058 errCode = ERR_COMMON;
1059 }
1060 if (formId == 0 || remoteDeviceId.empty()) {
1061 errCode = ERR_COMMON;
1062 }
1063
1064 napi_value lastParam = (argc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
1065 napi_value result = nullptr;
1066
1067 std::unique_ptr<AbilityRuntime::NapiAsyncTask> uasyncTask =
1068 AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
1069 std::shared_ptr<AbilityRuntime::NapiAsyncTask> asyncTask = std::move(uasyncTask);
1070
1071 ShareFormTask task = [env, asyncTask](int32_t code) {
1072 HILOG_DEBUG("task complete code: %{public}d", code);
1073 if (code == ERR_OK) {
1074 asyncTask->Resolve(env, CreateJsUndefined(env));
1075 } else {
1076 auto retCode = QueryRetCode(code);
1077 auto retMsg = QueryRetMsg(retCode);
1078 asyncTask->Reject(env, AbilityRuntime::CreateJsError(env, retCode, retMsg));
1079 }
1080 };
1081
1082 if (errCode != ERR_OK) {
1083 asyncTask->Reject(env, AbilityRuntime::CreateJsError(env, errCode, "Invalidate params."));
1084 } else {
1085 InnerShareForm(env, asyncTask, std::move(task), formId, remoteDeviceId);
1086 }
1087
1088 return result;
1089 }
1090
OnDisableFormsUpdate(napi_env env,size_t argc,napi_value * argv)1091 napi_value NapiFormHost::OnDisableFormsUpdate(napi_env env, size_t argc, napi_value* argv)
1092 {
1093 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1094 int32_t errCode = ERR_OK;
1095 if (argc > ARGS_TWO || argc < ARGS_ONE) {
1096 HILOG_ERROR("wrong number of arguments!");
1097 return CreateJsUndefined(env);
1098 }
1099
1100 std::vector<string> strFormIdList;
1101 if (!GetStringsValue(env, argv[PARAM0], strFormIdList)) {
1102 HILOG_ERROR("conversion string failed!");
1103 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1104 }
1105 if (strFormIdList.empty()) {
1106 HILOG_ERROR("formId list is empty!");
1107 errCode = ERR_APPEXECFWK_FORM_FORM_ID_ARRAY_ERR;
1108 }
1109 std::vector<int64_t> iFormIds;
1110 for (size_t i = 0; i < strFormIdList.size(); i++) {
1111 int64_t formIdValue;
1112 if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
1113 HILOG_ERROR("conversion int failed!");
1114 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1115 } else {
1116 iFormIds.push_back(formIdValue);
1117 }
1118 }
1119
1120 auto complete = [formIds = iFormIds, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1121 if (errCode != ERR_OK) {
1122 auto code = QueryRetCode(errCode);
1123 task.Reject(env, CreateJsError(env, code, QueryRetMsg(code)));
1124 return;
1125 }
1126 auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), false);
1127 if (ret != ERR_OK) {
1128 auto retCode = QueryRetCode(ret);
1129 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1130 return;
1131 }
1132 task.Resolve(env, CreateJsValue(env, ret));
1133 };
1134
1135 auto callback = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1136 napi_value result = nullptr;
1137 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnDisableFormsUpdate",
1138 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
1139 return result;
1140 }
1141
OnIsSystemReady(napi_env env,size_t argc,napi_value * argv)1142 napi_value NapiFormHost::OnIsSystemReady(napi_env env, size_t argc, napi_value* argv)
1143 {
1144 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1145 if (argc > ARGS_ONE || argc < ARGS_ZERO) {
1146 HILOG_ERROR("wrong number of arguments.");
1147 return CreateJsUndefined(env);
1148 }
1149
1150 auto complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
1151 // Use original logic.
1152 // Use the error code to return whether the function executed successfully.
1153 auto ret = FormMgr::GetInstance().CheckFMSReady() ? 0 : 1;
1154 if (ret == ERR_OK) {
1155 task.Resolve(env, CreateJsUndefined(env));
1156 } else {
1157 auto retCode = QueryRetCode(ret);
1158 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1159 }
1160 };
1161
1162 auto callback = (argc == ARGS_ZERO) ? nullptr : argv[PARAM0];
1163 napi_value result = nullptr;
1164 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnIsSystemReady",
1165 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
1166 return result;
1167 }
1168
OnGetAllFormsInfo(napi_env env,size_t argc,napi_value * argv)1169 napi_value NapiFormHost::OnGetAllFormsInfo(napi_env env, size_t argc, napi_value* argv)
1170 {
1171 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1172 if (argc > ARGS_ONE || argc < ARGS_ZERO) {
1173 HILOG_ERROR("wrong number of arguments!");
1174 return CreateJsUndefined(env);
1175 }
1176
1177 auto complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
1178 std::vector<FormInfo> formInfos;
1179 auto ret = FormMgr::GetInstance().GetAllFormsInfo(formInfos);
1180 if (ret != ERR_OK) {
1181 auto retCode = QueryRetCode(ret);
1182 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1183 return;
1184 }
1185 task.Resolve(env, CreateFormInfos(env, formInfos));
1186 };
1187
1188 auto callback = (argc == ARGS_ZERO) ? nullptr : argv[PARAM0];
1189 napi_value result = nullptr;
1190 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnGetAllFormsInfo",
1191 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
1192 return result;
1193 }
1194
OnGetFormsInfo(napi_env env,size_t argc,napi_value * argv)1195 napi_value NapiFormHost::OnGetFormsInfo(napi_env env, size_t argc, napi_value* argv)
1196 {
1197 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1198 int32_t errCode = ERR_OK;
1199 if (argc > ARGS_THREE || argc < ARGS_ONE) {
1200 HILOG_ERROR("wrong number of arguments!");
1201 return CreateJsUndefined(env);
1202 }
1203
1204 std::string bName("");
1205 if (!ConvertFromJsValue(env, argv[PARAM0], bName)) {
1206 HILOG_ERROR("conversion failed!");
1207 errCode = ERR_APPEXECFWK_FORM_INVALID_BUNDLENAME;
1208 }
1209
1210 std::string mName("");
1211 bool bParam = false;
1212 bool flagCall = UnwrapGetFormsInfoParams(env, argc, argv, mName, bParam);
1213 auto complete = [bName, mName, bParam, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1214 std::string bundleName(bName);
1215 std::string moduleName(mName);
1216 std::vector<FormInfo> formInfos;
1217 if (errCode != ERR_OK) {
1218 auto retCode = QueryRetCode(errCode);
1219 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1220 return;
1221 }
1222 int ret = ERR_OK;
1223 if (!bParam) {
1224 ret = FormMgr::GetInstance().GetFormsInfoByApp(bundleName, formInfos);
1225 } else {
1226 ret = FormMgr::GetInstance().GetFormsInfoByModule(bundleName, moduleName, formInfos);
1227 }
1228
1229 if (ret != ERR_OK) {
1230 auto retCode = QueryRetCode(ret);
1231 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1232 return;
1233 }
1234 task.Resolve(env, CreateFormInfos(env, formInfos));
1235 };
1236
1237 napi_value result = nullptr;
1238 auto callback = flagCall ? ((argc == ARGS_TWO) ? argv[PARAM1] : argv[PARAM2]) : nullptr;
1239 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnGetFormsInfo",
1240 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
1241 return result;
1242 }
1243
OnDeleteForm(napi_env env,size_t argc,napi_value * argv)1244 napi_value NapiFormHost::OnDeleteForm(napi_env env, size_t argc, napi_value* argv)
1245 {
1246 HILOG_DEBUG("%{public}s called.", __func__);
1247
1248 int32_t errCode = ERR_OK;
1249 int64_t formId = 0;
1250 if (argc > ARGS_TWO || argc < ARGS_ONE) {
1251 HILOG_ERROR("OnDeleteForm wrong number of arguments.");
1252 return CreateJsUndefined(env);
1253 }
1254 if (!IsTypeForNapiValue(env, argv[PARAM0], napi_string)) {
1255 HILOG_ERROR("input arguments is not string!");
1256 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
1257 } else {
1258 std::string strFormId;
1259 if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
1260 HILOG_ERROR("conversion failed!");
1261 return CreateJsUndefined(env);
1262 }
1263 if (!ConvertStringToInt64(strFormId, formId)) {
1264 HILOG_ERROR("OnDeleteForm convert string formId to int64 failed.");
1265 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1266 }
1267 }
1268 NapiAsyncTask::CompleteCallback complete = [formId, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1269 if (errCode != ERR_OK) {
1270 auto retCode = QueryRetCode(errCode);
1271 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1272 return;
1273 }
1274 auto ret = FormMgr::GetInstance().DeleteForm(formId, FormHostClient::GetInstance());
1275 if (ret == ERR_OK) {
1276 auto result = QueryRetCode(ret);
1277 task.Resolve(env, CreateJsValue(env, result));
1278 } else {
1279 auto retCode = QueryRetCode(ret);
1280 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1281 }
1282 };
1283
1284 napi_value lastParam = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1285 napi_value result = nullptr;
1286 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnDeleteForm",
1287 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1288 return result;
1289 }
1290
OnReleaseForm(napi_env env,size_t argc,napi_value * argv)1291 napi_value NapiFormHost::OnReleaseForm(napi_env env,
1292 size_t argc, napi_value* argv)
1293 {
1294 HILOG_DEBUG("%{public}s called.", __func__);
1295
1296 int32_t errCode = ERR_OK;
1297 int64_t formId = 0;
1298 bool isReleaseCache = false;
1299 if (argc > ARGS_THREE || argc < ARGS_ONE) {
1300 HILOG_ERROR("OnReleaseForm wrong number of arguments.");
1301 return CreateJsUndefined(env);
1302 }
1303 if (!IsTypeForNapiValue(env, argv[PARAM0], napi_string)) {
1304 HILOG_ERROR("input params is not string!");
1305 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
1306 } else {
1307 std::string strFormId;
1308 if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
1309 HILOG_ERROR("conversion error!");
1310 return CreateJsUndefined(env);
1311 }
1312 if (!ConvertStringToInt64(strFormId, formId)) {
1313 HILOG_ERROR("OnReleaseForm convert string formId to int64 failed.");
1314 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1315 } else if ((argc == ARGS_TWO || argc == ARGS_THREE) &&
1316 !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1317 if (IsTypeForNapiValue(env, argv[PARAM1], napi_boolean)) {
1318 if (!ConvertFromJsValue(env, argv[PARAM1], isReleaseCache)) {
1319 HILOG_ERROR("conversion bool failed!");
1320 return CreateJsUndefined(env);
1321 }
1322 } else {
1323 HILOG_ERROR("promise second param type is illegal");
1324 errCode = ERR_APPEXECFWK_FORM_RELEASE_FLG_ERR;
1325 }
1326 }
1327 }
1328
1329 NapiAsyncTask::CompleteCallback complete = [formId, errCode, isReleaseCache]
1330 (napi_env env, NapiAsyncTask &task, int32_t status) {
1331 auto ret = ERR_COMMON;
1332 if (errCode != ERR_OK) {
1333 auto retCode = QueryRetCode(errCode);
1334 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1335 return ;
1336 }
1337 ret = FormMgr::GetInstance().ReleaseForm(formId, FormHostClient::GetInstance(), isReleaseCache);
1338 if (ret == ERR_OK) {
1339 auto result = QueryRetCode(ret);
1340 task.Resolve(env, CreateJsValue(env, result));
1341 } else {
1342 auto retCode = QueryRetCode(ret);
1343 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1344 return;
1345 }
1346 };
1347
1348 napi_value lastParam = (argc == ARGS_ONE) ? nullptr :
1349 (argc == ARGS_TWO && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) ? nullptr :
1350 (argc == ARGS_THREE) ? argv[PARAM2] : argv[PARAM1];
1351 napi_value result = nullptr;
1352 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnReleaseForm",
1353 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1354 return result;
1355 }
1356
OnRequestForm(napi_env env,size_t argc,napi_value * argv)1357 napi_value NapiFormHost::OnRequestForm(napi_env env, size_t argc, napi_value* argv)
1358 {
1359 HILOG_DEBUG("%{public}s called.", __func__);
1360
1361 int32_t errCode = ERR_OK;
1362 int64_t formId = 0;
1363 if (argc > ARGS_TWO || argc < ARGS_ONE) {
1364 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1365 return CreateJsUndefined(env);
1366 }
1367 if (!IsTypeForNapiValue(env, argv[PARAM0], napi_string)) {
1368 HILOG_ERROR("input params is not string!");
1369 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
1370 } else {
1371 std::string strFormId;
1372 if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
1373 HILOG_ERROR("transform failed!");
1374 return CreateJsUndefined(env);
1375 }
1376 if (!ConvertStringToInt64(strFormId, formId)) {
1377 HILOG_ERROR("%{public}s, convert string formId to int64 failed.", __func__);
1378 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1379 }
1380 }
1381 NapiAsyncTask::CompleteCallback complete = [formId, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1382 if (errCode != ERR_OK) {
1383 auto retCode = QueryRetCode(errCode);
1384 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1385 return;
1386 }
1387 Want want;
1388 auto ret = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
1389 if (ret == ERR_OK) {
1390 auto result = QueryRetCode(ret);
1391 task.Resolve(env, CreateJsValue(env, result));
1392 } else {
1393 auto retCode = QueryRetCode(ret);
1394 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1395 }
1396 };
1397
1398 napi_value lastParam = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1399 napi_value result = nullptr;
1400 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnRequestForm",
1401 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1402 return result;
1403 }
1404
OnCastTempForm(napi_env env,size_t argc,napi_value * argv)1405 napi_value NapiFormHost::OnCastTempForm(napi_env env, size_t argc, napi_value* argv)
1406 {
1407 HILOG_DEBUG("%{public}s called.", __func__);
1408
1409 int32_t errCode = ERR_OK;
1410 int64_t formId = 0;
1411 if (argc > ARGS_TWO || argc < ARGS_ONE) {
1412 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1413 return CreateJsUndefined(env);
1414 }
1415 if (!IsTypeForNapiValue(env, argv[PARAM0], napi_string)) {
1416 HILOG_ERROR("input arguments is not string!");
1417 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
1418 } else {
1419 std::string strFormId;
1420 if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
1421 HILOG_ERROR("transform failed!");
1422 return CreateJsUndefined(env);
1423 }
1424 if (!ConvertStringToInt64(strFormId, formId)) {
1425 HILOG_ERROR("%{public}s, convert string formId to int64 failed.", __func__);
1426 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1427 }
1428 }
1429 NapiAsyncTask::CompleteCallback complete = [formId, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1430 if (errCode != ERR_OK) {
1431 auto retCode = QueryRetCode(errCode);
1432 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1433 return;
1434 }
1435 auto ret = FormMgr::GetInstance().CastTempForm(formId, FormHostClient::GetInstance());
1436 if (ret == ERR_OK) {
1437 auto result = QueryRetCode(ret);
1438 task.Resolve(env, CreateJsValue(env, result));
1439 } else {
1440 auto retCode = QueryRetCode(ret);
1441 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1442 }
1443 };
1444
1445 napi_value lastParam = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1446 napi_value result = nullptr;
1447 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnCastTempForm",
1448 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1449 return result;
1450 }
1451
OnEnableFormsUpdate(napi_env env,size_t argc,napi_value * argv)1452 napi_value NapiFormHost::OnEnableFormsUpdate(napi_env env, size_t argc, napi_value* argv)
1453 {
1454 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1455
1456 int32_t errCode = ERR_OK;
1457 std::vector<int64_t> iFormIds;
1458 if (argc > ARGS_TWO|| argc < ARGS_ONE) {
1459 HILOG_ERROR("wrong number of arguments!");
1460 return CreateJsUndefined(env);
1461 }
1462 std::vector<string> strFormIdList;
1463 if (!GetStringsValue(env, argv[PARAM0], strFormIdList)) {
1464 HILOG_ERROR("conversion string failed!");
1465 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1466 }
1467 for (size_t i = 0; i < strFormIdList.size(); i++) {
1468 int64_t formIdValue;
1469 if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
1470 HILOG_ERROR("conversion int failed!");
1471 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1472 } else {
1473 iFormIds.push_back(formIdValue);
1474 }
1475 }
1476 auto complete = [iFormIds, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1477 if (errCode != ERR_OK) {
1478 auto code = QueryRetCode(errCode);
1479 task.Reject(env, CreateJsError(env, code, QueryRetMsg(code)));
1480 return;
1481 }
1482 auto ret = FormMgr::GetInstance().LifecycleUpdate(iFormIds, FormHostClient::GetInstance(), true);
1483 if (ret == ERR_OK) {
1484 auto result = QueryRetCode(ret);
1485 task.Resolve(env, CreateJsValue(env, result));
1486 } else {
1487 auto retCode = QueryRetCode(ret);
1488 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1489 }
1490 };
1491
1492 auto callback = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1493 napi_value result = nullptr;
1494 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnEnableFormsUpdate",
1495 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
1496 return result;
1497 }
1498
GetStringsValue(napi_env env,napi_value array,std::vector<std::string> & strList)1499 bool NapiFormHost::GetStringsValue(napi_env env, napi_value array, std::vector<std::string> &strList)
1500 {
1501 uint32_t nativeArrayLen = 0;
1502 napi_get_array_length(env, array, &nativeArrayLen);
1503 napi_value element = nullptr;
1504
1505 for (uint32_t i = 0; i < nativeArrayLen; i++) {
1506 std::string itemStr("");
1507 napi_get_element(env, array, i, &element);
1508 if (!ConvertFromJsValue(env, element, itemStr)) {
1509 HILOG_ERROR("GetElement from to array [%{public}u] error", i);
1510 return false;
1511 }
1512 strList.push_back(itemStr);
1513 }
1514
1515 return true;
1516 }
1517
UnwrapGetFormsInfoParams(napi_env env,size_t argc,napi_value * argv,std::string & moduleName,bool & bParam)1518 bool NapiFormHost::UnwrapGetFormsInfoParams(
1519 napi_env env, size_t argc, napi_value* argv, std::string &moduleName, bool &bParam)
1520 {
1521 bool flagCall = true;
1522 if (argc == ARGS_ONE) {
1523 flagCall = false;
1524 bParam = false;
1525 } else if (argc == ARGS_TWO && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1526 if (!ConvertFromJsValue(env, argv[PARAM1], moduleName)) {
1527 HILOG_WARN("input params string error");
1528 }
1529 flagCall = false;
1530 bParam = true;
1531 } else if (argc == ARGS_TWO && IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1532 bParam = false;
1533 } else if (argc == ARGS_THREE) {
1534 if (!ConvertFromJsValue(env, argv[PARAM1], moduleName)) {
1535 HILOG_WARN("input params string error");
1536 }
1537 bParam = true;
1538 }
1539
1540 return flagCall;
1541 }
1542
InnerShareForm(napi_env env,const std::shared_ptr<AbilityRuntime::NapiAsyncTask> & asyncTask,ShareFormTask && task,int64_t formId,const std::string & remoteDeviceId)1543 void NapiFormHost::InnerShareForm(
1544 napi_env env,
1545 const std::shared_ptr<AbilityRuntime::NapiAsyncTask> &asyncTask,
1546 ShareFormTask &&task,
1547 int64_t formId,
1548 const std::string &remoteDeviceId)
1549 {
1550 auto shareFormCallback = std::make_shared<ShareFormCallBackClient>(std::move(task));
1551 int64_t requestCode = SystemTimeMillis();
1552 FormHostClient::GetInstance()->AddShareFormCallback(shareFormCallback, requestCode);
1553
1554 ErrCode ret = FormMgr::GetInstance().ShareForm(
1555 formId, remoteDeviceId, FormHostClient::GetInstance(), requestCode);
1556 if (ret != ERR_OK) {
1557 HILOG_INFO("share form fail");
1558 auto retCode = QueryRetCode(ret);
1559 auto retMsg = QueryRetMsg(retCode);
1560 asyncTask->Reject(env, AbilityRuntime::CreateJsError(env, retCode, retMsg));
1561 FormHostClient::GetInstance()->RemoveShareFormCallback(requestCode);
1562 }
1563 }
1564
NotifyFormsPrivacyProtected(napi_env env,napi_callback_info info)1565 napi_value NapiFormHost::NotifyFormsPrivacyProtected(napi_env env, napi_callback_info info)
1566 {
1567 GET_CB_INFO_AND_CALL(env, info, NapiFormHost, OnNotifyFormsPrivacyProtected);
1568 }
1569
OnNotifyFormsPrivacyProtected(napi_env env,size_t argc,napi_value * argv)1570 napi_value NapiFormHost::OnNotifyFormsPrivacyProtected(napi_env env, size_t argc, napi_value* argv)
1571 {
1572 HILOG_INFO("call");
1573 if (argc > ARGS_SIZE_THREE || argc < ARGS_SIZE_TWO) {
1574 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
1575 return nullptr;
1576 }
1577
1578 ErrCode errCode = ERR_OK;
1579 std::vector<int64_t> formIds {};
1580 GetFormIds(env, argv[0], errCode, formIds);
1581 if (errCode != ERR_OK) {
1582 HILOG_ERROR("get formIds faild, code is %{public}d", errCode);
1583 return nullptr;
1584 }
1585
1586 // The promise form has only two parameters
1587 decltype(argc) unwrapArgc = 2;
1588 bool isProtected = false;
1589
1590 if (!ConvertFromJsValue(env, argv[1], isProtected)) {
1591 HILOG_ERROR("convert from Js value failed!");
1592 return nullptr;
1593 }
1594
1595 NapiAsyncTask::CompleteCallback complete =
1596 [formIds, isProtected, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1597 if (errCode != ERR_OK) {
1598 HILOG_ERROR("task reject, code is %{public}d", errCode);
1599 task.Reject(env, CreateJsError(env, errCode, QueryRetMsg(errCode)));
1600 return;
1601 }
1602
1603 auto ret = FormMgr::GetInstance().NotifyFormsPrivacyProtected(formIds,
1604 isProtected, FormHostClient::GetInstance());
1605 if (ret == ERR_OK) {
1606 task.Resolve(env, CreateJsUndefined(env));
1607 } else {
1608 HILOG_ERROR("task reject, result code is %{public}d", ret);
1609 auto retCode = QueryRetCode(ret);
1610 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1611 }
1612 };
1613
1614 napi_value lastParam = (argc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
1615 napi_value result = nullptr;
1616 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnNotifyFormsPrivacyProtected",
1617 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1618 return result;
1619 }
1620
OnDeleteInvalidFormsParseParam(napi_env env,size_t argc,napi_value * argv,int32_t & errCode,std::vector<std::string> & strFormIdList)1621 bool NapiFormHost::OnDeleteInvalidFormsParseParam(napi_env env, size_t argc, napi_value* argv,
1622 int32_t &errCode, std::vector<std::string> &strFormIdList)
1623 {
1624 if (argc > ARGS_TWO || argc < ARGS_ONE) {
1625 HILOG_ERROR("wrong number of arguments.");
1626 return false;
1627 }
1628 if (!GetStringsValue(env, argv[PARAM0], strFormIdList)) {
1629 HILOG_ERROR("conversion string failed!");
1630 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1631 }
1632 if (strFormIdList.empty()) {
1633 HILOG_ERROR("formId list is empty!");
1634 errCode = ERR_APPEXECFWK_FORM_FORM_ID_ARRAY_ERR;
1635 }
1636 return true;
1637 }
1638
OnDeleteInvalidForms(napi_env env,size_t argc,napi_value * argv)1639 napi_value NapiFormHost::OnDeleteInvalidForms(napi_env env, size_t argc, napi_value* argv)
1640 {
1641 HILOG_DEBUG("called");
1642
1643 int32_t errCode = ERR_OK;
1644 std::vector<std::string> strFormIdList;
1645 if (!OnDeleteInvalidFormsParseParam(env, argc, argv, errCode, strFormIdList)) {
1646 HILOG_ERROR("parse param failed");
1647 return CreateJsNull(env);
1648 }
1649
1650 std::shared_ptr<OnDeleteInvalidFormsS> onDeleteInvalidForms = std::make_shared<OnDeleteInvalidFormsS>();
1651 for (size_t i = 0; i < strFormIdList.size(); i++) {
1652 int64_t formIdValue;
1653 if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
1654 HILOG_ERROR("conversion int failed!");
1655 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1656 } else {
1657 onDeleteInvalidForms->iFormIds.push_back(formIdValue);
1658 }
1659 }
1660 auto execute = [data = onDeleteInvalidForms] {
1661 if (data == nullptr) {
1662 HILOG_ERROR("onDeleteInvalidForms is nullptr.");
1663 return;
1664 }
1665 data->result = FormMgr::GetInstance().DeleteInvalidForms(
1666 data->iFormIds, FormHostClient::GetInstance(), data->numFormsDeleted);
1667 };
1668 auto complete = [data = onDeleteInvalidForms, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1669 if (errCode != ERR_OK) {
1670 auto retCode = QueryRetCode(errCode);
1671 auto retMsg = QueryRetMsg(retCode);
1672 task.Reject(env, CreateJsError(env, retCode, retMsg));
1673 return;
1674 }
1675 auto retCode = QueryRetCode(data->result);
1676 auto retMsg = QueryRetMsg(retCode);
1677 if (data->result == ERR_OK) {
1678 task.ResolveWithCustomize(env, CreateJsError(env, retCode, retMsg),
1679 CreateJsValue(env, data->numFormsDeleted));
1680 } else {
1681 task.Reject(env, CreateJsError(env, retCode, retMsg));
1682 }
1683 };
1684
1685 auto callback = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1686 napi_value result = nullptr;
1687 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnDeleteInvalidForms",
1688 env, CreateAsyncTaskWithLastParam(env, callback, std::move(execute), std::move(complete), &result));
1689 return result;
1690 }
1691
OnNotifyVisibleForms(napi_env env,size_t argc,napi_value * argv)1692 napi_value NapiFormHost::OnNotifyVisibleForms(napi_env env, size_t argc, napi_value* argv)
1693 {
1694 HILOG_DEBUG("called");
1695
1696 int32_t errCode = ERR_OK;
1697 std::vector<int64_t> iFormIds;
1698 if (argc > ARGS_TWO || argc < ARGS_ONE) {
1699 HILOG_ERROR("wrong number of arguments!");
1700 return CreateJsUndefined(env);
1701 }
1702 bool isArray = false;
1703 napi_is_array(env, argv[PARAM0], &isArray);
1704 if (!isArray) {
1705 HILOG_ERROR("input params0 is not array!");
1706 errCode = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR;
1707 } else {
1708 std::vector<string> strFormIdList;
1709 if (!GetStringsValue(env, argv[PARAM0], strFormIdList)) {
1710 HILOG_ERROR("conversion string failed!");
1711 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1712 }
1713 for (size_t i = 0; i < strFormIdList.size(); i++) {
1714 int64_t formIdValue;
1715 if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
1716 HILOG_ERROR("conversion int error!");
1717 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1718 } else {
1719 iFormIds.push_back(formIdValue);
1720 }
1721 }
1722 }
1723 auto complete = [iFormIds, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1724 if (errCode != ERR_OK) {
1725 auto code = QueryRetCode(errCode);
1726 task.Reject(env, CreateJsError(env, code, QueryRetMsg(code)));
1727 return;
1728 }
1729 auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(iFormIds, FormHostClient::GetInstance(),
1730 Constants::FORM_VISIBLE);
1731 auto retCode = QueryRetCode(ret);
1732 if (ret == ERR_OK) {
1733 task.ResolveWithCustomize(env, CreateJsError(env, retCode, QueryRetMsg(retCode)), CreateJsUndefined(env));
1734 } else {
1735 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1736 }
1737 };
1738 auto callback = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1739 napi_value result = nullptr;
1740 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnNotifyVisibleForms",
1741 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
1742 return result;
1743 }
1744
OnNotifyInVisibleFormsParseParam(napi_env env,size_t argc,napi_value * argv,std::vector<int64_t> & formIds)1745 int32_t NapiFormHost::OnNotifyInVisibleFormsParseParam(napi_env env, size_t argc, napi_value* argv,
1746 std::vector<int64_t> &formIds)
1747 {
1748 if (argc > ARGS_TWO || argc < ARGS_ONE) {
1749 HILOG_ERROR("wrong number of arguments. argc is %{public}zu", argc);
1750 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
1751 }
1752
1753 bool isArray = false;
1754 int32_t errCode = ERR_OK;
1755 napi_is_array(env, argv[PARAM0], &isArray);
1756 if (!isArray) {
1757 HILOG_ERROR("input params is not array!");
1758 errCode = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR;
1759 } else {
1760 std::vector<string> strFormIdList;
1761 if (!GetStringsValue(env, argv[PARAM0], strFormIdList)) {
1762 HILOG_ERROR("conversion string failed!");
1763 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
1764 } else {
1765 if (strFormIdList.size() == 0) {
1766 HILOG_ERROR("input params is null!");
1767 errCode = ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR;
1768 }
1769 }
1770 for (size_t i = 0; i < strFormIdList.size(); i++) {
1771 int64_t formIdValue;
1772 if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
1773 HILOG_ERROR("transform int failed!");
1774 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
1775 } else {
1776 formIds.push_back(formIdValue);
1777 }
1778 }
1779 }
1780 return errCode;
1781 }
1782
OnNotifyInVisibleForms(napi_env env,size_t argc,napi_value * argv)1783 napi_value NapiFormHost::OnNotifyInVisibleForms(napi_env env, size_t argc, napi_value* argv)
1784 {
1785 HILOG_DEBUG("called");
1786
1787 int32_t errCode;
1788 std::vector<int64_t> formIds;
1789
1790 errCode = OnNotifyInVisibleFormsParseParam(env, argc, argv, formIds);
1791 if (errCode == ERR_APPEXECFWK_FORM_INVALID_PARAM) {
1792 return CreateJsUndefined(env);
1793 }
1794
1795 auto complete = [formIds = formIds, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
1796 if (errCode != ERR_OK) {
1797 auto code = QueryRetCode(errCode);
1798 task.Reject(env, CreateJsError(env, code, QueryRetMsg(code)));
1799 return;
1800 }
1801 auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds,
1802 FormHostClient::GetInstance(), Constants::FORM_INVISIBLE);
1803 if (ret == ERR_OK) {
1804 auto resultCode = QueryRetCode(ret);
1805 task.ResolveWithCustomize(
1806 env, CreateJsError(env, resultCode, QueryRetMsg(resultCode)), CreateJsUndefined(env));
1807 } else {
1808 auto retCode = QueryRetCode(ret);
1809 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
1810 }
1811 };
1812
1813 auto callback = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1814 napi_value result = nullptr;
1815 NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnNotifyInVisibleForms",
1816 env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
1817 return result;
1818 }
1819 } // namespace AbilityRuntime
1820 } // namespace OHOS
1821