1 
2 /*
3  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "js_form_host.h"
18 
19 #include "fms_log_wrapper.h"
20 #include "form_info.h"
21 #include "form_info_filter.h"
22 #include "form_instance.h"
23 #include "form_instances_filter.h"
24 #include "form_callback_interface.h"
25 #include "form_host_client.h"
26 #include "form_mgr.h"
27 #include "form_mgr_errors.h"
28 #include "ipc_skeleton.h"
29 #include "js_runtime.h"
30 #include "js_runtime_utils.h"
31 #include "napi_common_data.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 #include "tokenid_kit.h"
39 
40 namespace OHOS {
41 namespace AbilityRuntime {
42 using namespace OHOS;
43 using namespace OHOS::AAFwk;
44 using namespace OHOS::AppExecFwk;
45 
46 namespace {
47     constexpr int REF_COUNT = 1;
48     // NANOSECONDS mean 10^9 nano second
49     constexpr int64_t NANOSECONDS = 1000000000;
50     // MICROSECONDS mean 10^6 millias second
51     constexpr int64_t MICROSECONDS = 1000000;
52     constexpr int32_t INVALID_FORM_LOCATION = -2;
53     constexpr int32_t INVALID_FORM_RESULT_ERRCODE = -2;
54 }
55 
SystemTimeMillis()56 int64_t SystemTimeMillis() noexcept
57 {
58     struct timespec t;
59     t.tv_sec = 0;
60     t.tv_nsec = 0;
61     clock_gettime(CLOCK_MONOTONIC, &t);
62     return static_cast<int64_t>(((t.tv_sec) * NANOSECONDS + t.tv_nsec) / MICROSECONDS);
63 }
64 
65 class ShareFormCallBackClient : public ShareFormCallBack,
66                                 public std::enable_shared_from_this<ShareFormCallBackClient> {
67 public:
68     using ShareFormTask = std::function<void(int32_t)>;
ShareFormCallBackClient(ShareFormTask && task)69     explicit ShareFormCallBackClient(ShareFormTask &&task) : task_(std::move(task))
70     {
71         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
72     }
73 
74     virtual ~ShareFormCallBackClient() = default;
75 
ProcessShareFormResponse(int32_t result)76     void ProcessShareFormResponse(int32_t result) override
77     {
78         if (handler_) {
79             handler_->PostSyncTask([client = shared_from_this(), result] () {
80                 client->task_(result);
81             });
82         }
83     }
84 
85 private:
86     ShareFormTask task_;
87     std::shared_ptr<AppExecFwk::EventHandler> handler_;
88 };
89 
90 class FormUninstallCallbackClient : public std::enable_shared_from_this<FormUninstallCallbackClient> {
91 public:
FormUninstallCallbackClient(napi_env env,napi_ref callbackRef)92     FormUninstallCallbackClient(napi_env env, napi_ref callbackRef) : callbackRef_(callbackRef), env_(env)
93     {
94         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
95     }
96 
~FormUninstallCallbackClient()97     virtual ~FormUninstallCallbackClient()
98     {
99         napi_delete_reference(env_, callbackRef_);
100     }
101 
ProcessFormUninstall(const int64_t formId)102     void ProcessFormUninstall(const int64_t formId)
103     {
104         if (handler_ == nullptr) {
105             HILOG_INFO("null handler");
106             return;
107         }
108         handler_->PostSyncTask([thisWeakPtr = weak_from_this(), formId]() {
109             auto sharedThis = thisWeakPtr.lock();
110             if (sharedThis == nullptr) {
111                 HILOG_ERROR("null sharedThis");
112                 return;
113             }
114             HILOG_DEBUG("task complete formId:%{public}" PRId64 ".", formId);
115             std::string formIdString = std::to_string(formId);
116             napi_value callbackValues;
117             napi_create_string_utf8(sharedThis->env_, formIdString.c_str(), NAPI_AUTO_LENGTH, &callbackValues);
118             napi_value callResult;
119             napi_value myCallback = nullptr;
120             napi_get_reference_value(sharedThis->env_, sharedThis->callbackRef_, &myCallback);
121             if (myCallback != nullptr) {
122                 napi_call_function(sharedThis->env_, nullptr, myCallback, ARGS_ONE, &callbackValues, &callResult);
123             }
124         });
125     }
126 
IsStrictEqual(napi_value callback)127     bool IsStrictEqual(napi_value callback)
128     {
129         bool isEqual = false;
130         napi_value myCallback = nullptr;
131         napi_get_reference_value(env_, callbackRef_, &myCallback);
132         napi_strict_equals(env_, myCallback, callback, &isEqual);
133         HILOG_INFO("isStrictEqual = %{public}d", isEqual);
134         return isEqual;
135     }
136 
137 private:
138     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
139     napi_ref callbackRef_ {};
140     napi_env env_;
141 };
142 
143 class JsFormStateCallbackClient : public FormStateCallbackInterface,
144                                   public std::enable_shared_from_this<JsFormStateCallbackClient> {
145 public:
146     using AcquireFormStateTask = std::function<void(int32_t, Want)>;
JsFormStateCallbackClient(AcquireFormStateTask && task)147     explicit JsFormStateCallbackClient(AcquireFormStateTask &&task) : task_(std::move(task))
148     {
149         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
150     }
151 
152     virtual ~JsFormStateCallbackClient() = default;
153 
ProcessAcquireState(FormState state)154     void ProcessAcquireState(FormState state) override
155     {
156         if (handler_) {
157             handler_->PostSyncTask([client = shared_from_this(), state] () {
158                 client->task_(static_cast<int32_t>(state), client->want_);
159             });
160         }
161     }
162 
SetWant(const Want want)163     void SetWant(const Want want)
164     {
165         want_ = want;
166     }
167 private:
168     Want want_;
169     AcquireFormStateTask task_;
170     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
171 };
172 
173 class JsFormDataCallbackClient : public FormDataCallbackInterface,
174                                  public std::enable_shared_from_this<JsFormDataCallbackClient> {
175 public:
176     using AcquireFormDataTask = std::function<void(AAFwk::WantParams data)>;
JsFormDataCallbackClient(AcquireFormDataTask && task)177     explicit JsFormDataCallbackClient(AcquireFormDataTask &&task) : task_(std::move(task))
178     {
179         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
180     }
181 
182     virtual ~JsFormDataCallbackClient() = default;
183 
ProcessAcquireFormData(AAFwk::WantParams data)184     void ProcessAcquireFormData(AAFwk::WantParams data) override
185     {
186         if (handler_) {
187             handler_->PostSyncTask([client = shared_from_this(), data] () {
188                 client->task_(data);
189             });
190         }
191     }
192 private:
193     AcquireFormDataTask task_;
194     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
195 };
196 
197 std::map<napi_ref, std::shared_ptr<FormUninstallCallbackClient>> g_formUninstallCallbackMap {};
198 std::mutex g_formUninstallCallbackMapMutex_;
199 
FormUninstallCallback(const std::vector<int64_t> & formIds)200 void FormUninstallCallback(const std::vector<int64_t> &formIds)
201 {
202     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
203     for (auto &iter : g_formUninstallCallbackMap) {
204         for (int64_t formId : formIds) {
205             iter.second->ProcessFormUninstall(formId);
206         }
207     }
208 }
209 
AddFormUninstallCallback(napi_env env,napi_value callback)210 bool AddFormUninstallCallback(napi_env env, napi_value callback)
211 {
212     HILOG_DEBUG("start");
213     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
214     for (auto &iter : g_formUninstallCallbackMap) {
215         if (iter.second->IsStrictEqual(callback)) {
216             HILOG_ERROR("found equal callback");
217             return false;
218         }
219     }
220 
221     napi_ref callbackRef;
222     napi_create_reference(env, callback, REF_COUNT, &callbackRef);
223     std::shared_ptr<FormUninstallCallbackClient> callbackClient = std::make_shared<FormUninstallCallbackClient>(env,
224         callbackRef);
225 
226     auto ret = g_formUninstallCallbackMap.emplace(callbackRef, callbackClient);
227     if (!ret.second) {
228         HILOG_ERROR("fail emplace callback");
229         return false;
230     }
231     return true;
232 }
233 
DelFormUninstallCallback(napi_value callback)234 bool DelFormUninstallCallback(napi_value callback)
235 {
236     HILOG_DEBUG("start");
237     int32_t count = 0;
238     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
239     for (auto iter = g_formUninstallCallbackMap.begin(); iter != g_formUninstallCallbackMap.end();) {
240         if (iter->second->IsStrictEqual(callback)) {
241             HILOG_INFO("found equal callback");
242             iter = g_formUninstallCallbackMap.erase(iter);
243             count++;
244         } else {
245             iter++;
246         }
247     }
248     HILOG_INFO("%{public}d form uninstall callback canceled.", count);
249     return true;
250 }
251 
ClearFormUninstallCallback()252 bool ClearFormUninstallCallback()
253 {
254     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
255     g_formUninstallCallbackMap.clear();
256     return true;
257 }
258 
259 class JsFormHost {
260 public:
261     JsFormHost() = default;
262     ~JsFormHost() = default;
263 
Finalizer(napi_env env,void * data,void * hint)264     static void Finalizer(napi_env env, void* data, void* hint)
265     {
266         HILOG_INFO("call");
267         std::unique_ptr<JsFormHost>(static_cast<JsFormHost*>(data));
268     }
269 
AddForm(napi_env env,napi_callback_info info)270     static napi_value AddForm(napi_env env, napi_callback_info info)
271     {
272         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnAddForm);
273     }
274 
DeleteForm(napi_env env,napi_callback_info info)275     static napi_value DeleteForm(napi_env env, napi_callback_info info)
276     {
277         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnDeleteForm);
278     }
279 
ReleaseForm(napi_env env,napi_callback_info info)280     static napi_value ReleaseForm(napi_env env, napi_callback_info info)
281     {
282         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnReleaseForm);
283     }
284 
RequestForm(napi_env env,napi_callback_info info)285     static napi_value RequestForm(napi_env env, napi_callback_info info)
286     {
287         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRequestForm);
288     }
289 
RequestFormWithParams(napi_env env,napi_callback_info info)290     static napi_value RequestFormWithParams(napi_env env, napi_callback_info info)
291     {
292         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRequestFormWithParams);
293     }
294 
CastTempForm(napi_env env,napi_callback_info info)295     static napi_value CastTempForm(napi_env env, napi_callback_info info)
296     {
297         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnCastTempForm);
298     }
299 
NotifyVisibleForms(napi_env env,napi_callback_info info)300     static napi_value NotifyVisibleForms(napi_env env, napi_callback_info info)
301     {
302         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyVisibleForms);
303     }
304 
NotifyInvisibleForms(napi_env env,napi_callback_info info)305     static napi_value NotifyInvisibleForms(napi_env env, napi_callback_info info)
306     {
307         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyInvisibleForms);
308     }
309 
EnableFormsUpdate(napi_env env,napi_callback_info info)310     static napi_value EnableFormsUpdate(napi_env env, napi_callback_info info)
311     {
312         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnEnableFormsUpdate);
313     }
314 
DisableFormsUpdate(napi_env env,napi_callback_info info)315     static napi_value DisableFormsUpdate(napi_env env, napi_callback_info info)
316     {
317         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnDisableFormsUpdate);
318     }
319 
IsSystemReady(napi_env env,napi_callback_info info)320     static napi_value IsSystemReady(napi_env env, napi_callback_info info)
321     {
322         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnIsSystemReady);
323     }
324 
DeleteInvalidForms(napi_env env,napi_callback_info info)325     static napi_value DeleteInvalidForms(napi_env env, napi_callback_info info)
326     {
327         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnDeleteInvalidForms);
328     }
329 
AcquireFormState(napi_env env,napi_callback_info info)330     static napi_value AcquireFormState(napi_env env, napi_callback_info info)
331     {
332         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnAcquireFormState);
333     }
334 
RegisterFormObserver(napi_env env,napi_callback_info info)335     static napi_value RegisterFormObserver(napi_env env, napi_callback_info info)
336     {
337         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRegisterFormObserver);
338     }
339 
UnregisterFormObserver(napi_env env,napi_callback_info info)340     static napi_value UnregisterFormObserver(napi_env env, napi_callback_info info)
341     {
342         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnUnregisterFormObserver);
343     }
344 
NotifyFormsVisible(napi_env env,napi_callback_info info)345     static napi_value NotifyFormsVisible(napi_env env, napi_callback_info info)
346     {
347         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyFormsVisible);
348     }
349 
NotifyFormsEnableUpdate(napi_env env,napi_callback_info info)350     static napi_value NotifyFormsEnableUpdate(napi_env env, napi_callback_info info)
351     {
352         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyFormsEnableUpdate);
353     }
354 
GetAllFormsInfo(napi_env env,napi_callback_info info)355     static napi_value GetAllFormsInfo(napi_env env, napi_callback_info info)
356     {
357         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnGetAllFormsInfo);
358     }
359 
GetFormsInfo(napi_env env,napi_callback_info info)360     static napi_value GetFormsInfo(napi_env env, napi_callback_info info)
361     {
362         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnGetFormsInfo);
363     }
364 
ShareForm(napi_env env,napi_callback_info info)365     static napi_value ShareForm(napi_env env, napi_callback_info info)
366     {
367         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnShareForm);
368     }
369 
AcquireFormData(napi_env env,napi_callback_info info)370     static napi_value AcquireFormData(napi_env env, napi_callback_info info)
371     {
372         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnAcquireFormData);
373     }
374 
SetRouterProxy(napi_env env,napi_callback_info info)375     static napi_value SetRouterProxy(napi_env env, napi_callback_info info)
376     {
377         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnSetRouterProxy);
378     }
379 
ClearRouterProxy(napi_env env,napi_callback_info info)380     static napi_value ClearRouterProxy(napi_env env, napi_callback_info info)
381     {
382         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnClearRouterProxy);
383     }
384 
NotifyFormsPrivacyProtected(napi_env env,napi_callback_info info)385     static napi_value NotifyFormsPrivacyProtected(napi_env env, napi_callback_info info)
386     {
387         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyFormsPrivacyProtected);
388     }
389 
SetFormsRecyclable(napi_env env,napi_callback_info info)390     static napi_value SetFormsRecyclable(napi_env env, napi_callback_info info)
391     {
392         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnSetFormsRecyclable);
393     }
394 
RecoverForms(napi_env env,napi_callback_info info)395     static napi_value RecoverForms(napi_env env, napi_callback_info info)
396     {
397         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRecoverForms);
398     }
399 
RecycleForms(napi_env env,napi_callback_info info)400     static napi_value RecycleForms(napi_env env, napi_callback_info info)
401     {
402         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRecycleForms);
403     }
404 
UpdateFormLocation(napi_env env,napi_callback_info info)405     static napi_value UpdateFormLocation(napi_env env, napi_callback_info info)
406     {
407         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnUpdateFormLocation);
408     }
409 
SetPublishFormResult(napi_env env,napi_callback_info info)410     static napi_value SetPublishFormResult(napi_env env, napi_callback_info info)
411     {
412         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnSetPublishFormResult);
413     }
414 
415 private:
CheckCallerIsSystemApp()416     bool CheckCallerIsSystemApp()
417     {
418         auto selfToken = IPCSkeleton::GetSelfTokenID();
419         return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken);
420     }
421 
ConvertFromId(napi_env env,napi_value jsValue,int64_t & formId)422     static bool ConvertFromId(napi_env env, napi_value jsValue, int64_t &formId)
423     {
424         std::string strFormId;
425         if (!ConvertFromJsValue(env, jsValue, strFormId)) {
426             HILOG_ERROR("convert strFormId failed");
427             return false;
428         }
429 
430         if (strFormId.empty()) {
431             HILOG_ERROR("empty strFormId");
432             return false;
433         }
434 
435         if (!ConvertStringToInt64(strFormId, formId)) {
436             HILOG_ERROR("convert string formId to int64 failed");
437             return false;
438         }
439         return true;
440     }
441 
GetStringsValue(napi_env env,napi_value array,std::vector<std::string> & strList)442     bool GetStringsValue(napi_env env, napi_value array, std::vector<std::string> &strList)
443     {
444         napi_valuetype paramType = napi_undefined;
445         napi_typeof(env, array, &paramType);
446         if (paramType == napi_undefined || paramType == napi_null) {
447             HILOG_ERROR("input array is napi_undefined or napi_null");
448             return false;
449         }
450         uint32_t nativeArrayLen = 0;
451         napi_get_array_length(env, array, &nativeArrayLen);
452         napi_value element = nullptr;
453 
454         for (uint32_t i = 0; i < nativeArrayLen; i++) {
455             std::string itemStr("");
456             napi_get_element(env, array, i, &element);
457             if (!ConvertFromJsValue(env, element, itemStr)) {
458                 HILOG_ERROR("GetElement from to array [%{public}u] error", i);
459                 return false;
460             }
461             strList.push_back(itemStr);
462         }
463 
464         return true;
465     }
466 
ConvertFromIds(napi_env env,napi_value jsValue,std::vector<int64_t> & formIds)467     bool ConvertFromIds(napi_env env, napi_value jsValue, std::vector<int64_t> &formIds)
468     {
469         std::vector<string> strFormIdList;
470         if (!GetStringsValue(env, jsValue, strFormIdList)) {
471             HILOG_ERROR("convert strFormIdList failed");
472             return false;
473         }
474 
475         for (size_t i = 0; i < strFormIdList.size(); i++) {
476             int64_t formIdValue;
477             if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
478                 HILOG_ERROR("convert formIdValue failed");
479                 return false;
480             }
481             formIds.push_back(formIdValue);
482         }
483         return true;
484     }
485 
ConvertDeviceId(napi_env env,napi_value jsValue,std::string & deviceId)486     bool ConvertDeviceId(napi_env env, napi_value jsValue, std::string &deviceId)
487     {
488         if (!ConvertFromJsValue(env, jsValue, deviceId)) {
489             HILOG_ERROR("convert deviceId failed");
490             return false;
491         }
492 
493         if (deviceId.empty()) {
494             HILOG_ERROR("empty deviceId");
495             return false;
496         }
497 
498         return true;
499     }
500 
ParseParameter(napi_env env,napi_value * argv,int32_t & formErrorCode,std::string & messageInfo)501     bool ParseParameter(napi_env env, napi_value *argv, int32_t &formErrorCode, std::string &messageInfo)
502     {
503         napi_valuetype param1Type = napi_undefined;
504         napi_typeof(env, argv[1], &param1Type);
505         if (param1Type != napi_object) {
506             HILOG_ERROR("result not napi_object");
507             return false;
508         }
509         napi_value publishFormErrorCode = nullptr;
510         napi_status codeRet = napi_get_named_property(env, argv[1], "code", &publishFormErrorCode);
511         napi_value message = nullptr;
512         napi_status messageRet = napi_get_named_property(env, argv[1], "message", &message);
513         if (codeRet != napi_ok || messageRet != napi_ok) {
514             HILOG_ERROR("get property failed");
515             return false;
516         }
517         messageInfo = GetStringFromNapi(env, message);
518         if (napi_get_value_int32(env, publishFormErrorCode, &formErrorCode) != napi_ok) {
519             HILOG_ERROR("PublishFormErrorCode not number");
520             return false;
521         }
522         if (formErrorCode < static_cast<int32_t>(Constants::PublishFormErrorCode::SUCCESS) ||
523                 formErrorCode > static_cast<int32_t>(Constants::PublishFormErrorCode::INTERNAL_ERROR)) {
524             HILOG_ERROR("PublishFormResult is convert fail");
525             return false;
526         }
527         return true;
528     }
529 
OnAddForm(napi_env env,size_t argc,napi_value * argv)530     napi_value OnAddForm(napi_env env, size_t argc, napi_value* argv)
531     {
532         HILOG_INFO("call");
533 
534         if (argc != ARGS_ONE) {
535             HILOG_ERROR("invalid argc");
536             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
537             return CreateJsUndefined(env);
538         }
539 
540         Want want;
541         if (!UnwrapWant(env, argv[PARAM0], want)) {
542             HILOG_ERROR("UnwrapWant failed");
543             NapiFormUtil::ThrowParamTypeError(env, "want", "Want");
544             return CreateJsUndefined(env);
545         }
546 
547         std::shared_ptr<AppExecFwk::RunningFormInfo> runningFormInfo =
548             std::make_shared<AppExecFwk::RunningFormInfo>();
549         auto apiResult = std::make_shared<int32_t>();
550         NapiAsyncTask::ExecuteCallback execute = [want, runningFormInfo, ret = apiResult]() {
551             *ret = FormMgr::GetInstance().CreateForm(want, *runningFormInfo);
552         };
553 
554         NapiAsyncTask::CompleteCallback complete = [runningFormInfo, ret = apiResult](napi_env env,
555             NapiAsyncTask &task, int32_t status) {
556             HILOG_INFO("ret:%{public}d,formId:%{public}" PRId64, *ret, runningFormInfo->formId);
557             if (*ret == ERR_OK) {
558                 task.ResolveWithNoError(env, CreateRunningFormInfo(env, *runningFormInfo));
559             } else {
560                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
561             }
562         };
563 
564         napi_value result = nullptr;
565         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnAddForm",
566             env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
567         return result;
568     }
569 
OnDeleteForm(napi_env env,size_t argc,napi_value * argv)570     napi_value OnDeleteForm(napi_env env, size_t argc, napi_value* argv)
571     {
572         HILOG_DEBUG("call");
573         if (argc > ARGS_TWO || argc < ARGS_ONE) {
574             HILOG_ERROR("OnDeleteForm invalid argc");
575             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
576             return CreateJsUndefined(env);
577         }
578 
579         decltype(argc) convertArgc = 0;
580         int64_t formId = 0;
581         if (!ConvertFromId(env, argv[PARAM0], formId)) {
582             HILOG_ERROR("invalid formId");
583             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
584             return CreateJsUndefined(env);
585         }
586         convertArgc++;
587 
588         auto apiResult = std::make_shared<int32_t>();
589         NapiAsyncTask::ExecuteCallback execute = [formId, ret = apiResult]() {
590             *ret = FormMgr::GetInstance().DeleteForm(formId, FormHostClient::GetInstance());
591         };
592 
593         NapiAsyncTask::CompleteCallback complete = [formId, ret = apiResult](napi_env env,
594             NapiAsyncTask &task, int32_t status) {
595             HILOG_INFO("deleteForm ret:%{public}d,formId:%{public}" PRId64, *ret, formId);
596             if (*ret == ERR_OK) {
597                 task.ResolveWithNoError(env, CreateJsUndefined(env));
598             } else {
599                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
600             }
601         };
602 
603         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
604         napi_value result = nullptr;
605         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnDeleteForm",
606             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
607         return result;
608     }
609 
OnReleaseForm(napi_env env,size_t argc,napi_value * argv)610     napi_value OnReleaseForm(napi_env env, size_t argc, napi_value* argv)
611     {
612         HILOG_DEBUG("call");
613 
614         if (argc > ARGS_THREE || argc < ARGS_ONE) {
615             HILOG_ERROR("OnReleaseForm invalid argc");
616             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2 or 3");
617             return CreateJsUndefined(env);
618         }
619 
620         decltype(argc) convertArgc = 0;
621         int64_t formId = 0;
622         if (!ConvertFromId(env, argv[PARAM0], formId)) {
623             HILOG_ERROR("invalid formId");
624             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
625             return CreateJsUndefined(env);
626         }
627         convertArgc++;
628 
629         bool isReleaseCache = false;
630         if ((argc == ARGS_TWO || argc == ARGS_THREE) && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
631             if (!ConvertFromJsValue(env, argv[PARAM1], isReleaseCache)) {
632                 HILOG_ERROR("convert isReleaseCache failed");
633                 NapiFormUtil::ThrowParamTypeError(env, "isReleaseCache", "boolean");
634                 return CreateJsUndefined(env);
635             }
636             convertArgc++;
637         }
638 
639         NapiAsyncTask::CompleteCallback complete = [formId, isReleaseCache]
640             (napi_env env, NapiAsyncTask &task, int32_t status) {
641             auto ret = FormMgr::GetInstance().ReleaseForm(formId, FormHostClient::GetInstance(), isReleaseCache);
642             if (ret == ERR_OK) {
643                 task.ResolveWithNoError(env, CreateJsUndefined(env));
644             } else {
645                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
646             }
647         };
648 
649         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
650         napi_value result = nullptr;
651         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnReleaseForm",
652             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
653         return result;
654     }
655 
OnRequestForm(napi_env env,size_t argc,napi_value * argv)656     napi_value OnRequestForm(napi_env env, size_t argc, napi_value* argv)
657     {
658         HILOG_DEBUG("call");
659 
660         if (argc > ARGS_TWO || argc < ARGS_ONE) {
661             HILOG_ERROR("invalid argc");
662             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
663             return CreateJsUndefined(env);
664         }
665 
666         decltype(argc) convertArgc = 0;
667         int64_t formId = 0;
668         if (!ConvertFromId(env, argv[PARAM0], formId)) {
669             HILOG_ERROR("invalid formId");
670             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
671             return CreateJsUndefined(env);
672         }
673         convertArgc++;
674 
675         NapiAsyncTask::CompleteCallback complete = [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
676             Want want;
677             auto ret = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
678             if (ret == ERR_OK) {
679                 task.ResolveWithNoError(env, CreateJsUndefined(env));
680             } else {
681                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
682             }
683         };
684 
685         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
686         napi_value result = nullptr;
687         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRequestForm",
688             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
689         return result;
690     }
691 
OnRequestFormWithParams(napi_env env,size_t argc,napi_value * argv)692     napi_value OnRequestFormWithParams(napi_env env, size_t argc, napi_value* argv)
693     {
694         HILOG_DEBUG("call");
695 
696         if (argc > ARGS_TWO || argc < ARGS_ONE) {
697             HILOG_ERROR("invalid argc");
698             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
699             return CreateJsUndefined(env);
700         }
701 
702         decltype(argc) convertArgc = 0;
703         int64_t formId = 0;
704         if (!ConvertFromId(env, argv[PARAM0], formId)) {
705             HILOG_ERROR("invalid formId");
706             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
707             return CreateJsUndefined(env);
708         }
709         convertArgc++;
710 
711         if (argc == ARGS_TWO && !IsTypeForNapiValue(env, argv[PARAM1], napi_object)) {
712             HILOG_ERROR("invalid secondInputParam");
713             NapiFormUtil::ThrowParamTypeError(env, "wantParams", "object");
714             return CreateJsUndefined(env);
715         }
716 
717         Want want;
718         AAFwk::WantParams wantParams;
719         if (UnwrapWantParams(env, argv[PARAM1], wantParams)) {
720             want.SetParams(wantParams);
721         }
722         convertArgc++;
723 
724         NapiAsyncTask::CompleteCallback complete = [formId, want](napi_env env, NapiAsyncTask &task, int32_t status) {
725             auto ret = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
726             if (ret == ERR_OK) {
727                 task.ResolveWithNoError(env, CreateJsUndefined(env));
728             } else {
729                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
730             }
731         };
732 
733         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
734         napi_value result = nullptr;
735         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRequestFormWithParams",
736             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
737         return result;
738     }
739 
OnCastTempForm(napi_env env,size_t argc,napi_value * argv)740     napi_value OnCastTempForm(napi_env env, size_t argc, napi_value* argv)
741     {
742         HILOG_DEBUG("call");
743 
744         if (argc > ARGS_TWO || argc < ARGS_ONE) {
745             HILOG_ERROR("invalid argc");
746             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
747             return CreateJsUndefined(env);
748         }
749 
750         decltype(argc) convertArgc = 0;
751         int64_t formId = 0;
752         if (!ConvertFromId(env, argv[PARAM0], formId)) {
753             HILOG_ERROR("invalid formId");
754             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
755             return CreateJsUndefined(env);
756         }
757         convertArgc++;
758 
759         NapiAsyncTask::CompleteCallback complete = [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
760             auto ret = FormMgr::GetInstance().CastTempForm(formId, FormHostClient::GetInstance());
761             if (ret == ERR_OK) {
762                 task.ResolveWithNoError(env, CreateJsUndefined(env));
763             } else {
764                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
765             }
766         };
767 
768         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
769         napi_value result = nullptr;
770         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnCastTempForm",
771             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
772         return result;
773     }
774 
OnNotifyVisibleForms(napi_env env,size_t argc,napi_value * argv)775     napi_value OnNotifyVisibleForms(napi_env env, size_t argc, napi_value* argv)
776     {
777         HILOG_DEBUG("call");
778 
779         if (argc > ARGS_TWO || argc < ARGS_ONE) {
780             HILOG_ERROR("invalid argc");
781             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
782             return CreateJsUndefined(env);
783         }
784 
785         decltype(argc) convertArgc = 0;
786         std::vector<int64_t> formIds;
787         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
788             HILOG_ERROR("invalid formIdList");
789             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
790             return CreateJsUndefined(env);
791         }
792         convertArgc++;
793 
794         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
795             auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds, FormHostClient::GetInstance(),
796                 Constants::FORM_VISIBLE);
797             if (ret == ERR_OK) {
798                 task.ResolveWithNoError(env, CreateJsUndefined(env));
799             } else {
800                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
801             }
802         };
803 
804         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
805         napi_value result = nullptr;
806         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
807             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
808         return result;
809         HILOG_DEBUG("OnNotifyVisibleForms end");
810     }
811 
OnNotifyInvisibleForms(napi_env env,size_t argc,napi_value * argv)812     napi_value OnNotifyInvisibleForms(napi_env env, size_t argc, napi_value* argv)
813     {
814         HILOG_DEBUG("call");
815 
816         if (argc > ARGS_TWO || argc < ARGS_ONE) {
817             HILOG_ERROR("invalid argc");
818             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
819             return CreateJsUndefined(env);
820         }
821 
822         decltype(argc) convertArgc = 0;
823         std::vector<int64_t> formIds;
824         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
825             HILOG_ERROR("invalid formIdList");
826             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
827             return CreateJsUndefined(env);
828         }
829         convertArgc++;
830 
831         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
832             auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds, FormHostClient::GetInstance(),
833                 Constants::FORM_INVISIBLE);
834             if (ret == ERR_OK) {
835                 task.ResolveWithNoError(env, CreateJsUndefined(env));
836             } else {
837                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
838             }
839         };
840 
841         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
842         napi_value result = nullptr;
843         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
844             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
845         return result;
846         HILOG_DEBUG("OnNotifyInvisibleForms end");
847     }
848 
OnEnableFormsUpdate(napi_env env,size_t argc,napi_value * argv)849     napi_value OnEnableFormsUpdate(napi_env env, size_t argc, napi_value* argv)
850     {
851         HILOG_DEBUG("call");
852 
853         if (argc > ARGS_TWO || argc < ARGS_ONE) {
854             HILOG_ERROR("invalid argc");
855             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
856             return CreateJsUndefined(env);
857         }
858 
859         decltype(argc) convertArgc = 0;
860         std::vector<int64_t> formIds;
861         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
862             HILOG_ERROR("invalid formIdList");
863             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
864             return CreateJsUndefined(env);
865         }
866         convertArgc++;
867 
868         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
869             auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), true);
870             if (ret == ERR_OK) {
871                 task.ResolveWithNoError(env, CreateJsUndefined(env));
872             } else {
873                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
874             }
875         };
876 
877         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
878         napi_value result = nullptr;
879         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
880             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
881         return result;
882         HILOG_DEBUG("OnEnableFormsUpdate end");
883     }
884 
OnDisableFormsUpdate(napi_env env,size_t argc,napi_value * argv)885     napi_value OnDisableFormsUpdate(napi_env env, size_t argc, napi_value* argv)
886     {
887         HILOG_DEBUG("call");
888 
889         if (argc > ARGS_TWO || argc < ARGS_ONE) {
890             HILOG_ERROR("invalid argc");
891             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
892             return CreateJsUndefined(env);
893         }
894 
895         decltype(argc) convertArgc = 0;
896         std::vector<int64_t> iFormIds;
897         if (!ConvertFromIds(env, argv[PARAM0], iFormIds)) {
898             HILOG_ERROR("invalid formIdList");
899             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
900             return CreateJsUndefined(env);
901         }
902         convertArgc++;
903 
904         auto complete = [formIds = iFormIds](napi_env env, NapiAsyncTask &task, int32_t status) {
905             auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), false);
906             if (ret != ERR_OK) {
907                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
908                 return;
909             }
910             task.ResolveWithNoError(env, CreateJsUndefined(env));
911         };
912 
913         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
914         napi_value result = nullptr;
915         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnDisableFormsUpdate",
916             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
917         return result;
918     }
919 
OnIsSystemReady(napi_env env,size_t argc,napi_value * argv)920     napi_value OnIsSystemReady(napi_env env, size_t argc, napi_value* argv)
921     {
922         HILOG_DEBUG("call");
923 
924         if (!CheckCallerIsSystemApp()) {
925             HILOG_ERROR("the app not system-app,can't use system-api");
926             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
927             return CreateJsUndefined(env);
928         }
929 
930         if (argc > ARGS_ONE || argc < ARGS_ZERO) {
931             HILOG_ERROR("invalid argc");
932             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "0 or 1");
933             return CreateJsUndefined(env);
934         }
935 
936         auto complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
937             // Use original logic.
938             // Use the error code to return whether the function executed successfully.
939             auto ret = FormMgr::GetInstance().CheckFMSReady() ? 0 : 1;
940             if (ret == ERR_OK) {
941                 task.ResolveWithNoError(env, CreateJsUndefined(env));
942             } else {
943                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
944             }
945         };
946 
947         auto callback = (argc == ARGS_ZERO) ? nullptr : argv[PARAM0];
948         napi_value result = nullptr;
949         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnIsSystemReady",
950             env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
951         return result;
952     }
953 
OnDeleteInvalidForms(napi_env env,size_t argc,napi_value * argv)954     napi_value OnDeleteInvalidForms(napi_env env, size_t argc, napi_value* argv)
955     {
956         HILOG_DEBUG("call");
957 
958         if (argc > ARGS_TWO || argc < ARGS_ONE) {
959             HILOG_ERROR("invalid argc");
960             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
961             return CreateJsUndefined(env);
962         }
963 
964         decltype(argc) convertArgc = 0;
965         std::vector<int64_t> formIds;
966         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
967             HILOG_ERROR("invalid formIdList");
968             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
969             return CreateJsUndefined(env);
970         }
971         convertArgc++;
972 
973         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
974             int32_t num;
975             auto ret = FormMgr::GetInstance().DeleteInvalidForms(formIds, FormHostClient::GetInstance(), num);
976             if (ret == ERR_OK) {
977                 task.ResolveWithNoError(env, CreateJsValue(env, num));
978             } else {
979                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
980             }
981         };
982 
983         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
984         napi_value result = nullptr;
985         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
986             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
987         return result;
988     }
989 
InnerAcquireFormState(napi_env env,const std::shared_ptr<NapiAsyncTask> & asyncTask,JsFormStateCallbackClient::AcquireFormStateTask && task,const Want & want)990     void InnerAcquireFormState(
991         napi_env env,
992         const std::shared_ptr<NapiAsyncTask> &asyncTask,
993         JsFormStateCallbackClient::AcquireFormStateTask &&task,
994         const Want &want)
995     {
996         auto formStateCallback = std::make_shared<JsFormStateCallbackClient>(std::move(task));
997         FormHostClient::GetInstance()->AddFormState(formStateCallback, want);
998         FormStateInfo stateInfo;
999         auto result = FormMgr::GetInstance().AcquireFormState(want, FormHostClient::GetInstance(), stateInfo);
1000         formStateCallback->SetWant(stateInfo.want);
1001         if (result != ERR_OK) {
1002             HILOG_DEBUG("AcquireFormState failed");
1003             asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, result));
1004             FormHostClient::GetInstance()->RemoveFormState(want);
1005         }
1006     }
1007 
OnAcquireFormState(napi_env env,size_t argc,napi_value * argv)1008     napi_value OnAcquireFormState(napi_env env, size_t argc, napi_value* argv)
1009     {
1010         HILOG_DEBUG("call");
1011         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1012             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1013             return CreateJsUndefined(env);
1014         }
1015 
1016         Want want;
1017         napi_value argWant = argv[PARAM0];
1018         if (!UnwrapWant(env, argWant, want)) {
1019             HILOG_ERROR("invalid want");
1020             NapiFormUtil::ThrowParamTypeError(env, "want", "Want");
1021             return CreateJsUndefined(env);
1022         }
1023 
1024         napi_value lastParam = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1025         napi_value result = nullptr;
1026 
1027         std::unique_ptr<AbilityRuntime::NapiAsyncTask> uasyncTask =
1028             AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
1029         std::shared_ptr<AbilityRuntime::NapiAsyncTask> asyncTask = std::move(uasyncTask);
1030 
1031         JsFormStateCallbackClient::AcquireFormStateTask task = [env, asyncTask](int32_t state, Want want) {
1032             HILOG_DEBUG("task complete state:%{public}d", state);
1033             napi_value objValue = nullptr;
1034             napi_create_object(env, &objValue);
1035             napi_set_named_property(env, objValue, "want", CreateJsWant(env, want));
1036             napi_set_named_property(env, objValue, "formState", CreateJsValue(env, state));
1037             asyncTask->ResolveWithNoError(env, objValue);
1038         };
1039 
1040         InnerAcquireFormState(env, asyncTask, std::move(task), want);
1041         return result;
1042     }
1043 
OnSetRouterProxy(napi_env env,size_t argc,napi_value * argv)1044     napi_value OnSetRouterProxy(napi_env env, size_t argc, napi_value* argv)
1045     {
1046         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1047             HILOG_ERROR("invalid argc");
1048             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1049             return CreateJsUndefined(env);
1050         }
1051         decltype(argc) convertArgc = 0;
1052 
1053         // Check the type of the PARAM0.
1054         std::vector<int64_t> formIds;
1055         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1056             HILOG_ERROR("invalid formIdList");
1057             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1058             return CreateJsUndefined(env);
1059         }
1060         convertArgc++;
1061 
1062         // Check the type of the PARAM1.
1063         if (!IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1064             HILOG_ERROR("invalid Param2");
1065             NapiFormUtil::ThrowParamTypeError(env, "callback", "Callback<Want>");
1066             return CreateJsUndefined(env);
1067         }
1068         convertArgc++;
1069 
1070         auto apiResult = std::make_shared<int32_t>();
1071         JsFormRouterProxyMgr::GetInstance()->AddFormRouterProxyCallback(env, argv[PARAM1], formIds);
1072         auto execute = [formIds, ret = apiResult]() {
1073             *ret = FormMgr::GetInstance().RegisterFormRouterProxy(formIds, JsFormRouterProxyMgr::GetInstance());
1074         };
1075 
1076         NapiAsyncTask::CompleteCallback complete =
1077             [ret = apiResult](napi_env env, NapiAsyncTask &task, int32_t status) {
1078                 if (*ret == ERR_OK) {
1079                     task.ResolveWithNoError(env, CreateJsUndefined(env));
1080                 } else {
1081                     task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
1082                 }
1083             };
1084 
1085         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1086         napi_value result = nullptr;
1087         NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnSetRouterProxy",
1088             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1089         return result;
1090     }
1091 
OnClearRouterProxy(napi_env env,size_t argc,napi_value * argv)1092     napi_value OnClearRouterProxy(napi_env env, size_t argc, napi_value* argv)
1093     {
1094         // Check the number of input parameters.
1095         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1096             HILOG_ERROR("invalid argc");
1097             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1098             return CreateJsUndefined(env);
1099         }
1100         decltype(argc) convertArgc = 0;
1101 
1102         // Check the type of the PARAM0.
1103         std::vector<int64_t> formIds;
1104         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1105             HILOG_ERROR("invalid formIdList");
1106             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1107             return CreateJsUndefined(env);
1108         }
1109         convertArgc++;
1110 
1111         auto apiResult = std::make_shared<int32_t>();
1112         JsFormRouterProxyMgr::GetInstance()->RemoveFormRouterProxyCallback(formIds);
1113         auto execute = [formIds, ret = apiResult]() {
1114             *ret = FormMgr::GetInstance().UnregisterFormRouterProxy(formIds);
1115         };
1116 
1117         NapiAsyncTask::CompleteCallback complete =
1118             [ret = apiResult](napi_env env, NapiAsyncTask &task, int32_t status) {
1119                 if (*ret == ERR_OK) {
1120                     task.ResolveWithNoError(env, CreateJsUndefined(env));
1121                 } else {
1122                     task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
1123                 }
1124             };
1125         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1126         napi_value result = nullptr;
1127         NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnClearRouterProxy",
1128             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1129         return result;
1130     }
1131 
OnRegisterFormObserver(napi_env env,size_t argc,napi_value * argv)1132     napi_value OnRegisterFormObserver(napi_env env, size_t argc, napi_value* argv)
1133     {
1134         HILOG_DEBUG("call");
1135         if (!CheckCallerIsSystemApp()) {
1136             HILOG_ERROR("The app not system-app,can't use system-api");
1137             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
1138             return CreateJsUndefined(env);
1139         }
1140 
1141         // Check the number of input parameters.
1142         if (argc != ARGS_TWO) {
1143             HILOG_ERROR("invalid argc");
1144             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2");
1145             return CreateJsUndefined(env);
1146         }
1147 
1148         std::string type;
1149         if (!ConvertFromJsValue(env, argv[PARAM0], type) || type != "formUninstall") {
1150             HILOG_ERROR("args[0] not formUninstall");
1151             NapiFormUtil::ThrowParamTypeError(env, "type", "formUninstall");
1152             return CreateJsUndefined(env);
1153         }
1154 
1155         // Check the type of the PARAM1.
1156         if (!IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1157             HILOG_ERROR("invalid param1");
1158             NapiFormUtil::ThrowParamTypeError(env, "callback", "Callback<string>");
1159             return CreateJsUndefined(env);
1160         }
1161         FormHostClient::GetInstance()->RegisterUninstallCallback(FormUninstallCallback);
1162         AddFormUninstallCallback(env, argv[PARAM1]);
1163         return CreateJsUndefined(env);
1164     }
1165 
OnUnregisterFormObserver(napi_env env,size_t argc,napi_value * argv)1166     napi_value OnUnregisterFormObserver(napi_env env, size_t argc, napi_value* argv)
1167     {
1168         HILOG_DEBUG("call");
1169         if (!CheckCallerIsSystemApp()) {
1170             HILOG_ERROR("the application not system-app,can't use system-api");
1171             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
1172             return CreateJsUndefined(env);
1173         }
1174 
1175         // Check the number of input parameters.
1176         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1177             HILOG_ERROR("invalid argc");
1178             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1179             return CreateJsUndefined(env);
1180         }
1181 
1182         // Check the type of the PARAM0 and convert it to string.
1183         std::string type;
1184         if (!ConvertFromJsValue(env, argv[PARAM0], type) || type != "formUninstall") {
1185             HILOG_ERROR("args[0] not formUninstall");
1186             NapiFormUtil::ThrowParamTypeError(env, "type", "formUninstall");
1187             return CreateJsUndefined(env);
1188         }
1189         // Check the type of the PARAM1.
1190         if (argc == ARGS_TWO && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1191             HILOG_ERROR("invalid param1");
1192             NapiFormUtil::ThrowParamTypeError(env, "callback", "Callback<string>");
1193             return CreateJsUndefined(env);
1194         }
1195 
1196         if (argc == ARGS_TWO) {
1197             DelFormUninstallCallback(argv[PARAM1]);
1198             return CreateJsUndefined(env);
1199         }
1200 
1201         ClearFormUninstallCallback();
1202         return CreateJsUndefined(env);
1203     }
1204 
OnNotifyFormsVisible(napi_env env,size_t argc,napi_value * argv)1205     napi_value OnNotifyFormsVisible(napi_env env, size_t argc, napi_value* argv)
1206     {
1207         HILOG_DEBUG("call");
1208 
1209         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1210             HILOG_ERROR("invalid argc");
1211             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1212             return CreateJsUndefined(env);
1213         }
1214 
1215         decltype(argc) convertArgc = 0;
1216         std::vector<int64_t> formIds;
1217         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1218             HILOG_ERROR("invalid formIdList");
1219             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1220             return CreateJsUndefined(env);
1221         }
1222         convertArgc++;
1223 
1224         bool isVisible = false;
1225         if (!ConvertFromJsValue(env, argv[PARAM1], isVisible)) {
1226             HILOG_ERROR("convert isVisible failed");
1227             NapiFormUtil::ThrowParamTypeError(env, "isVisible", "boolean");
1228             return CreateJsUndefined(env);
1229         }
1230         convertArgc++;
1231 
1232         auto complete = [formIds, isVisible](napi_env env, NapiAsyncTask &task, int32_t status) {
1233             auto ret = FormMgr::GetInstance().NotifyFormsVisible(formIds, isVisible,
1234                 FormHostClient::GetInstance());
1235             if (ret == ERR_OK) {
1236                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1237             } else {
1238                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1239             }
1240         };
1241 
1242         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1243         napi_value result = nullptr;
1244         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnNotifyFormsVisible",
1245             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1246         return result;
1247     }
1248 
OnNotifyFormsEnableUpdate(napi_env env,size_t argc,napi_value * argv)1249     napi_value OnNotifyFormsEnableUpdate(napi_env env, size_t argc, napi_value* argv)
1250     {
1251         HILOG_DEBUG("call");
1252 
1253         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1254             HILOG_ERROR("invalid argc");
1255             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1256             return CreateJsUndefined(env);
1257         }
1258 
1259         decltype(argc) convertArgc = 0;
1260         std::vector<int64_t> formIds;
1261         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1262             HILOG_ERROR("invalid formIdList");
1263             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1264             return CreateJsUndefined(env);
1265         }
1266         convertArgc++;
1267 
1268         bool isEnableUpdate = false;
1269         if (!ConvertFromJsValue(env, argv[PARAM1], isEnableUpdate)) {
1270             HILOG_ERROR("convert isEnableUpdate failed");
1271             NapiFormUtil::ThrowParamTypeError(env, "isEnableUpdate", "boolean");
1272             return CreateJsUndefined(env);
1273         }
1274         convertArgc++;
1275 
1276         auto complete = [formIds, isEnableUpdate](napi_env env, NapiAsyncTask &task, int32_t status) {
1277             auto ret = FormMgr::GetInstance().NotifyFormsEnableUpdate(formIds, isEnableUpdate,
1278                 FormHostClient::GetInstance());
1279             if (ret == ERR_OK) {
1280                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1281             } else {
1282                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1283             }
1284         };
1285 
1286         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1287         napi_value result = nullptr;
1288         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnNotifyFormsVisible",
1289             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1290         return result;
1291     }
1292 
OnGetAllFormsInfo(napi_env env,size_t argc,napi_value * argv)1293     napi_value OnGetAllFormsInfo(napi_env env, size_t argc, napi_value* argv)
1294     {
1295         HILOG_DEBUG("call");
1296         if (argc > ARGS_ONE || argc < ARGS_ZERO) {
1297             HILOG_ERROR("invalid argc");
1298             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "0 or 1");
1299             return CreateJsUndefined(env);
1300         }
1301 
1302         auto errCodeVal = std::make_shared<int32_t>(0);
1303         auto formInfoList = std::make_shared<std::vector<FormInfo>>();
1304         NapiAsyncTask::ExecuteCallback execute = [formInfos = formInfoList, errCode = errCodeVal]() {
1305             if (formInfos == nullptr || errCode == nullptr) {
1306                 HILOG_ERROR("invalid param");
1307                 return;
1308             }
1309             *errCode = FormMgr::GetInstance().GetAllFormsInfo(*formInfos);
1310         };
1311 
1312         NapiAsyncTask::CompleteCallback complete = CreateFormInfosCompleteCallback(errCodeVal, formInfoList);
1313 
1314         auto callback = (argc == ARGS_ZERO) ? nullptr : argv[PARAM0];
1315         napi_value result = nullptr;
1316         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnGetAllFormsInfo",
1317             env, CreateAsyncTaskWithLastParam(env, callback, std::move(execute), std::move(complete), &result));
1318         return result;
1319     }
1320 
GetFormsInfoByFilter(napi_env env,size_t argc,napi_value * argv)1321     napi_value GetFormsInfoByFilter(napi_env env, size_t argc, napi_value* argv)
1322     {
1323         HILOG_DEBUG("call");
1324         if (argc != ARGS_ONE) {
1325             HILOG_ERROR("invalid argc");
1326             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
1327             return CreateJsUndefined(env);
1328         }
1329 
1330         decltype(argc) convertArgc = 0;
1331         AppExecFwk::FormInfoFilter filter;
1332         napi_value jsValue = GetPropertyValueByPropertyName(env, argv[PARAM0], "supportedDimensions", napi_object);
1333         if (jsValue != nullptr) {
1334             std::vector<int32_t> dimensions;
1335             UnwrapArrayInt32FromJS(env, jsValue, dimensions);
1336             for (size_t i = 0; i < dimensions.size(); ++i) {
1337                 if (dimensions[i] < 0) {
1338                     HILOG_ERROR("dimensions value should not be negative");
1339                     NapiFormUtil::ThrowParamError(env, "dimensions value should not be negative");
1340                     return CreateJsUndefined(env);
1341                 }
1342                 filter.supportDimensions.emplace_back(dimensions[i]);
1343             }
1344         }
1345 
1346         napi_value jsShapeValue = GetPropertyValueByPropertyName(env, argv[PARAM0], "supportedShapes", napi_object);
1347         if (jsShapeValue != nullptr && !GetIntVecValue(env, jsShapeValue, filter.supportShapes)) {
1348             HILOG_ERROR("shapes value should not be negative");
1349             NapiFormUtil::ThrowParamError(env, "shapes value should not be negative");
1350             return CreateJsUndefined(env);
1351         }
1352 
1353         UnwrapStringByPropertyName(env, argv[PARAM0], "moduleName", filter.moduleName);
1354         UnwrapStringByPropertyName(env, argv[PARAM0], "bundleName", filter.bundleName);
1355 
1356         convertArgc++;
1357 
1358         auto errCodeVal = std::make_shared<int32_t>(0);
1359         auto formInfoList = std::make_shared<std::vector<FormInfo>>();
1360         NapiAsyncTask::ExecuteCallback execute = [filter, formInfos = formInfoList, errCode = errCodeVal]() {
1361             if (formInfos == nullptr || errCode == nullptr) {
1362                 HILOG_ERROR("invalid param");
1363                 return;
1364             }
1365             *errCode = FormMgr::GetInstance().GetFormsInfoByFilter(filter, *formInfos);
1366         };
1367 
1368         NapiAsyncTask::CompleteCallback complete = CreateFormInfosCompleteCallback(errCodeVal, formInfoList);
1369 
1370         napi_value result = nullptr;
1371         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1372         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnGetFormsInfo",
1373             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1374         return result;
1375     }
1376 
GetIntVecValue(napi_env & env,napi_value & jsValue,std::vector<int32_t> & results)1377     bool GetIntVecValue(napi_env &env, napi_value &jsValue, std::vector<int32_t> &results)
1378     {
1379         std::vector<int32_t> vals;
1380         UnwrapArrayInt32FromJS(env, jsValue, vals);
1381         for (size_t i = 0; i < vals.size(); ++i) {
1382             if (vals[i] < 0) {
1383                 HILOG_ERROR("value should not be negative");
1384                 return false;
1385             }
1386             results.emplace_back(vals[i]);
1387         }
1388         return true;
1389     }
1390 
OnGetFormsInfo(napi_env env,size_t argc,napi_value * argv)1391     napi_value OnGetFormsInfo(napi_env env, size_t argc, napi_value* argv)
1392     {
1393         HILOG_DEBUG("call");
1394         if (argc == ARGS_ONE && IsTypeForNapiValue(env, argv[PARAM0], napi_object)) {
1395             return GetFormsInfoByFilter(env, argc, argv);
1396         }
1397         if (argc > ARGS_THREE || argc < ARGS_ONE) {
1398             HILOG_ERROR("invalid argc");
1399             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2 or 3");
1400             return CreateJsUndefined(env);
1401         }
1402         decltype(argc) convertArgc = 0;
1403         std::string bName("");
1404         if (!ConvertFromJsValue(env, argv[PARAM0], bName)) {
1405             HILOG_ERROR("bundleName convert failed");
1406             NapiFormUtil::ThrowParamTypeError(env, "bundleName", "string");
1407             return CreateJsUndefined(env);
1408         }
1409         convertArgc++;
1410         std::string mName("");
1411         if ((argc == ARGS_TWO || argc == ARGS_THREE) && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1412             if (!ConvertFromJsValue(env, argv[PARAM1], mName)) {
1413                 HILOG_ERROR("moduleName convert failed");
1414                 NapiFormUtil::ThrowParamTypeError(env, "moduleName", "string");
1415                 return CreateJsUndefined(env);
1416             }
1417             convertArgc++;
1418         }
1419 
1420         auto errCodeVal = std::make_shared<int32_t>(0);
1421         auto formInfoList = std::make_shared<std::vector<FormInfo>>();
1422         NapiAsyncTask::ExecuteCallback execute = [bName, mName, convertArgc, formInfos = formInfoList,
1423             errCode = errCodeVal]() {
1424             if (formInfos == nullptr || errCode == nullptr) {
1425                 HILOG_ERROR("invalid param");
1426                 return;
1427             }
1428             std::string bundleName(bName);
1429             std::string moduleName(mName);
1430             if (convertArgc == ARGS_ONE) {
1431                 *errCode = FormMgr::GetInstance().GetFormsInfoByApp(bundleName, *formInfos);
1432             } else {
1433                 *errCode = FormMgr::GetInstance().GetFormsInfoByModule(bundleName, moduleName, *formInfos);
1434             }
1435         };
1436 
1437         NapiAsyncTask::CompleteCallback complete = CreateFormInfosCompleteCallback(errCodeVal, formInfoList);
1438         napi_value result = nullptr;
1439         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1440         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnGetFormsInfo",
1441             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1442         return result;
1443     }
1444 
CreateFormInfosCompleteCallback(std::shared_ptr<int32_t> errCodeVal,std::shared_ptr<std::vector<FormInfo>> formInfoList)1445     NapiAsyncTask::CompleteCallback CreateFormInfosCompleteCallback(std::shared_ptr<int32_t> errCodeVal,
1446         std::shared_ptr<std::vector<FormInfo>> formInfoList)
1447     {
1448         return [errCode = errCodeVal, formInfos = formInfoList](
1449             napi_env env, NapiAsyncTask &task, int32_t status) {
1450             if (errCode == nullptr || formInfos == nullptr) {
1451                 HILOG_ERROR("invalid param");
1452                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ERR_APPEXECFWK_FORM_COMMON_CODE));
1453                 return;
1454             }
1455             if (*errCode != ERR_OK) {
1456                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *errCode));
1457                 return;
1458             }
1459             task.ResolveWithNoError(env, CreateFormInfos(env, *formInfos));
1460         };
1461     }
1462 
InnerShareForm(napi_env env,const std::shared_ptr<AbilityRuntime::NapiAsyncTask> & asyncTask,ShareFormCallBackClient::ShareFormTask && task,int64_t formId,const std::string & remoteDeviceId)1463     void InnerShareForm(napi_env env, const std::shared_ptr<AbilityRuntime::NapiAsyncTask> &asyncTask,
1464         ShareFormCallBackClient::ShareFormTask &&task, int64_t formId, const std::string &remoteDeviceId)
1465     {
1466         auto shareFormCallback = std::make_shared<ShareFormCallBackClient>(std::move(task));
1467         int64_t requestCode = SystemTimeMillis();
1468         FormHostClient::GetInstance()->AddShareFormCallback(shareFormCallback, requestCode);
1469 
1470         ErrCode ret = FormMgr::GetInstance().ShareForm(
1471             formId, remoteDeviceId, FormHostClient::GetInstance(), requestCode);
1472         if (ret != ERR_OK) {
1473             HILOG_INFO("share form fail");
1474             asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1475             FormHostClient::GetInstance()->RemoveShareFormCallback(requestCode);
1476         }
1477     }
1478 
InnerAcquireFormData(napi_env env,const std::shared_ptr<AbilityRuntime::NapiAsyncTask> & asyncTask,JsFormDataCallbackClient::AcquireFormDataTask && task,int64_t formId)1479     void InnerAcquireFormData(napi_env env, const std::shared_ptr<AbilityRuntime::NapiAsyncTask> &asyncTask,
1480        JsFormDataCallbackClient::AcquireFormDataTask &&task, int64_t formId)
1481     {
1482         auto formDataCallbackClient = std::make_shared<JsFormDataCallbackClient>(std::move(task));
1483         int64_t requestCode = SystemTimeMillis();
1484         FormHostClient::GetInstance()->AddAcqiureFormDataCallback(formDataCallbackClient, requestCode);
1485 
1486         AAFwk::WantParams formData;
1487         auto ret = FormMgr::GetInstance().AcquireFormData(formId, requestCode, FormHostClient::GetInstance(), formData);
1488         if (ret != ERR_OK) {
1489             HILOG_ERROR("acquire form failed");
1490             asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1491             FormHostClient::GetInstance()->RemoveAcquireDataCallback(requestCode);
1492         }
1493     }
1494 
OnShareForm(napi_env env,size_t argc,napi_value * argv)1495     napi_value OnShareForm(napi_env env, size_t argc, napi_value* argv)
1496     {
1497         HILOG_DEBUG("call");
1498         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1499             HILOG_ERROR("invalid argc");
1500             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2 or 3");
1501             return CreateJsUndefined(env);
1502         }
1503 
1504         decltype(argc) convertArgc = 0;
1505         int64_t formId = 0;
1506         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1507             HILOG_ERROR("invalid formId");
1508             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1509             return CreateJsUndefined(env);
1510         }
1511         convertArgc++;
1512 
1513         std::string devicedId;
1514         if (!ConvertDeviceId(env, argv[PARAM1], devicedId)) {
1515             HILOG_ERROR("invalid deviceId");
1516             NapiFormUtil::ThrowParamTypeError(env, "devicedId", "string");
1517             return CreateJsUndefined(env);
1518         }
1519         convertArgc++;
1520 
1521         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1522         napi_value result = nullptr;
1523 
1524         std::unique_ptr<AbilityRuntime::NapiAsyncTask> uasyncTask =
1525             AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
1526         std::shared_ptr<AbilityRuntime::NapiAsyncTask> asyncTask = std::move(uasyncTask);
1527 
1528         ShareFormCallBackClient::ShareFormTask task = [env, asyncTask](int32_t code) {
1529             HILOG_DEBUG("task complete code:%{public}d", code);
1530             if (code == ERR_OK) {
1531                 asyncTask->ResolveWithNoError(env, CreateJsUndefined(env));
1532             } else {
1533                 asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, code));
1534             }
1535         };
1536 
1537         InnerShareForm(env, asyncTask, std::move(task), formId, devicedId);
1538 
1539         return result;
1540     }
1541 
OnAcquireFormData(napi_env env,size_t argc,napi_value * argv)1542     napi_value OnAcquireFormData(napi_env env, size_t argc, napi_value* argv)
1543     {
1544         HILOG_DEBUG("call");
1545         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1546             HILOG_ERROR("invalid argc");
1547             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1548             return CreateJsUndefined(env);
1549         }
1550 
1551         // The promise form has only one parameters
1552         decltype(argc) unwrapArgc = 1;
1553         int64_t formId = 0;
1554         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1555             HILOG_ERROR("invalid formId");
1556             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1557             return CreateJsUndefined(env);
1558         }
1559 
1560         napi_value lastParam = (argc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
1561         napi_value result = nullptr;
1562 
1563         std::unique_ptr<AbilityRuntime::NapiAsyncTask> uasyncTask =
1564             AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
1565         std::shared_ptr<AbilityRuntime::NapiAsyncTask> asyncTask = std::move(uasyncTask);
1566 
1567         JsFormDataCallbackClient::AcquireFormDataTask task = [env, asyncTask](AAFwk::WantParams data) {
1568             HILOG_DEBUG("task complete form data");
1569             napi_value objValue = nullptr;
1570             napi_create_object(env, &objValue);
1571             napi_set_named_property(env, objValue, "formData", CreateJsWantParams(env, data));
1572             asyncTask->ResolveWithNoError(env, objValue);
1573         };
1574 
1575         InnerAcquireFormData(env, asyncTask, std::move(task), formId);
1576         return result;
1577     }
1578 
OnNotifyFormsPrivacyProtected(napi_env env,size_t argc,napi_value * argv)1579     napi_value OnNotifyFormsPrivacyProtected(napi_env env, size_t argc, napi_value* argv)
1580     {
1581         HILOG_INFO("call");
1582         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1583             HILOG_ERROR("invalid argc");
1584             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1585             return CreateJsUndefined(env);
1586         }
1587 
1588         decltype(argc) convertArgc = 0;
1589         std::vector<int64_t> formIds;
1590         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1591             HILOG_ERROR("invalid formIdList");
1592             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1593             return CreateJsUndefined(env);
1594         }
1595         convertArgc++;
1596 
1597         bool isProtected = false;
1598         if (!ConvertFromJsValue(env, argv[PARAM1], isProtected)) {
1599             HILOG_ERROR("convert isProtected failed");
1600             NapiFormUtil::ThrowParamTypeError(env, "isProtected", "boolean");
1601             return CreateJsUndefined(env);
1602         }
1603         convertArgc++;
1604 
1605         NapiAsyncTask::CompleteCallback complete =
1606             [formIds, isProtected](napi_env env, NapiAsyncTask &task, int32_t status) {
1607                 auto ret = FormMgr::GetInstance().NotifyFormsPrivacyProtected(formIds,
1608                     isProtected, FormHostClient::GetInstance());
1609                 if (ret == ERR_OK) {
1610                     task.ResolveWithNoError(env, CreateJsUndefined(env));
1611                 } else {
1612                     task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1613                 }
1614             };
1615 
1616         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1617         napi_value result = nullptr;
1618         NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnNotifyFormsPrivacyProtected",
1619             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1620         return result;
1621     }
1622 
OnSetFormsRecyclable(napi_env env,size_t argc,napi_value * argv)1623     napi_value OnSetFormsRecyclable(napi_env env, size_t argc, napi_value *argv)
1624     {
1625         HILOG_DEBUG("call");
1626         if (argc < ARGS_ONE || argc > ARGS_TWO) {
1627             HILOG_ERROR("invalid argc");
1628             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1629             return CreateJsUndefined(env);
1630         }
1631 
1632         decltype(argc) convertArgc = 0;
1633         std::vector<int64_t> formIds;
1634         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1635             HILOG_ERROR("invalid formIdList");
1636             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1637             return CreateJsUndefined(env);
1638         }
1639         convertArgc++;
1640 
1641         NapiAsyncTask::CompleteCallback complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
1642             auto ret = FormMgr::GetInstance().SetFormsRecyclable(formIds);
1643             if (ret == ERR_OK) {
1644                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1645             } else {
1646                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1647             }
1648         };
1649 
1650         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1651         napi_value result = nullptr;
1652         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnSetFormsRecyclable",
1653             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1654         return result;
1655     }
1656 
OnRecoverForms(napi_env env,size_t argc,napi_value * argv)1657     napi_value OnRecoverForms(napi_env env, size_t argc, napi_value *argv)
1658     {
1659         HILOG_DEBUG("call");
1660         if (argc < ARGS_ONE || argc > ARGS_TWO) {
1661             HILOG_ERROR("invalid argc");
1662             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1663             return CreateJsUndefined(env);
1664         }
1665 
1666         decltype(argc) convertArgc = 0;
1667         std::vector<int64_t> formIds;
1668         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1669             HILOG_ERROR("invalid formIdList");
1670             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1671             return CreateJsUndefined(env);
1672         }
1673         convertArgc++;
1674 
1675         NapiAsyncTask::CompleteCallback complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
1676             Want want;
1677             auto ret = FormMgr::GetInstance().RecoverForms(formIds, want);
1678             if (ret == ERR_OK) {
1679                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1680             } else {
1681                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1682             }
1683         };
1684 
1685         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1686         napi_value result = nullptr;
1687         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRecoverForms",
1688             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1689         return result;
1690     }
1691 
OnRecycleForms(napi_env env,size_t argc,napi_value * argv)1692     napi_value OnRecycleForms(napi_env env, size_t argc, napi_value *argv)
1693     {
1694         HILOG_DEBUG("call");
1695         if (argc < ARGS_ONE || argc > ARGS_TWO) {
1696             HILOG_ERROR("invalid argc");
1697             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1698             return CreateJsUndefined(env);
1699         }
1700 
1701         decltype(argc) convertArgc = 0;
1702         std::vector<int64_t> formIds;
1703         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1704             HILOG_ERROR("invalid formIdList");
1705             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1706             return CreateJsUndefined(env);
1707         }
1708         convertArgc++;
1709 
1710         NapiAsyncTask::CompleteCallback complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
1711             Want want;
1712             auto ret = FormMgr::GetInstance().RecycleForms(formIds, want);
1713             if (ret == ERR_OK) {
1714                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1715             } else {
1716                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1717             }
1718         };
1719 
1720         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1721         napi_value result = nullptr;
1722         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRecycleForms",
1723             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1724         return result;
1725     }
1726 
OnUpdateFormLocation(napi_env env,size_t argc,napi_value * argv)1727     napi_value OnUpdateFormLocation(napi_env env, size_t argc, napi_value *argv)
1728     {
1729         HILOG_DEBUG("call");
1730         if (argc != ARGS_TWO) {
1731             HILOG_ERROR("invalid argc");
1732             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "argc != 2");
1733             return CreateJsUndefined(env);
1734         }
1735 
1736         int64_t formId = -1;
1737         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1738             HILOG_ERROR("Convert strFormIdList failed");
1739             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1740             return CreateJsUndefined(env);
1741         }
1742         HILOG_INFO("formId:%{public}s", std::to_string(formId).c_str());
1743         int32_t formLocation = INVALID_FORM_LOCATION;
1744         if (napi_get_value_int32(env, argv[PARAM1], &formLocation) == napi_ok) {
1745             if (formLocation < static_cast<int32_t>(Constants::FormLocation::OTHER) ||
1746                  formLocation > static_cast<int32_t>(Constants::FormLocation::AI_SUGGESTION)) {
1747                 HILOG_ERROR("formLocation not FormLocation enum");
1748                 NapiFormUtil::ThrowParamTypeError(env, "formLocation", "FormLocation enum");
1749                 return CreateJsUndefined(env);
1750             }
1751         } else {
1752             HILOG_ERROR("formLocation not number");
1753             NapiFormUtil::ThrowParamTypeError(env, "formLocation", "number");
1754             return CreateJsUndefined(env);
1755         }
1756         HILOG_INFO("formLocation:%{public}s", std::to_string(formLocation).c_str());
1757         auto ret = FormMgr::GetInstance().UpdateFormLocation(formId, formLocation);
1758         if (ret == ERR_OK) {
1759             return CreateJsUndefined(env);
1760         }
1761         NapiFormUtil::ThrowByInternalErrorCode(env, ret);
1762         return CreateJsUndefined(env);
1763     }
1764 
OnSetPublishFormResult(napi_env env,size_t argc,napi_value * argv)1765     napi_value OnSetPublishFormResult(napi_env env, size_t argc, napi_value *argv)
1766     {
1767         HILOG_DEBUG("call");
1768         if (!CheckCallerIsSystemApp()) {
1769             HILOG_ERROR("the application not system-app,can't use system-api");
1770             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
1771             return CreateJsUndefined(env);
1772         }
1773         if (argc != ARGS_TWO) {
1774             HILOG_ERROR("invalid argc");
1775             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2");
1776             return CreateJsUndefined(env);
1777         }
1778         decltype(argc) convertArgc = 0;
1779         int64_t formId;
1780         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1781             HILOG_ERROR("Convert strFormId failed");
1782             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1783             return CreateJsUndefined(env);
1784         }
1785         convertArgc++;
1786         std::string messageInfo = "";
1787         int32_t formErrorCode = INVALID_FORM_RESULT_ERRCODE;
1788         if (!ParseParameter(env, argv, formErrorCode, messageInfo)) {
1789             HILOG_ERROR("Parsing Argument Errors");
1790             NapiFormUtil::ThrowParamError(env, "Failed to get property.");
1791             return CreateJsUndefined(env);
1792         }
1793         convertArgc++;
1794 
1795         AppExecFwk::Constants::PublishFormResult publishFormResult;
1796         publishFormResult.code = static_cast<AppExecFwk::Constants::PublishFormErrorCode>(formErrorCode);
1797         publishFormResult.message = messageInfo;
1798         ErrCode ret = FormMgr::GetInstance().SetPublishFormResult(formId, publishFormResult);
1799         if (ret == ERR_OK) {
1800             return CreateJsUndefined(env);
1801         }
1802         NapiFormUtil::ThrowByInternalErrorCode(env, ret);
1803         return CreateJsUndefined(env);
1804     }
1805 };
1806 
JsFormHostInit(napi_env env,napi_value exportObj)1807 napi_value JsFormHostInit(napi_env env, napi_value exportObj)
1808 {
1809     HILOG_DEBUG("call");
1810 
1811     std::unique_ptr<JsFormHost> jsFormHost = std::make_unique<JsFormHost>();
1812     napi_wrap(env, exportObj, jsFormHost.release(), JsFormHost::Finalizer, nullptr, nullptr);
1813 
1814     const char *moduleName = "JsFormHost";
1815     BindNativeFunction(env, exportObj, "deleteForm", moduleName, JsFormHost::DeleteForm);
1816     BindNativeFunction(env, exportObj, "releaseForm", moduleName, JsFormHost::ReleaseForm);
1817     BindNativeFunction(env, exportObj, "requestForm", moduleName, JsFormHost::RequestForm);
1818     BindNativeFunction(env, exportObj, "requestFormWithParams", moduleName, JsFormHost::RequestFormWithParams);
1819     BindNativeFunction(env, exportObj, "castTempForm", moduleName, JsFormHost::CastTempForm);
1820     BindNativeFunction(env, exportObj, "castToNormalForm", moduleName, JsFormHost::CastTempForm);
1821     BindNativeFunction(env, exportObj, "notifyVisibleForms", moduleName, JsFormHost::NotifyVisibleForms);
1822     BindNativeFunction(env, exportObj, "notifyInvisibleForms", moduleName, JsFormHost::NotifyInvisibleForms);
1823     BindNativeFunction(env, exportObj, "enableFormsUpdate", moduleName, JsFormHost::EnableFormsUpdate);
1824     BindNativeFunction(env, exportObj, "disableFormsUpdate", moduleName, JsFormHost::DisableFormsUpdate);
1825     BindNativeFunction(env, exportObj, "isSystemReady", moduleName, JsFormHost::IsSystemReady);
1826     BindNativeFunction(env, exportObj, "deleteInvalidForms", moduleName, JsFormHost::DeleteInvalidForms);
1827     BindNativeFunction(env, exportObj, "acquireFormState", moduleName, JsFormHost::AcquireFormState);
1828     BindNativeFunction(env, exportObj, "on", moduleName, JsFormHost::RegisterFormObserver);
1829     BindNativeFunction(env, exportObj, "off", moduleName, JsFormHost::UnregisterFormObserver);
1830     BindNativeFunction(env, exportObj, "notifyFormsVisible", moduleName, JsFormHost::NotifyFormsVisible);
1831     BindNativeFunction(env, exportObj, "notifyFormsEnableUpdate", moduleName, JsFormHost::NotifyFormsEnableUpdate);
1832     BindNativeFunction(env, exportObj, "getAllFormsInfo", moduleName, JsFormHost::GetAllFormsInfo);
1833     BindNativeFunction(env, exportObj, "getFormsInfo", moduleName, JsFormHost::GetFormsInfo);
1834     BindNativeFunction(env, exportObj, "shareForm", moduleName, JsFormHost::ShareForm);
1835     BindNativeFunction(env, exportObj, "notifyFormsPrivacyProtected", moduleName,
1836         JsFormHost::NotifyFormsPrivacyProtected);
1837     BindNativeFunction(env, exportObj, "acquireFormData", moduleName, JsFormHost::AcquireFormData);
1838     BindNativeFunction(env, exportObj, "setRouterProxy", moduleName, JsFormHost::SetRouterProxy);
1839     BindNativeFunction(env, exportObj, "clearRouterProxy", moduleName, JsFormHost::ClearRouterProxy);
1840     BindNativeFunction(env, exportObj, "setFormsRecyclable", moduleName, JsFormHost::SetFormsRecyclable);
1841     BindNativeFunction(env, exportObj, "recoverForms", moduleName, JsFormHost::RecoverForms);
1842     BindNativeFunction(env, exportObj, "recycleForms", moduleName, JsFormHost::RecycleForms);
1843     BindNativeFunction(env, exportObj, "updateFormLocation", moduleName, JsFormHost::UpdateFormLocation);
1844     BindNativeFunction(env, exportObj, "setPublishFormResult", moduleName, JsFormHost::SetPublishFormResult);
1845     BindNativeFunction(env, exportObj, "addForm", moduleName, JsFormHost::AddForm);
1846 
1847     return CreateJsUndefined(env);
1848 }
1849 
FormRouterProxyCallbackClient(napi_env env,napi_ref callbackRef)1850 FormRouterProxyCallbackClient::FormRouterProxyCallbackClient(napi_env env, napi_ref callbackRef)
1851 {
1852     env_ = env;
1853     callbackRef_ = callbackRef;
1854     handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
1855 }
1856 
~FormRouterProxyCallbackClient()1857 FormRouterProxyCallbackClient::~FormRouterProxyCallbackClient()
1858 {
1859     napi_delete_reference(env_, callbackRef_);
1860 }
1861 
ProcessFormRouterProxy(const Want & want)1862 void FormRouterProxyCallbackClient::ProcessFormRouterProxy(const Want &want)
1863 {
1864     HILOG_INFO("call");
1865     if (handler_ == nullptr) {
1866         HILOG_ERROR("null Handler");
1867         return;
1868     }
1869     handler_->PostSyncTask([thisWeakPtr = weak_from_this(), want]() {
1870         auto sharedThis = thisWeakPtr.lock();
1871         if (sharedThis == nullptr) {
1872             HILOG_ERROR("null SharedThis");
1873             return;
1874         }
1875 
1876         napi_value callbackValues = CreateJsWant(sharedThis->env_, want);
1877         napi_value callResult;
1878         napi_value myCallback = nullptr;
1879         napi_get_reference_value(sharedThis->env_, sharedThis->callbackRef_, &myCallback);
1880         if (myCallback != nullptr) {
1881             napi_call_function(sharedThis->env_, nullptr, myCallback, ARGS_ONE, &callbackValues, &callResult);
1882         }
1883     });
1884 }
1885 
1886 sptr<JsFormRouterProxyMgr> JsFormRouterProxyMgr::instance_ = nullptr;
1887 std::mutex JsFormRouterProxyMgr::mutex_;
GetInstance()1888 sptr<JsFormRouterProxyMgr> JsFormRouterProxyMgr::GetInstance()
1889 {
1890     if (instance_ == nullptr) {
1891         std::lock_guard<std::mutex> lock(mutex_);
1892         if (instance_ == nullptr) {
1893             instance_ = new (std::nothrow) JsFormRouterProxyMgr();
1894             if (instance_ == nullptr) {
1895                 HILOG_ERROR("create JsFormRouterProxyMgr failed");
1896             }
1897         }
1898     }
1899     return instance_;
1900 }
1901 
RouterEvent(int64_t formId,const Want & want)1902 ErrCode JsFormRouterProxyMgr::RouterEvent(int64_t formId, const Want &want)
1903 {
1904     HILOG_DEBUG("call");
1905 
1906     std::lock_guard<std::mutex> lock(FormRouterProxyCallbackMutex_);
1907     auto callbackClient = formRouterProxyCallbackMap_.find(formId);
1908     if (callbackClient != formRouterProxyCallbackMap_.end()) {
1909         if (callbackClient->second != nullptr) {
1910             callbackClient->second->ProcessFormRouterProxy(want);
1911         }
1912     }
1913     return ERR_OK;
1914 }
1915 
AddFormRouterProxyCallback(napi_env env,napi_value callback,const std::vector<int64_t> & formIds)1916 void JsFormRouterProxyMgr::AddFormRouterProxyCallback(napi_env env, napi_value callback,
1917     const std::vector<int64_t> &formIds)
1918 {
1919     HILOG_DEBUG("call");
1920     std::lock_guard<std::mutex> lock(FormRouterProxyCallbackMutex_);
1921 
1922     napi_ref callbackRef;
1923     napi_create_reference(env, callback, REF_COUNT, &callbackRef);
1924     std::shared_ptr<FormRouterProxyCallbackClient> callbackClient = std::make_shared<FormRouterProxyCallbackClient>(env,
1925         callbackRef);
1926 
1927     for (const auto &formId : formIds) {
1928         auto iter = formRouterProxyCallbackMap_.find(formId);
1929         if (iter != formRouterProxyCallbackMap_.end()) {
1930             iter->second = callbackClient;
1931             continue;
1932         }
1933         formRouterProxyCallbackMap_.emplace(formId, callbackClient);
1934     }
1935 }
1936 
RemoveFormRouterProxyCallback(const std::vector<int64_t> & formIds)1937 void JsFormRouterProxyMgr::RemoveFormRouterProxyCallback(const std::vector<int64_t> &formIds)
1938 {
1939     HILOG_INFO("call");
1940     std::lock_guard<std::mutex> lock(FormRouterProxyCallbackMutex_);
1941     for (const auto &formId : formIds) {
1942         auto iter = formRouterProxyCallbackMap_.find(formId);
1943         if (iter != formRouterProxyCallbackMap_.end()) {
1944             formRouterProxyCallbackMap_.erase(formId);
1945         }
1946     }
1947 }
1948 } // namespace AbilityRuntime
1949 } // namespace OHOS
1950