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