• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) 2022 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 "form_info.h"
20 #include "form_callback_interface.h"
21 #include "form_host_client.h"
22 #include "form_mgr.h"
23 #include "form_mgr_errors.h"
24 #include "hilog_wrapper.h"
25 #include "napi_form_util.h"
26 #include "napi/native_api.h"
27 #include "napi/native_node_api.h"
28 #include "napi_common_util.h"
29 #include "napi_common_want.h"
30 #include "runtime.h"
31 
32 namespace OHOS {
33 namespace AbilityRuntime {
34 using namespace OHOS;
35 using namespace OHOS::AAFwk;
36 using namespace OHOS::AppExecFwk;
37 
38 namespace {
39     constexpr int REF_COUNT = 1;
40     // NANOSECONDS mean 10^9 nano second
41     constexpr int64_t NANOSECONDS = 1000000000;
42     // MICROSECONDS mean 10^6 millias second
43     constexpr int64_t MICROSECONDS = 1000000;
44 }
45 
SystemTimeMillis()46 int64_t SystemTimeMillis() noexcept
47 {
48     struct timespec t;
49     t.tv_sec = 0;
50     t.tv_nsec = 0;
51     clock_gettime(CLOCK_MONOTONIC, &t);
52     return static_cast<int64_t>(((t.tv_sec) * NANOSECONDS + t.tv_nsec) / MICROSECONDS);
53 }
54 
55 class ShareFormCallBackClient : public ShareFormCallBack,
56                                 public std::enable_shared_from_this<ShareFormCallBackClient> {
57 public:
58     using ShareFormTask = std::function<void(int32_t)>;
ShareFormCallBackClient(ShareFormTask && task)59     explicit ShareFormCallBackClient(ShareFormTask &&task) : task_(std::move(task))
60     {
61         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
62     }
63 
64     virtual ~ShareFormCallBackClient() = default;
65 
ProcessShareFormResponse(int32_t result)66     void ProcessShareFormResponse(int32_t result) override
67     {
68         if (handler_) {
69             handler_->PostSyncTask([client = shared_from_this(), result] () {
70                 client->task_(result);
71             });
72         }
73     }
74 
75 private:
76     ShareFormTask task_;
77     std::shared_ptr<AppExecFwk::EventHandler> handler_;
78 };
79 
80 class FormUninstallCallbackClient : public std::enable_shared_from_this<FormUninstallCallbackClient>
81 {
82 public:
FormUninstallCallbackClient(napi_env env,napi_ref callbackRef)83     FormUninstallCallbackClient(napi_env env, napi_ref callbackRef) : callbackRef_(callbackRef), env_(env)
84     {
85         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
86     }
87 
~FormUninstallCallbackClient()88     virtual ~FormUninstallCallbackClient()
89     {
90         napi_delete_reference(env_, callbackRef_);
91     }
92 
ProcessFormUninstall(const int64_t formId)93     void ProcessFormUninstall(const int64_t formId)
94     {
95         if (handler_ == nullptr) {
96             HILOG_INFO("handler is nullptr");
97             return;
98         }
99         handler_->PostSyncTask([thisWeakPtr = weak_from_this(), formId]() {
100             auto sharedThis = thisWeakPtr.lock();
101             if (sharedThis == nullptr) {
102                 HILOG_ERROR("sharedThis is nullptr.");
103                 return;
104             }
105             HILOG_DEBUG("task complete formId: form: %{public}" PRId64 ".", formId);
106             std::string formIdString = std::to_string(formId);
107             napi_value callbackValues;
108             napi_create_string_utf8(sharedThis->env_, formIdString.c_str(), NAPI_AUTO_LENGTH, &callbackValues);
109             napi_value callResult;
110             napi_value myCallback = nullptr;
111             napi_get_reference_value(sharedThis->env_, sharedThis->callbackRef_, &myCallback);
112             if (myCallback != nullptr) {
113                 napi_call_function(sharedThis->env_, nullptr, myCallback, ARGS_ONE, &callbackValues, &callResult);
114             }
115         });
116     }
117 
IsStrictEqual(napi_value callback)118     bool IsStrictEqual(napi_value callback)
119     {
120         bool isEqual = false;
121         napi_value myCallback = nullptr;
122         napi_get_reference_value(env_, callbackRef_, &myCallback);
123         napi_strict_equals(env_, myCallback, callback, &isEqual);
124         HILOG_INFO("isStrictEqual: %{public}d", isEqual);
125         return isEqual;
126     }
127 
128 private:
129     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
130     napi_ref callbackRef_ {};
131     napi_env env_;
132 };
133 
134 class JsFormStateCallbackClient : public FormStateCallbackInterface,
135                                   public std::enable_shared_from_this<JsFormStateCallbackClient> {
136 public:
137     using AcquireFormStateTask = std::function<void(int32_t, Want)>;
JsFormStateCallbackClient(AcquireFormStateTask && task)138     explicit JsFormStateCallbackClient(AcquireFormStateTask &&task) : task_(std::move(task))
139     {
140         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
141     }
142 
143     virtual ~JsFormStateCallbackClient() = default;
144 
ProcessAcquireState(FormState state)145     void ProcessAcquireState(FormState state) override
146     {
147         if (handler_) {
148             handler_->PostSyncTask([client = shared_from_this(), state] () {
149                 client->task_(static_cast<int32_t>(state), client->want_);
150             });
151         }
152     }
153 
SetWant(const Want want)154     void SetWant(const Want want)
155     {
156         want_ = want;
157     }
158 private:
159     Want want_;
160     AcquireFormStateTask task_;
161     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
162 };
163 
164 std::map<napi_ref, std::shared_ptr<FormUninstallCallbackClient>> formUninstallCallbackMap {};
165 std::mutex formUninstallCallbackMapMutex_;
166 
FormUninstallCallback(const std::vector<int64_t> & formIds)167 void FormUninstallCallback(const std::vector<int64_t> &formIds)
168 {
169     std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
170     for (auto &iter : formUninstallCallbackMap) {
171         for (int64_t formId : formIds) {
172             iter.second->ProcessFormUninstall(formId);
173         }
174     }
175 }
176 
AddFormUninstallCallback(napi_env env,napi_value callback)177 bool AddFormUninstallCallback(napi_env env, napi_value callback)
178 {
179     std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
180     for (auto &iter : formUninstallCallbackMap) {
181         if (iter.second->IsStrictEqual(callback)) {
182             HILOG_ERROR("found equal callback");
183             return false;
184         }
185     }
186 
187     napi_ref callbackRef;
188     napi_create_reference(env, callback, REF_COUNT, &callbackRef);
189     std::shared_ptr<FormUninstallCallbackClient> callbackClient = std::make_shared<FormUninstallCallbackClient>(env,
190         callbackRef);
191 
192     auto ret = formUninstallCallbackMap.emplace(callbackRef, callbackClient);
193     if (!ret.second) {
194         HILOG_ERROR("failed to emplace callback");
195         return false;
196     }
197     return true;
198 }
199 
DelFormUninstallCallback(napi_value callback)200 bool DelFormUninstallCallback(napi_value callback)
201 {
202     int32_t count = 0;
203     std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
204     for (auto iter = formUninstallCallbackMap.begin(); iter != formUninstallCallbackMap.end();) {
205         if (iter->second->IsStrictEqual(callback)) {
206             HILOG_INFO("found equal callback");
207             iter = formUninstallCallbackMap.erase(iter);
208             count++;
209         } else {
210             iter++;
211         }
212     }
213     HILOG_INFO("%{public}d form uninstall callback deleted.", count);
214     return true;
215 }
216 
ClearFormUninstallCallback()217 bool ClearFormUninstallCallback()
218 {
219     std::lock_guard<std::mutex> lock(formUninstallCallbackMapMutex_);
220     formUninstallCallbackMap.clear();
221     return true;
222 }
223 
224 class JsFormHost {
225 public:
226     JsFormHost() = default;
227     ~JsFormHost() = default;
228 
Finalizer(NativeEngine * engine,void * data,void * hint)229     static void Finalizer(NativeEngine* engine, void* data, void* hint)
230     {
231         HILOG_INFO("JsFormHost::Finalizer is called");
232         std::unique_ptr<JsFormHost>(static_cast<JsFormHost*>(data));
233     }
234 
DeleteForm(NativeEngine * engine,NativeCallbackInfo * info)235     static NativeValue* DeleteForm(NativeEngine* engine, NativeCallbackInfo* info)
236     {
237         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
238         return (me != nullptr) ? me->OnDeleteForm(*engine, *info) : nullptr;
239     }
240 
ReleaseForm(NativeEngine * engine,NativeCallbackInfo * info)241     static NativeValue* ReleaseForm(NativeEngine* engine, NativeCallbackInfo* info)
242     {
243         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
244         return (me != nullptr) ? me->OnReleaseForm(*engine, *info) : nullptr;
245     }
246 
RequestForm(NativeEngine * engine,NativeCallbackInfo * info)247     static NativeValue* RequestForm(NativeEngine* engine, NativeCallbackInfo* info)
248     {
249         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
250         return (me != nullptr) ? me->OnRequestForm(*engine, *info) : nullptr;
251     }
252 
CastTempForm(NativeEngine * engine,NativeCallbackInfo * info)253     static NativeValue* CastTempForm(NativeEngine* engine, NativeCallbackInfo* info)
254     {
255         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
256         return (me != nullptr) ? me->OnCastTempForm(*engine, *info) : nullptr;
257     }
258 
NotifyVisibleForms(NativeEngine * engine,NativeCallbackInfo * info)259     static NativeValue* NotifyVisibleForms(NativeEngine* engine, NativeCallbackInfo* info)
260     {
261         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
262         return (me != nullptr) ? me->OnNotifyVisibleForms(*engine, *info) : nullptr;
263     }
264 
NotifyInvisibleForms(NativeEngine * engine,NativeCallbackInfo * info)265     static NativeValue* NotifyInvisibleForms(NativeEngine* engine, NativeCallbackInfo* info)
266     {
267         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
268         return (me != nullptr) ? me->OnNotifyInvisibleForms(*engine, *info) : nullptr;
269     }
270 
EnableFormsUpdate(NativeEngine * engine,NativeCallbackInfo * info)271     static NativeValue* EnableFormsUpdate(NativeEngine* engine, NativeCallbackInfo* info)
272     {
273         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
274         return (me != nullptr) ? me->OnEnableFormsUpdate(*engine, *info) : nullptr;
275     }
276 
DisableFormsUpdate(NativeEngine * engine,NativeCallbackInfo * info)277     static NativeValue* DisableFormsUpdate(NativeEngine* engine, NativeCallbackInfo* info)
278     {
279         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
280         return (me != nullptr) ? me->OnDisableFormsUpdate(*engine, *info) : nullptr;
281     }
282 
IsSystemReady(NativeEngine * engine,NativeCallbackInfo * info)283     static NativeValue* IsSystemReady(NativeEngine* engine, NativeCallbackInfo* info)
284     {
285         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
286         return (me != nullptr) ? me->OnIsSystemReady(*engine, *info) : nullptr;
287     }
288 
DeleteInvalidForms(NativeEngine * engine,NativeCallbackInfo * info)289     static NativeValue* DeleteInvalidForms(NativeEngine* engine, NativeCallbackInfo* info)
290     {
291         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
292         return (me != nullptr) ? me->OnDeleteInvalidForms(*engine, *info) : nullptr;
293     }
294 
AcquireFormState(NativeEngine * engine,NativeCallbackInfo * info)295     static NativeValue* AcquireFormState(NativeEngine* engine, NativeCallbackInfo* info)
296     {
297         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
298         return (me != nullptr) ? me->OnAcquireFormState(*engine, *info) : nullptr;
299     }
300 
RegisterFormUninstallObserver(NativeEngine * engine,NativeCallbackInfo * info)301     static NativeValue* RegisterFormUninstallObserver(NativeEngine* engine, NativeCallbackInfo* info)
302     {
303         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
304         return (me != nullptr) ? me->OnRegisterFormUninstallObserver(*engine, *info) : nullptr;
305     }
306 
UnregisterFormUninstallObserver(NativeEngine * engine,NativeCallbackInfo * info)307     static NativeValue* UnregisterFormUninstallObserver(NativeEngine* engine, NativeCallbackInfo* info)
308     {
309         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
310         return (me != nullptr) ? me->OnUnregisterFormUninstallObserver(*engine, *info) : nullptr;
311     }
312 
NotifyFormsVisible(NativeEngine * engine,NativeCallbackInfo * info)313     static NativeValue* NotifyFormsVisible(NativeEngine* engine, NativeCallbackInfo* info)
314     {
315         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
316         return (me != nullptr) ? me->OnNotifyFormsVisible(*engine, *info) : nullptr;
317     }
318 
NotifyFormsEnableUpdate(NativeEngine * engine,NativeCallbackInfo * info)319     static NativeValue* NotifyFormsEnableUpdate(NativeEngine* engine, NativeCallbackInfo* info)
320     {
321         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
322         return (me != nullptr) ? me->OnNotifyFormsEnableUpdate(*engine, *info) : nullptr;
323     }
324 
GetAllFormsInfo(NativeEngine * engine,NativeCallbackInfo * info)325     static NativeValue* GetAllFormsInfo(NativeEngine* engine, NativeCallbackInfo* info)
326     {
327         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
328         return (me != nullptr) ? me->OnGetAllFormsInfo(*engine, *info) : nullptr;
329     }
330 
GetFormsInfo(NativeEngine * engine,NativeCallbackInfo * info)331     static NativeValue* GetFormsInfo(NativeEngine* engine, NativeCallbackInfo* info)
332     {
333         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
334         return (me != nullptr) ? me->OnGetFormsInfo(*engine, *info) : nullptr;
335     }
336 
ShareForm(NativeEngine * engine,NativeCallbackInfo * info)337     static NativeValue* ShareForm(NativeEngine* engine, NativeCallbackInfo* info)
338     {
339         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
340         return (me != nullptr) ? me->OnShareForm(*engine, *info) : nullptr;
341     }
342 
NotifyFormsPrivacyProtected(NativeEngine * engine,NativeCallbackInfo * info)343     static NativeValue* NotifyFormsPrivacyProtected(NativeEngine* engine, NativeCallbackInfo* info)
344     {
345         JsFormHost* me = CheckParamsAndGetThis<JsFormHost>(engine, info);
346         return (me != nullptr) ? me->OnNotifyFormsPrivacyProtected(*engine, *info) : nullptr;
347     }
348 private:
ConvertFromId(NativeEngine & engine,NativeValue * jsValue,int64_t & formId)349     static bool ConvertFromId(NativeEngine& engine, NativeValue* jsValue, int64_t &formId)
350     {
351         if (jsValue->TypeOf() != NATIVE_STRING) {
352             HILOG_ERROR("input params is not string.");
353             return false;
354         }
355 
356         std::string strFormId;
357         if (!ConvertFromJsValue(engine, jsValue, strFormId)) {
358             HILOG_ERROR("convert strFormId failed.");
359             return false;
360         }
361 
362         if (strFormId.empty()) {
363             HILOG_ERROR("strFormId is empty.");
364             return false;
365         }
366 
367         if (!ConvertStringToInt64(strFormId, formId)) {
368             HILOG_ERROR("convert string formId to int64 failed.");
369             return false;
370         }
371         return true;
372     }
373 
GetStringsValue(NativeEngine & engine,NativeValue * object,std::vector<std::string> & strList)374     bool GetStringsValue(NativeEngine &engine, NativeValue *object, std::vector<std::string> &strList)
375     {
376         auto array = ConvertNativeValueTo<NativeArray>(object);
377         if (array == nullptr) {
378             HILOG_ERROR("input params error");
379             return false;
380         }
381 
382         for (uint32_t i = 0; i < array->GetLength(); i++) {
383             std::string itemStr("");
384             if ((array->GetElement(i))->TypeOf() != NATIVE_STRING) {
385                 HILOG_ERROR("GetElement is not string");
386                 return false;
387             }
388             if (!ConvertFromJsValue(engine, array->GetElement(i), itemStr)) {
389                 HILOG_ERROR("GetElement from to array [%{public}u] error", i);
390                 return false;
391             }
392             strList.push_back(itemStr);
393         }
394 
395         return true;
396     }
397 
ConvertFromIds(NativeEngine & engine,NativeValue * jsValue,std::vector<int64_t> & formIds)398     bool ConvertFromIds(NativeEngine& engine, NativeValue* jsValue, std::vector<int64_t> &formIds)
399     {
400         if (!(jsValue->IsArray())) {
401             HILOG_ERROR("input params0 is not array!");
402             return false;
403         }
404 
405         std::vector<string> strFormIdList;
406         if(!GetStringsValue(engine, jsValue, strFormIdList)) {
407             HILOG_ERROR("convert strFormIdList failed!");
408             return false;
409         }
410 
411         for(size_t i = 0; i < strFormIdList.size(); i++) {
412             int64_t formIdValue;
413             if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
414                 HILOG_ERROR("convert formIdValue failed!");
415                 return false;
416             }
417             formIds.push_back(formIdValue);
418         }
419         return true;
420     }
421 
ConvertDeviceId(NativeEngine & engine,NativeValue * jsValue,std::string & deviceId)422     bool ConvertDeviceId(NativeEngine& engine, NativeValue* jsValue, std::string &deviceId)
423     {
424         if (jsValue->TypeOf() != NATIVE_STRING) {
425             HILOG_ERROR("input params is not string.");
426             return false;
427         }
428 
429         if (!ConvertFromJsValue(engine, jsValue, deviceId)) {
430             HILOG_ERROR("convert deviceId failed.");
431             return false;
432         }
433 
434         if (deviceId.empty()) {
435             HILOG_ERROR("deviceId is empty.");
436             return false;
437         }
438 
439         return true;
440     }
441 
OnDeleteForm(NativeEngine & engine,NativeCallbackInfo & info)442     NativeValue* OnDeleteForm(NativeEngine &engine, NativeCallbackInfo &info)
443     {
444         HILOG_DEBUG("%{public}s called.", __func__);
445 
446         if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
447             HILOG_ERROR("OnDeleteForm wrong number of arguments.");
448             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
449             return engine.CreateUndefined();
450         }
451 
452         decltype(info.argc) convertArgc = 0;
453         HILOG_DEBUG("info.argv[PARAM0]->TypeOf() %{public}d", info.argv[PARAM0]->TypeOf());
454         int64_t formId = 0;
455         if (!ConvertFromId(engine, info.argv[PARAM0], formId)) {
456             HILOG_ERROR("form id is invalid.");
457             NapiFormUtil::ThrowParamTypeError(engine, "formId", "string");
458             return engine.CreateUndefined();
459         }
460         convertArgc++;
461 
462         AsyncTask::CompleteCallback complete = [formId](NativeEngine &engine, AsyncTask &task, int32_t status) {
463             auto ret = FormMgr::GetInstance().DeleteForm(formId, FormHostClient::GetInstance());
464             if (ret == ERR_OK) {
465                 task.ResolveWithNoError(engine, engine.CreateUndefined());
466             } else {
467                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
468             }
469         };
470 
471         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
472         NativeValue* result = nullptr;
473         AsyncTask::Schedule("JsFormHost::OnDeleteForm",
474             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
475         return result;
476     }
477 
OnReleaseForm(NativeEngine & engine,const NativeCallbackInfo & info)478     NativeValue* OnReleaseForm(NativeEngine &engine, const NativeCallbackInfo &info)
479     {
480         HILOG_DEBUG("%{public}s called.", __func__);
481 
482         if (info.argc > ARGS_THREE || info.argc < ARGS_ONE) {
483             HILOG_ERROR("OnReleaseForm wrong number of arguments.");
484             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2 or 3");
485             return engine.CreateUndefined();
486         }
487 
488         decltype(info.argc) convertArgc = 0;
489         int64_t formId = 0;
490         if (!ConvertFromId(engine, info.argv[PARAM0], formId)) {
491             HILOG_ERROR("form id is invalid.");
492             NapiFormUtil::ThrowParamTypeError(engine, "formId", "string");
493             return engine.CreateUndefined();
494         }
495         convertArgc++;
496 
497         bool isReleaseCache = false;
498         if ((info.argc == ARGS_TWO || info.argc == ARGS_THREE) && info.argv[PARAM1]->TypeOf() != NATIVE_FUNCTION) {
499             if (info.argv[PARAM1]->TypeOf() != NATIVE_BOOLEAN) {
500                 HILOG_ERROR("promise second param type is illegal");
501                 NapiFormUtil::ThrowParamTypeError(engine, "isReleaseCache", "boolean");
502                 return engine.CreateUndefined();
503             }
504 
505             if (!ConvertFromJsValue(engine, info.argv[PARAM1], isReleaseCache)) {
506                 HILOG_ERROR("convert isReleaseCache failed!");
507                 NapiFormUtil::ThrowParamTypeError(engine, "isReleaseCache", "boolean");
508                 return engine.CreateUndefined();
509             }
510             convertArgc++;
511         }
512 
513         AsyncTask::CompleteCallback complete = [formId, isReleaseCache]
514             (NativeEngine &engine, AsyncTask &task, int32_t status) {
515             auto ret = FormMgr::GetInstance().ReleaseForm(formId, FormHostClient::GetInstance(), isReleaseCache);
516             if (ret == ERR_OK) {
517                 task.ResolveWithNoError(engine, engine.CreateUndefined());
518             } else {
519                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
520             }
521         };
522 
523         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
524         NativeValue* result = nullptr;
525         AsyncTask::Schedule("JsFormHost::OnReleaseForm",
526             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
527         return result;
528     }
529 
OnRequestForm(NativeEngine & engine,const NativeCallbackInfo & info)530     NativeValue* OnRequestForm(NativeEngine &engine, const NativeCallbackInfo &info)
531     {
532         HILOG_DEBUG("%{public}s called.", __func__);
533 
534         if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
535             HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
536             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
537             return engine.CreateUndefined();
538         }
539 
540         decltype(info.argc) convertArgc = 0;
541         int64_t formId = 0;
542         if (!ConvertFromId(engine, info.argv[PARAM0], formId)) {
543             HILOG_ERROR("form id is invalid.");
544             NapiFormUtil::ThrowParamTypeError(engine, "formId", "string");
545             return engine.CreateUndefined();
546         }
547         convertArgc++;
548 
549         AsyncTask::CompleteCallback complete = [formId](NativeEngine &engine, AsyncTask &task, int32_t status) {
550             Want want;
551             auto ret = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
552             if (ret == ERR_OK) {
553                 task.ResolveWithNoError(engine, engine.CreateUndefined());
554             } else {
555                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
556             }
557         };
558 
559         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
560         NativeValue* result = nullptr;
561         AsyncTask::Schedule("JsFormHost::OnRequestForm",
562             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
563         return result;
564     }
565 
OnCastTempForm(NativeEngine & engine,const NativeCallbackInfo & info)566     NativeValue* OnCastTempForm(NativeEngine &engine, const NativeCallbackInfo &info)
567     {
568         HILOG_DEBUG("%{public}s called.", __func__);
569 
570         if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
571             HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
572             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
573             return engine.CreateUndefined();
574         }
575 
576         decltype(info.argc) convertArgc = 0;
577         int64_t formId = 0;
578         if (!ConvertFromId(engine, info.argv[PARAM0], formId)) {
579             HILOG_ERROR("form id is invalid.");
580             NapiFormUtil::ThrowParamTypeError(engine, "formId", "string");
581             return engine.CreateUndefined();
582         }
583         convertArgc++;
584 
585         AsyncTask::CompleteCallback complete = [formId](NativeEngine &engine, AsyncTask &task, int32_t status) {
586             auto ret = FormMgr::GetInstance().CastTempForm(formId, FormHostClient::GetInstance());
587             if (ret == ERR_OK) {
588                 task.ResolveWithNoError(engine, engine.CreateUndefined());
589             } else {
590                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
591             }
592         };
593 
594         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
595         NativeValue* result = nullptr;
596         AsyncTask::Schedule("JsFormHost::OnCastTempForm",
597             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
598         return result;
599     }
600 
OnNotifyVisibleForms(NativeEngine & engine,const NativeCallbackInfo & info)601     NativeValue* OnNotifyVisibleForms(NativeEngine &engine, const NativeCallbackInfo &info)
602     {
603         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
604 
605         if (info.argc > ARGS_TWO|| info.argc < ARGS_ONE) {
606             HILOG_ERROR("wrong number of arguments.");
607             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
608             return engine.CreateUndefined();
609         }
610 
611         decltype(info.argc) convertArgc = 0;
612         std::vector<int64_t> formIds;
613         if (!ConvertFromIds(engine, info.argv[PARAM0], formIds)) {
614             HILOG_ERROR("form id list is invalid.");
615             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
616             return engine.CreateUndefined();
617         }
618         convertArgc++;
619 
620         auto complete = [formIds](NativeEngine &engine, AsyncTask &task, int32_t status) {
621             auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds, FormHostClient::GetInstance(),
622                 Constants::FORM_VISIBLE);
623             if (ret == ERR_OK) {
624                 task.ResolveWithNoError(engine, engine.CreateUndefined());
625             } else {
626                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
627             }
628         };
629 
630         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
631         NativeValue *result = nullptr;
632         AsyncTask::Schedule("JsFormHost::OnEnableFormsUpdate",
633             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
634         return result;
635     }
636 
OnNotifyInvisibleForms(NativeEngine & engine,const NativeCallbackInfo & info)637     NativeValue* OnNotifyInvisibleForms(NativeEngine &engine, const NativeCallbackInfo &info)
638     {
639         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
640 
641         if (info.argc > ARGS_TWO|| info.argc < ARGS_ONE) {
642             HILOG_ERROR("wrong number of arguments.");
643             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
644             return engine.CreateUndefined();
645         }
646 
647         decltype(info.argc) convertArgc = 0;
648         std::vector<int64_t> formIds;
649         if (!ConvertFromIds(engine, info.argv[PARAM0], formIds)) {
650             HILOG_ERROR("form id list is invalid.");
651             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
652             return engine.CreateUndefined();
653         }
654         convertArgc++;
655 
656         auto complete = [formIds](NativeEngine &engine, AsyncTask &task, int32_t status) {
657             auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds, FormHostClient::GetInstance(),
658                 Constants::FORM_INVISIBLE);
659             if (ret == ERR_OK) {
660                 task.ResolveWithNoError(engine, engine.CreateUndefined());
661             } else {
662                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
663             }
664         };
665 
666         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
667         NativeValue *result = nullptr;
668         AsyncTask::Schedule("JsFormHost::OnEnableFormsUpdate",
669             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
670         return result;
671     }
672 
OnEnableFormsUpdate(NativeEngine & engine,const NativeCallbackInfo & info)673     NativeValue* OnEnableFormsUpdate(NativeEngine &engine, const NativeCallbackInfo &info)
674     {
675         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
676 
677         if (info.argc > ARGS_TWO|| info.argc < ARGS_ONE) {
678             HILOG_ERROR("wrong number of arguments.");
679             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
680             return engine.CreateUndefined();
681         }
682 
683         decltype(info.argc) convertArgc = 0;
684         std::vector<int64_t> formIds;
685         if (!ConvertFromIds(engine, info.argv[PARAM0], formIds)) {
686             HILOG_ERROR("form id list is invalid.");
687             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
688             return engine.CreateUndefined();
689         }
690         convertArgc++;
691 
692         auto complete = [formIds](NativeEngine &engine, AsyncTask &task, int32_t status) {
693             auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), true);
694             if (ret == ERR_OK) {
695                 task.ResolveWithNoError(engine, engine.CreateUndefined());
696             } else {
697                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
698             }
699         };
700 
701         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
702         NativeValue *result = nullptr;
703         AsyncTask::Schedule("JsFormHost::OnEnableFormsUpdate",
704             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
705         return result;
706     }
707 
OnDisableFormsUpdate(NativeEngine & engine,const NativeCallbackInfo & info)708     NativeValue* OnDisableFormsUpdate(NativeEngine &engine, const NativeCallbackInfo &info)
709     {
710         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
711 
712         if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
713             HILOG_ERROR("wrong number of arguments.");
714             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
715             return engine.CreateUndefined();
716     }
717 
718         decltype(info.argc) convertArgc = 0;
719         std::vector<int64_t> iFormIds;
720         if (!ConvertFromIds(engine, info.argv[PARAM0], iFormIds)) {
721             HILOG_ERROR("form id list is invalid.");
722             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
723             return engine.CreateUndefined();
724         }
725         convertArgc++;
726 
727         auto complete = [formIds = iFormIds](NativeEngine &engine, AsyncTask &task, int32_t status) {
728             auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), false);
729             if (ret != ERR_OK) {
730                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
731                 return;
732             }
733             task.ResolveWithNoError(engine, engine.CreateUndefined());
734         };
735 
736         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
737         NativeValue *result = nullptr;
738         AsyncTask::Schedule("JsFormHost::OnDisableFormsUpdate",
739             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
740         return result;
741     }
742 
OnIsSystemReady(NativeEngine & engine,const NativeCallbackInfo & info)743     NativeValue* OnIsSystemReady(NativeEngine &engine, const NativeCallbackInfo &info)
744     {
745         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
746         if (info.argc > ARGS_ONE || info.argc < ARGS_ZERO) {
747             HILOG_ERROR("wrong number of arguments.");
748             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "0 or 1");
749             return engine.CreateUndefined();
750         }
751 
752         auto complete = [](NativeEngine &engine, AsyncTask &task, int32_t status) {
753             // Use original logic.
754             // Use the error code to return whether the function executed successfully.
755             auto ret = FormMgr::GetInstance().CheckFMSReady() ? 0 : 1;
756             if( ret == ERR_OK ) {
757                 task.ResolveWithNoError(engine, engine.CreateUndefined());
758             } else {
759                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
760             }
761         };
762 
763         auto callback = (info.argc == ARGS_ZERO) ? nullptr : info.argv[PARAM0];
764         NativeValue *result = nullptr;
765         AsyncTask::Schedule("JsFormHost::OnIsSystemReady",
766             engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
767         return result;
768     }
769 
OnDeleteInvalidForms(NativeEngine & engine,const NativeCallbackInfo & info)770     NativeValue* OnDeleteInvalidForms(NativeEngine &engine, const NativeCallbackInfo &info)
771     {
772         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
773 
774         if (info.argc > ARGS_TWO|| info.argc < ARGS_ONE) {
775             HILOG_ERROR("wrong number of arguments.");
776             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
777             return engine.CreateUndefined();
778         }
779 
780         decltype(info.argc) convertArgc = 0;
781         std::vector<int64_t> formIds;
782         if (!ConvertFromIds(engine, info.argv[PARAM0], formIds)) {
783             HILOG_ERROR("form id list is invalid.");
784             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
785             return engine.CreateUndefined();
786         }
787         convertArgc++;
788 
789         auto complete = [formIds](NativeEngine &engine, AsyncTask &task, int32_t status) {
790             int32_t num;
791             auto ret = FormMgr::GetInstance().DeleteInvalidForms(formIds, FormHostClient::GetInstance(), num);
792             if (ret == ERR_OK) {
793                 task.ResolveWithNoError(engine, CreateJsValue(engine, num));
794             } else {
795                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
796             }
797         };
798 
799         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
800         NativeValue *result = nullptr;
801         AsyncTask::Schedule("JsFormHost::OnEnableFormsUpdate",
802             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
803         return result;
804     }
805 
InnerAcquireFormState(NativeEngine & engine,const std::shared_ptr<AsyncTask> & asyncTask,JsFormStateCallbackClient::AcquireFormStateTask && task,const Want & want)806     void InnerAcquireFormState(
807         NativeEngine &engine,
808         const std::shared_ptr<AsyncTask> &asyncTask,
809         JsFormStateCallbackClient::AcquireFormStateTask &&task,
810         const Want &want)
811     {
812         auto formStateCallback = std::make_shared<JsFormStateCallbackClient>(std::move(task));
813         FormHostClient::GetInstance()->AddFormState(formStateCallback, want);
814         FormStateInfo stateInfo;
815         auto result = FormMgr::GetInstance().AcquireFormState(want, FormHostClient::GetInstance(), stateInfo);
816         formStateCallback->SetWant(stateInfo.want);
817         if (result != ERR_OK) {
818             HILOG_DEBUG("AcquireFormState failed.");
819             asyncTask->Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, result));
820             FormHostClient::GetInstance()->RemoveFormState(want);
821         }
822     }
823 
OnAcquireFormState(NativeEngine & engine,NativeCallbackInfo & info)824     NativeValue* OnAcquireFormState(NativeEngine &engine, NativeCallbackInfo &info)
825     {
826         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
827         if (info.argc > ARGS_TWO || info.argc < ARGS_ONE) {
828             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
829             return engine.CreateUndefined();
830         }
831 
832         Want want;
833         auto env = reinterpret_cast<napi_env>(&engine);
834         auto argWant = reinterpret_cast<napi_value>(info.argv[PARAM0]);
835         if (!UnwrapWant(env, argWant, want)) {
836             HILOG_ERROR("want is invalid.");
837             NapiFormUtil::ThrowParamTypeError(engine, "want", "Want");
838             return engine.CreateUndefined();
839         }
840 
841         NativeValue *lastParam = (info.argc == ARGS_ONE) ? nullptr : info.argv[PARAM1];
842         NativeValue *result = nullptr;
843 
844         std::unique_ptr<AbilityRuntime::AsyncTask> uasyncTask =
845             AbilityRuntime::CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, nullptr, &result);
846         std::shared_ptr<AbilityRuntime::AsyncTask> asyncTask = std::move(uasyncTask);
847 
848         JsFormStateCallbackClient::AcquireFormStateTask task = [&engine, asyncTask](int32_t state, Want want) {
849             HILOG_DEBUG("task complete state: %{public}d", state);
850             NativeValue *objValue = engine.CreateObject();
851             NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
852             object->SetProperty("want", CreateJsWant(engine, want));
853             object->SetProperty("formState", CreateJsValue(engine, state));
854             asyncTask->ResolveWithNoError(engine, objValue);
855         };
856 
857         InnerAcquireFormState(engine, asyncTask, std::move(task), want);
858         return result;
859     }
860 
OnRegisterFormUninstallObserver(NativeEngine & engine,NativeCallbackInfo & info)861     NativeValue* OnRegisterFormUninstallObserver(NativeEngine &engine, NativeCallbackInfo &info)
862     {
863         HILOG_DEBUG("%{public}s called.", __func__);
864 
865         if (info.argc != ARGS_TWO) {
866             HILOG_ERROR("wrong number of arguments.");
867             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "2");
868             return engine.CreateUndefined();
869         }
870 
871         if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
872             HILOG_ERROR("param0 is invalid");
873             NapiFormUtil::ThrowParamTypeError(engine, "type", "formUninstall");
874             return engine.CreateUndefined();
875         }
876         std::string type;
877         if (!ConvertFromJsValue(engine, info.argv[PARAM0], type)) {
878             HILOG_ERROR("convert type failed!");
879             NapiFormUtil::ThrowParamTypeError(engine, "type", "formUninstall");
880             return engine.CreateUndefined();
881         }
882 
883         if (type != "formUninstall") {
884             HILOG_ERROR("args[0] should be formUninstall.");
885             NapiFormUtil::ThrowParamTypeError(engine, "type", "formUninstall");
886             return engine.CreateUndefined();
887         }
888 
889         if (info.argv[PARAM1]->TypeOf() != NATIVE_FUNCTION) {
890             HILOG_ERROR("param1 is invalid");
891             NapiFormUtil::ThrowParamTypeError(engine, "callback", "Callback<string>");
892             return engine.CreateUndefined();
893         }
894 
895         FormHostClient::GetInstance()->RegisterUninstallCallback(FormUninstallCallback);
896         AddFormUninstallCallback(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[1]));
897         return engine.CreateUndefined();
898     }
899 
OnUnregisterFormUninstallObserver(NativeEngine & engine,NativeCallbackInfo & info)900     NativeValue* OnUnregisterFormUninstallObserver(NativeEngine &engine, NativeCallbackInfo &info)
901     {
902         HILOG_DEBUG("%{public}s called.", __func__);
903 
904         if (info.argc > ARGS_TWO|| info.argc < ARGS_ONE) {
905             HILOG_ERROR("wrong number of arguments.");
906             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2");
907             return engine.CreateUndefined();
908         }
909 
910         if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
911             HILOG_ERROR("param0 is invalid");
912             NapiFormUtil::ThrowParamTypeError(engine, "type", "formUninstall");
913             return engine.CreateUndefined();
914         }
915         std::string type;
916         if (!ConvertFromJsValue(engine, info.argv[PARAM0], type)) {
917             HILOG_ERROR("convert type failed!");
918             NapiFormUtil::ThrowParamTypeError(engine, "type", "formUninstall");
919             return engine.CreateUndefined();
920         }
921 
922         if (type != "formUninstall") {
923             HILOG_ERROR("args[0] should be formUninstall.");
924             NapiFormUtil::ThrowParamTypeError(engine, "type", "formUninstall");
925             return engine.CreateUndefined();
926         }
927 
928         if (info.argc == ARGS_TWO && info.argv[PARAM1]->TypeOf() != NATIVE_FUNCTION) {
929             HILOG_ERROR("param1 is invalid");
930             NapiFormUtil::ThrowParamTypeError(engine, "callback", "Callback<string>");
931             return engine.CreateUndefined();
932         }
933 
934         if (info.argc == ARGS_TWO) {
935             DelFormUninstallCallback(reinterpret_cast<napi_value>(info.argv[PARAM1]));
936             return engine.CreateUndefined();
937         }
938 
939         ClearFormUninstallCallback();
940         return engine.CreateUndefined();
941     }
942 
OnNotifyFormsVisible(NativeEngine & engine,const NativeCallbackInfo & info)943     NativeValue* OnNotifyFormsVisible(NativeEngine &engine, const NativeCallbackInfo &info)
944     {
945         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
946 
947         if (info.argc > ARGS_THREE|| info.argc < ARGS_TWO) {
948             HILOG_ERROR("wrong number of arguments.");
949             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "2 or 3");
950             return engine.CreateUndefined();
951         }
952 
953         decltype(info.argc) convertArgc = 0;
954         std::vector<int64_t> formIds;
955         if (!ConvertFromIds(engine, info.argv[PARAM0], formIds)) {
956             HILOG_ERROR("form id list is invalid.");
957             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
958             return engine.CreateUndefined();
959         }
960         convertArgc++;
961 
962         bool isVisible = false;
963         if (info.argv[PARAM1]->TypeOf() != NATIVE_BOOLEAN) {
964             HILOG_ERROR("promise second param type is illegal");
965             NapiFormUtil::ThrowParamTypeError(engine, "isVisible", "boolean");
966             return engine.CreateUndefined();
967         }
968         if (!ConvertFromJsValue(engine, info.argv[PARAM1], isVisible)) {
969             HILOG_ERROR("convert isVisible failed!");
970             NapiFormUtil::ThrowParamTypeError(engine, "isVisible", "boolean");
971             return engine.CreateUndefined();
972         }
973         convertArgc++;
974 
975         auto complete = [formIds, isVisible](NativeEngine &engine, AsyncTask &task, int32_t status) {
976             auto ret = FormMgr::GetInstance().NotifyFormsVisible(formIds, isVisible,
977                 FormHostClient::GetInstance());
978             if (ret == ERR_OK) {
979                 task.ResolveWithNoError(engine, engine.CreateUndefined());
980             } else {
981                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
982             }
983         };
984 
985         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
986         NativeValue *result = nullptr;
987         AsyncTask::Schedule("JsFormHost::OnNotifyFormsVisible",
988             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
989         return result;
990     }
991 
OnNotifyFormsEnableUpdate(NativeEngine & engine,NativeCallbackInfo & info)992     NativeValue* OnNotifyFormsEnableUpdate(NativeEngine &engine, NativeCallbackInfo &info)
993     {
994         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
995 
996         if (info.argc > ARGS_THREE|| info.argc < ARGS_TWO) {
997             HILOG_ERROR("wrong number of arguments.");
998             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "2 or 3");
999             return engine.CreateUndefined();
1000         }
1001 
1002         decltype(info.argc) convertArgc = 0;
1003         std::vector<int64_t> formIds;
1004         if (!ConvertFromIds(engine, info.argv[PARAM0], formIds)) {
1005             HILOG_ERROR("form id list is invalid.");
1006             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
1007             return engine.CreateUndefined();
1008         }
1009         convertArgc++;
1010 
1011         bool isEnableUpdate = false;
1012         if (info.argv[PARAM1]->TypeOf() != NATIVE_BOOLEAN) {
1013             HILOG_ERROR("promise second param type is illegal");
1014             NapiFormUtil::ThrowParamTypeError(engine, "isEnableUpdate", "boolean");
1015             return engine.CreateUndefined();
1016         }
1017         if (!ConvertFromJsValue(engine, info.argv[PARAM1], isEnableUpdate)) {
1018             HILOG_ERROR("convert isEnableUpdate failed!");
1019             NapiFormUtil::ThrowParamTypeError(engine, "isEnableUpdate", "boolean");
1020             return engine.CreateUndefined();
1021         }
1022         convertArgc++;
1023 
1024         auto complete = [formIds, isEnableUpdate](NativeEngine &engine, AsyncTask &task, int32_t status) {
1025             auto ret = FormMgr::GetInstance().NotifyFormsEnableUpdate(formIds, isEnableUpdate,
1026                 FormHostClient::GetInstance());
1027             if (ret == ERR_OK) {
1028                 task.ResolveWithNoError(engine, engine.CreateUndefined());
1029             } else {
1030                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
1031             }
1032         };
1033 
1034         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
1035         NativeValue *result = nullptr;
1036         AsyncTask::Schedule("JsFormHost::OnNotifyFormsVisible",
1037             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
1038         return result;
1039     }
1040 
OnGetAllFormsInfo(NativeEngine & engine,const NativeCallbackInfo & info)1041     NativeValue* OnGetAllFormsInfo(NativeEngine &engine, const NativeCallbackInfo &info)
1042     {
1043         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1044         if (info.argc > ARGS_ONE || info.argc < ARGS_ZERO) {
1045             HILOG_ERROR("wrong number of arguments.");
1046             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "0 or 1");
1047             return engine.CreateUndefined();
1048         }
1049 
1050         auto complete = [](NativeEngine &engine, AsyncTask &task, int32_t status) {
1051             std::vector<FormInfo> formInfos;
1052             auto ret = FormMgr::GetInstance().GetAllFormsInfo(formInfos);
1053             if (ret != ERR_OK) {
1054                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
1055                 return;
1056             }
1057             task.ResolveWithNoError(engine, CreateFormInfos(engine, formInfos));
1058         };
1059 
1060         auto callback = (info.argc == ARGS_ZERO) ? nullptr : info.argv[PARAM0];
1061         NativeValue *result = nullptr;
1062         AsyncTask::Schedule("JsFormHost::OnGetAllFormsInfo",
1063             engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
1064         return result;
1065     }
1066 
OnGetFormsInfo(NativeEngine & engine,NativeCallbackInfo & info)1067     NativeValue* OnGetFormsInfo(NativeEngine &engine, NativeCallbackInfo &info)
1068     {
1069         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1070         if (info.argc > ARGS_THREE || info.argc < ARGS_ONE) {
1071             HILOG_ERROR("wrong number of arguments.");
1072             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2 or 3");
1073             return engine.CreateUndefined();
1074         }
1075 
1076         if (info.argv[PARAM0] && info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
1077             HILOG_ERROR("input params is not string.");
1078             NapiFormUtil::ThrowParamTypeError(engine, "bundleName", "string");
1079             return engine.CreateUndefined();
1080         }
1081 
1082         decltype(info.argc) convertArgc = 0;
1083         std::string bName("");
1084         if (!ConvertFromJsValue(engine, info.argv[PARAM0], bName)) {
1085             HILOG_ERROR("bundle name convert failed.");
1086             NapiFormUtil::ThrowParamTypeError(engine, "bundleName", "string");
1087             return engine.CreateUndefined();
1088         }
1089         convertArgc++;
1090 
1091         std::string mName("");
1092         if ((info.argc == ARGS_TWO || info.argc == ARGS_THREE) && info.argv[PARAM1]->TypeOf() != NATIVE_FUNCTION) {
1093             if (info.argv[PARAM1]->TypeOf() != NATIVE_STRING) {
1094                 HILOG_ERROR("input params is not string");
1095                 NapiFormUtil::ThrowParamTypeError(engine, "moduleName", "string");
1096                 return engine.CreateUndefined();
1097             }
1098 
1099             if (!ConvertFromJsValue(engine, info.argv[PARAM1], mName)) {
1100                 HILOG_ERROR("module name convert failed.");
1101                 NapiFormUtil::ThrowParamTypeError(engine, "moduleName", "string");
1102                 return engine.CreateUndefined();
1103             }
1104             convertArgc++;
1105         }
1106 
1107         auto complete = [bName, mName, convertArgc](NativeEngine &engine, AsyncTask &task, int32_t status) {
1108             std::string bundleName(bName);
1109             std::string moduleName(mName);
1110             std::vector<FormInfo> formInfos;
1111             int ret = ERR_OK;
1112             if (convertArgc == ARGS_ONE) {
1113                 ret = FormMgr::GetInstance().GetFormsInfoByApp(bundleName, formInfos);
1114             } else {
1115                 ret = FormMgr::GetInstance().GetFormsInfoByModule(bundleName, moduleName, formInfos);
1116             }
1117 
1118             if (ret != ERR_OK) {
1119                 task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
1120                 return;
1121             }
1122             task.ResolveWithNoError(engine, CreateFormInfos(engine, formInfos));
1123         };
1124 
1125         NativeValue *result = nullptr;
1126         NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
1127         AsyncTask::Schedule("JsFormHost::OnGetFormsInfo",
1128             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
1129         return result;
1130     }
1131 
InnerShareForm(NativeEngine & engine,const std::shared_ptr<AbilityRuntime::AsyncTask> & asyncTask,ShareFormCallBackClient::ShareFormTask && task,int64_t formId,const std::string & remoteDeviceId)1132     void InnerShareForm(NativeEngine &engine, const std::shared_ptr<AbilityRuntime::AsyncTask> &asyncTask,
1133         ShareFormCallBackClient::ShareFormTask &&task, int64_t formId, const std::string &remoteDeviceId)
1134     {
1135         auto shareFormCallback = std::make_shared<ShareFormCallBackClient>(std::move(task));
1136         int64_t requestCode = SystemTimeMillis();
1137         FormHostClient::GetInstance()->AddShareFormCallback(shareFormCallback, requestCode);
1138 
1139         ErrCode ret = FormMgr::GetInstance().ShareForm(
1140             formId, remoteDeviceId, FormHostClient::GetInstance(), requestCode);
1141         if (ret != ERR_OK) {
1142             HILOG_INFO("%{public}s, share form failed.", __func__);
1143             asyncTask->Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
1144             FormHostClient::GetInstance()->RemoveShareFormCallback(requestCode);
1145         }
1146     }
1147 
OnShareForm(NativeEngine & engine,NativeCallbackInfo & info)1148     NativeValue* OnShareForm(NativeEngine &engine, NativeCallbackInfo &info)
1149     {
1150         HILOG_DEBUG("%{public}s is called", __FUNCTION__);
1151         if (info.argc > ARGS_THREE || info.argc < ARGS_TWO) {
1152             HILOG_ERROR("wrong number of arguments.");
1153             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "1 or 2 or 3");
1154             return engine.CreateUndefined();
1155         }
1156 
1157         decltype(info.argc) convertArgc = 0;
1158         HILOG_DEBUG("info.argv[PARAM0]->TypeOf() %{public}d", info.argv[PARAM0]->TypeOf());
1159         int64_t formId = 0;
1160         if (!ConvertFromId(engine, info.argv[PARAM0], formId)) {
1161             HILOG_ERROR("form id is invalid.");
1162             NapiFormUtil::ThrowParamTypeError(engine, "formId", "string");
1163             return engine.CreateUndefined();
1164         }
1165         convertArgc++;
1166 
1167         std::string devicedId;
1168         if (!ConvertDeviceId(engine, info.argv[PARAM1], devicedId)) {
1169             HILOG_ERROR("deviced id is invalid.");
1170             NapiFormUtil::ThrowParamTypeError(engine, "devicedId", "string");
1171             return engine.CreateUndefined();
1172         }
1173         convertArgc++;
1174 
1175         NativeValue *lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
1176         NativeValue *result = nullptr;
1177 
1178         std::unique_ptr<AbilityRuntime::AsyncTask> uasyncTask =
1179             AbilityRuntime::CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, nullptr, &result);
1180         std::shared_ptr<AbilityRuntime::AsyncTask> asyncTask = std::move(uasyncTask);
1181 
1182         ShareFormCallBackClient::ShareFormTask task = [&engine, asyncTask](int32_t code) {
1183             HILOG_DEBUG("task complete code: %{public}d", code);
1184             if (code == ERR_OK) {
1185                 asyncTask->ResolveWithNoError(engine, engine.CreateUndefined());
1186             } else {
1187                 asyncTask->Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, code));
1188             }
1189         };
1190 
1191         InnerShareForm(engine, asyncTask, std::move(task), formId, devicedId);
1192 
1193         return result;
1194     }
1195 
OnNotifyFormsPrivacyProtected(NativeEngine & engine,NativeCallbackInfo & info)1196     NativeValue* OnNotifyFormsPrivacyProtected(NativeEngine &engine, NativeCallbackInfo &info)
1197     {
1198         HILOG_INFO("%{public}s is called", __func__);
1199         if (info.argc > ARGS_THREE || info.argc < ARGS_TWO) {
1200             HILOG_ERROR("wrong number of arguments.");
1201             NapiFormUtil::ThrowParamNumError(engine, std::to_string(info.argc), "2 or 3");
1202             return engine.CreateUndefined();
1203         }
1204 
1205         decltype(info.argc) convertArgc = 0;
1206         std::vector<int64_t> formIds;
1207         if (!ConvertFromIds(engine, info.argv[PARAM0], formIds)) {
1208             HILOG_ERROR("form id list is invalid.");
1209             NapiFormUtil::ThrowParamTypeError(engine, "formIds", "Array<string>");
1210             return engine.CreateUndefined();
1211         }
1212         convertArgc++;
1213 
1214         bool isProtected = false;
1215         if (info.argv[PARAM1]->TypeOf() != NATIVE_BOOLEAN) {
1216             HILOG_ERROR("promise second param type is illegal");
1217             NapiFormUtil::ThrowParamTypeError(engine, "isProtected", "boolean");
1218             return engine.CreateUndefined();
1219         }
1220         if (!ConvertFromJsValue(engine, info.argv[PARAM1], isProtected)) {
1221             HILOG_ERROR("convert isProtected failed!");
1222             NapiFormUtil::ThrowParamTypeError(engine, "isProtected", "boolean");
1223             return engine.CreateUndefined();
1224         }
1225         convertArgc++;
1226 
1227         AsyncTask::CompleteCallback complete =
1228             [formIds, isProtected](NativeEngine &engine, AsyncTask &task, int32_t status) {
1229                 auto ret = FormMgr::GetInstance().NotifyFormsPrivacyProtected(formIds,
1230                     isProtected, FormHostClient::GetInstance());
1231                 if (ret == ERR_OK) {
1232                     task.ResolveWithNoError(engine, engine.CreateUndefined());
1233                 } else {
1234                     task.Reject(engine, NapiFormUtil::CreateErrorByInternalErrorCode(engine, ret));
1235                 }
1236             };
1237 
1238         NativeValue *lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
1239         NativeValue *result = nullptr;
1240         AsyncTask::Schedule("NapiFormHost::OnNotifyFormsPrivacyProtected",
1241             engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
1242         return result;
1243     }
1244 };
1245 
JsFormHostInit(NativeEngine * engine,NativeValue * exportObj)1246 NativeValue* JsFormHostInit(NativeEngine* engine, NativeValue* exportObj)
1247 {
1248     HILOG_INFO("JsFormHostInit is called");
1249     if (engine == nullptr || exportObj == nullptr) {
1250         HILOG_INFO("Invalid input parameters");
1251         return nullptr;
1252     }
1253 
1254     NativeObject* object = ConvertNativeValueTo<NativeObject>(exportObj);
1255     if (object == nullptr) {
1256         HILOG_INFO("object is nullptr");
1257         return nullptr;
1258     }
1259 
1260     std::unique_ptr<JsFormHost> jsFormHost = std::make_unique<JsFormHost>();
1261     object->SetNativePointer(jsFormHost.release(), JsFormHost::Finalizer, nullptr);
1262 
1263     const char *moduleName = "JsFormHost";
1264     BindNativeFunction(*engine, *object, "deleteForm", moduleName, JsFormHost::DeleteForm);
1265     BindNativeFunction(*engine, *object, "releaseForm", moduleName, JsFormHost::ReleaseForm);
1266     BindNativeFunction(*engine, *object, "requestForm", moduleName, JsFormHost::RequestForm);
1267     BindNativeFunction(*engine, *object, "castTempForm", moduleName, JsFormHost::CastTempForm);
1268     BindNativeFunction(*engine, *object, "castToNormalForm", moduleName, JsFormHost::CastTempForm);
1269     BindNativeFunction(*engine, *object, "notifyVisibleForms", moduleName, JsFormHost::NotifyVisibleForms);
1270     BindNativeFunction(*engine, *object, "notifyInvisibleForms", moduleName, JsFormHost::NotifyInvisibleForms);
1271     BindNativeFunction(*engine, *object, "enableFormsUpdate", moduleName, JsFormHost::EnableFormsUpdate);
1272     BindNativeFunction(*engine, *object, "disableFormsUpdate", moduleName, JsFormHost::DisableFormsUpdate);
1273     BindNativeFunction(*engine, *object, "isSystemReady", moduleName, JsFormHost::IsSystemReady);
1274     BindNativeFunction(*engine, *object, "deleteInvalidForms", moduleName, JsFormHost::DeleteInvalidForms);
1275     BindNativeFunction(*engine, *object, "acquireFormState", moduleName, JsFormHost::AcquireFormState);
1276     BindNativeFunction(*engine, *object, "on", moduleName, JsFormHost::RegisterFormUninstallObserver);
1277     BindNativeFunction(*engine, *object, "off", moduleName, JsFormHost::UnregisterFormUninstallObserver);
1278     BindNativeFunction(*engine, *object, "notifyFormsVisible", moduleName, JsFormHost::NotifyFormsVisible);
1279     BindNativeFunction(*engine, *object, "notifyFormsEnableUpdate", moduleName, JsFormHost::NotifyFormsEnableUpdate);
1280     BindNativeFunction(*engine, *object, "getAllFormsInfo", moduleName, JsFormHost::GetAllFormsInfo);
1281     BindNativeFunction(*engine, *object, "getFormsInfo", moduleName, JsFormHost::GetFormsInfo);
1282     BindNativeFunction(*engine, *object, "shareForm", moduleName, JsFormHost::ShareForm);
1283     BindNativeFunction(*engine, *object, "notifyFormsPrivacyProtected", moduleName,
1284         JsFormHost::NotifyFormsPrivacyProtected);
1285     return engine->CreateUndefined();
1286 }
1287 } // namespace AbilityRuntime
1288 } // namespace OHOS